Skip to content

Commit

Permalink
Rollup merge of #99787 - aDotInTheVoid:rdj-dyn, r=camelid,notriddle,G…
Browse files Browse the repository at this point in the history
…uillaumeGomez

Rustdoc-Json: Document HRTB's on DynTrait

Closes #99118

Probably best reviewed commit by commit.

`@rustbot` modify labels: +A-rustdoc-json

cc `@Enselic`

r? `@CraftSpider`
  • Loading branch information
Dylan-DPC authored Aug 9, 2022
2 parents 1dc4858 + 6290f92 commit e41be25
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 77 deletions.
4 changes: 2 additions & 2 deletions src/etc/check_missing_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ def check_type(ty):
for bound in binding["binding"]["constraint"]:
check_generic_bound(bound)
elif "parenthesized" in args:
for ty in args["parenthesized"]["inputs"]:
check_type(ty)
for input_ty in args["parenthesized"]["inputs"]:
check_type(input_ty)
if args["parenthesized"]["output"]:
check_type(args["parenthesized"]["output"])
if not valid_id(ty["inner"]["id"]):
Expand Down
120 changes: 59 additions & 61 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ where
}
}

impl<I, T, U> FromWithTcx<I> for Vec<U>
where
I: IntoIterator<Item = T>,
U: FromWithTcx<T>,
{
fn from_tcx(f: I, tcx: TyCtxt<'_>) -> Vec<U> {
f.into_iter().map(|x| x.into_tcx(tcx)).collect()
}
}

pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
#[rustfmt::skip]
let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
Expand All @@ -130,11 +140,11 @@ impl FromWithTcx<clean::GenericArgs> for GenericArgs {
use clean::GenericArgs::*;
match args {
AngleBracketed { args, bindings } => GenericArgs::AngleBracketed {
args: args.into_vec().into_iter().map(|a| a.into_tcx(tcx)).collect(),
bindings: bindings.into_iter().map(|a| a.into_tcx(tcx)).collect(),
args: args.into_vec().into_tcx(tcx),
bindings: bindings.into_tcx(tcx),
},
Parenthesized { inputs, output } => GenericArgs::Parenthesized {
inputs: inputs.into_vec().into_iter().map(|a| a.into_tcx(tcx)).collect(),
inputs: inputs.into_vec().into_tcx(tcx),
output: output.map(|a| (*a).into_tcx(tcx)),
},
}
Expand All @@ -145,7 +155,7 @@ impl FromWithTcx<clean::GenericArg> for GenericArg {
fn from_tcx(arg: clean::GenericArg, tcx: TyCtxt<'_>) -> Self {
use clean::GenericArg::*;
match arg {
Lifetime(l) => GenericArg::Lifetime(l.0.to_string()),
Lifetime(l) => GenericArg::Lifetime(convert_lifetime(l)),
Type(t) => GenericArg::Type(t.into_tcx(tcx)),
Const(box c) => GenericArg::Const(c.into_tcx(tcx)),
Infer => GenericArg::Infer,
Expand Down Expand Up @@ -177,9 +187,7 @@ impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
use clean::TypeBindingKind::*;
match kind {
Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)),
Constraint { bounds } => {
TypeBindingKind::Constraint(bounds.into_iter().map(|a| a.into_tcx(tcx)).collect())
}
Constraint { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
}
}
}
Expand Down Expand Up @@ -244,7 +252,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, header.unwrap(), tcx)),
TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, header.unwrap(), tcx)),
ImplItem(i) => ItemEnum::Impl(i.into_tcx(tcx)),
ImplItem(i) => ItemEnum::Impl((*i).into_tcx(tcx)),
StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
ForeignTypeItem => ItemEnum::ForeignType,
Expand All @@ -260,12 +268,12 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
}
TyAssocTypeItem(g, b) => ItemEnum::AssocType {
generics: (*g).into_tcx(tcx),
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
bounds: b.into_tcx(tcx),
default: None,
},
AssocTypeItem(t, b) => ItemEnum::AssocType {
generics: t.generics.into_tcx(tcx),
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
bounds: b.into_tcx(tcx),
default: Some(t.item_type.unwrap_or(t.type_).into_tcx(tcx)),
},
// `convert_item` early returns `None` for stripped items and keywords.
Expand Down Expand Up @@ -347,15 +355,15 @@ fn convert_abi(a: RustcAbi) -> Abi {
}
}

fn convert_lifetime(l: clean::Lifetime) -> String {
l.0.to_string()
}

impl FromWithTcx<clean::Generics> for Generics {
fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self {
Generics {
params: generics.params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
where_predicates: generics
.where_predicates
.into_iter()
.map(|x| x.into_tcx(tcx))
.collect(),
params: generics.params.into_tcx(tcx),
where_predicates: generics.where_predicates.into_tcx(tcx),
}
}
}
Expand All @@ -374,10 +382,10 @@ impl FromWithTcx<clean::GenericParamDefKind> for GenericParamDefKind {
use clean::GenericParamDefKind::*;
match kind {
Lifetime { outlives } => GenericParamDefKind::Lifetime {
outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(),
outlives: outlives.into_iter().map(convert_lifetime).collect(),
},
Type { did: _, bounds, default, synthetic } => GenericParamDefKind::Type {
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
bounds: bounds.into_tcx(tcx),
default: default.map(|x| (*x).into_tcx(tcx)),
synthetic,
},
Expand All @@ -395,7 +403,7 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
match predicate {
BoundPredicate { ty, bounds, bound_params } => WherePredicate::BoundPredicate {
type_: ty.into_tcx(tcx),
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
bounds: bounds.into_tcx(tcx),
generic_params: bound_params
.into_iter()
.map(|x| GenericParamDef {
Expand All @@ -405,8 +413,8 @@ impl FromWithTcx<clean::WherePredicate> for WherePredicate {
.collect(),
},
RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate {
lifetime: lifetime.0.to_string(),
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
lifetime: convert_lifetime(lifetime),
bounds: bounds.into_tcx(tcx),
},
EqPredicate { lhs, rhs } => {
WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) }
Expand All @@ -424,11 +432,11 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
GenericBound::TraitBound {
trait_,
generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
generic_params: generic_params.into_tcx(tcx),
modifier: from_trait_bound_modifier(modifier),
}
}
Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()),
Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)),
}
}
}
Expand All @@ -447,8 +455,8 @@ pub(crate) fn from_trait_bound_modifier(
impl FromWithTcx<clean::Type> for Type {
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
use clean::Type::{
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive,
QPath, RawPointer, Slice, Tuple,
Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
RawPointer, Slice, Tuple,
};

match ty {
Expand All @@ -458,40 +466,24 @@ impl FromWithTcx<clean::Type> for Type {
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
param_names: Vec::new(),
},
DynTrait(mut bounds, lt) => {
let first_trait = bounds.remove(0).trait_;

Type::ResolvedPath {
name: first_trait.whole_name(),
id: from_item_id(first_trait.def_id().into(), tcx),
args: first_trait
.segments
.last()
.map(|args| Box::new(args.clone().args.into_tcx(tcx))),
param_names: bounds
.into_iter()
.map(|t| {
clean::GenericBound::TraitBound(t, rustc_hir::TraitBoundModifier::None)
})
.chain(lt.map(clean::GenericBound::Outlives))
.map(|bound| bound.into_tcx(tcx))
.collect(),
}
}
clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait {
lifetime: lt.map(convert_lifetime),
traits: bounds.into_tcx(tcx),
}),
Generic(s) => Type::Generic(s.to_string()),
Primitive(p) => Type::Primitive(p.as_sym().to_string()),
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
Tuple(t) => Type::Tuple(t.into_tcx(tcx)),
Slice(t) => Type::Slice(Box::new((*t).into_tcx(tcx))),
Array(t, s) => Type::Array { type_: Box::new((*t).into_tcx(tcx)), len: s },
ImplTrait(g) => Type::ImplTrait(g.into_iter().map(|x| x.into_tcx(tcx)).collect()),
ImplTrait(g) => Type::ImplTrait(g.into_tcx(tcx)),
Infer => Type::Infer,
RawPointer(mutability, type_) => Type::RawPointer {
mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)),
},
BorrowedRef { lifetime, mutability, type_ } => Type::BorrowedRef {
lifetime: lifetime.map(|l| l.0.to_string()),
lifetime: lifetime.map(convert_lifetime),
mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)),
},
Expand Down Expand Up @@ -528,7 +520,7 @@ impl FromWithTcx<clean::BareFunctionDecl> for FunctionPointer {
async_: false,
abi: convert_abi(abi),
},
generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
generic_params: generic_params.into_tcx(tcx),
decl: decl.into_tcx(tcx),
}
}
Expand Down Expand Up @@ -562,16 +554,28 @@ impl FromWithTcx<clean::Trait> for Trait {
is_unsafe,
items: ids(items, tcx),
generics: generics.into_tcx(tcx),
bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
bounds: bounds.into_tcx(tcx),
implementations: Vec::new(), // Added in JsonRenderer::item
}
}
}

impl FromWithTcx<Box<clean::Impl>> for Impl {
fn from_tcx(impl_: Box<clean::Impl>, tcx: TyCtxt<'_>) -> Self {
impl FromWithTcx<clean::PolyTrait> for PolyTrait {
fn from_tcx(
clean::PolyTrait { trait_, generic_params }: clean::PolyTrait,
tcx: TyCtxt<'_>,
) -> Self {
PolyTrait {
trait_: clean::Type::Path { path: trait_ }.into_tcx(tcx),
generic_params: generic_params.into_tcx(tcx),
}
}
}

impl FromWithTcx<clean::Impl> for Impl {
fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
let provided_trait_methods = impl_.provided_trait_methods(tcx);
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = *impl_;
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
// FIXME: use something like ImplKind in JSON?
Expand Down Expand Up @@ -730,10 +734,7 @@ impl FromWithTcx<Box<clean::Typedef>> for Typedef {

impl FromWithTcx<clean::OpaqueTy> for OpaqueTy {
fn from_tcx(opaque: clean::OpaqueTy, tcx: TyCtxt<'_>) -> Self {
OpaqueTy {
bounds: opaque.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
generics: opaque.generics.into_tcx(tcx),
}
OpaqueTy { bounds: opaque.bounds.into_tcx(tcx), generics: opaque.generics.into_tcx(tcx) }
}
}

Expand All @@ -749,10 +750,7 @@ impl FromWithTcx<clean::Static> for Static {

impl FromWithTcx<clean::TraitAlias> for TraitAlias {
fn from_tcx(alias: clean::TraitAlias, tcx: TyCtxt<'_>) -> Self {
TraitAlias {
generics: alias.generics.into_tcx(tcx),
params: alias.bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(),
}
TraitAlias { generics: alias.generics.into_tcx(tcx), params: alias.bounds.into_tcx(tcx) }
}
}

Expand Down
38 changes: 34 additions & 4 deletions src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};

/// rustdoc format-version.
pub const FORMAT_VERSION: u32 = 16;
pub const FORMAT_VERSION: u32 = 17;

/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
/// about the language items in the local crate, as well as info about external items to allow
Expand Down Expand Up @@ -115,6 +115,35 @@ pub enum Visibility {
},
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct DynTrait {
/// All the traits implemented. One of them is the vtable, and the rest must be auto traits.
pub traits: Vec<PolyTrait>,
/// The lifetime of the whole dyn object
/// ```text
/// dyn Debug + 'static
/// ^^^^^^^
/// |
/// this part
/// ```
pub lifetime: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
/// A trait and potential HRTBs
pub struct PolyTrait {
#[serde(rename = "trait")]
pub trait_: Type,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```text
/// dyn for<'a> Fn() -> &'a i32"
/// ^^^^^^^
/// |
/// this part
/// ```
pub generic_params: Vec<GenericParamDef>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GenericArgs {
Expand Down Expand Up @@ -395,7 +424,7 @@ pub enum WherePredicate {
type_: Type,
bounds: Vec<GenericBound>,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```plain
/// ```text
/// where for<'a> &'a T: Iterator,"
/// ^^^^^^^
/// |
Expand All @@ -420,7 +449,7 @@ pub enum GenericBound {
#[serde(rename = "trait")]
trait_: Type,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```plain
/// ```text
/// where F: for<'a, 'b> Fn(&'a u8, &'b u8)
/// ^^^^^^^^^^^
/// |
Expand Down Expand Up @@ -458,6 +487,7 @@ pub enum Type {
args: Option<Box<GenericArgs>>,
param_names: Vec<GenericBound>,
},
DynTrait(DynTrait),
/// Parameterized types
Generic(String),
/// Fixed-size numeric types (plus int/usize/float), char, arrays, slices, and tuples
Expand Down Expand Up @@ -505,7 +535,7 @@ pub enum Type {
pub struct FunctionPointer {
pub decl: FnDecl,
/// Used for Higher-Rank Trait Bounds (HRTBs)
/// ```plain
/// ```text
/// for<'c> fn(val: &'c i32) -> i32
/// ^^^^^^^
/// |
Expand Down
Loading

0 comments on commit e41be25

Please sign in to comment.