diff options
| -rw-r--r-- | src/librustdoc/json/conversions.rs | 48 | ||||
| -rw-r--r-- | src/rustdoc-json-types/lib.rs | 38 | ||||
| -rw-r--r-- | src/test/rustdoc-json/type/dyn.rs | 45 | ||||
| -rw-r--r-- | src/test/rustdoc-json/type/hrtb.rs | 9 |
4 files changed, 91 insertions, 49 deletions
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 716a4c9ea43..f5c089ce1e4 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -244,7 +244,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, @@ -447,8 +447,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 { @@ -458,26 +458,10 @@ 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(|lt| lt.0.to_string()), + traits: bounds.into_iter().map(|t| t.into_tcx(tcx)).collect(), + }), 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))), @@ -568,10 +552,22 @@ impl FromWithTcx<clean::Trait> for Trait { } } -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_iter().map(|x| x.into_tcx(tcx)).collect(), + } + } +} + +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? diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 761e94c7ebb..bd4ea98441d 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -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 @@ -116,6 +116,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 { /// <'a, 32, B: Copy, C = u32> @@ -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," /// ^^^^^^^ /// | @@ -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) /// ^^^^^^^^^^^ /// | @@ -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 @@ -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 /// ^^^^^^^ /// | diff --git a/src/test/rustdoc-json/type/dyn.rs b/src/test/rustdoc-json/type/dyn.rs index 79eeb996dcc..c18b54d1fdf 100644 --- a/src/test/rustdoc-json/type/dyn.rs +++ b/src/test/rustdoc-json/type/dyn.rs @@ -1,10 +1,13 @@ // ignore-tidy-linelength +use std::fmt::Debug; -// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items[*]" 2 +// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items[*]" 3 // @set sync_int_gen = - "$.index[*][?(@.name=='SyncIntGen')].id" -// @set ref_fn = - "$.index[*][?(@.name=='RefFn')].id" +// @set ref_fn = - "$.index[*][?(@.name=='RefFn')].id" +// @set weird_order = - "$.index[*][?(@.name=='WeirdOrder')].id" // @has - "$.index[*][?(@.name=='dyn')].inner.items[*]" $sync_int_gen // @has - "$.index[*][?(@.name=='dyn')].inner.items[*]" $ref_fn +// @has - "$.index[*][?(@.name=='dyn')].inner.items[*]" $weird_order // @is - "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\" // @is - "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}' @@ -12,14 +15,16 @@ // @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.name" \"Box\" // @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.bindings" [] // @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args" 1 -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\" -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"resolved_path\" -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.name" \"Fn\" -// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[*]" 3 -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[0].trait_bound.trait.inner.name" \"Send\" -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[1].trait_bound.trait.inner.name" \"Sync\" -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.param_names[2]" "{\"outlives\": \"'static\"}" -// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}' +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.kind" \"dyn_trait\" +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.lifetime" \"\'static\" +// @count - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[*]" 3 +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].generic_params" [] +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].generic_params" [] +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].generic_params" [] +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.name" '"Fn"' +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.inner.name" '"Send"' +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[2].trait.inner.name" '"Sync"' +// @is - "$.index[*][?(@.name=='SyncIntGen')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.args" '{"parenthesized": {"inputs": [],"output": {"inner": "i32","kind": "primitive"}}}' pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>; // @is - "$.index[*][?(@.name=='RefFn')].kind" \"typedef\" @@ -27,10 +32,18 @@ pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>; // @is - "$.index[*][?(@.name=='RefFn')].inner.type.kind" '"borrowed_ref"' // @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.mutable" 'false' // @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.lifetime" "\"'a\"" -// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.kind" '"resolved_path"' -// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.name" '"Fn"' -// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.args.parenthesized.inputs[0].kind" '"borrowed_ref"' -// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.args.parenthesized.inputs[0].inner.lifetime" "\"'b\"" -// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.args.parenthesized.output.kind" '"borrowed_ref"' -// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.args.parenthesized.output.inner.lifetime" "\"'b\"" +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.kind" '"dyn_trait"' +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.lifetime" null +// @count - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[*]" 1 +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.kind" '"resolved_path"' +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.name" '"Fn"' +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.inputs[0].kind" '"borrowed_ref"' +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.inputs[0].inner.lifetime" "\"'b\"" +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.output.kind" '"borrowed_ref"' +// @is - "$.index[*][?(@.name=='RefFn')].inner.type.inner.type.inner.traits[0].trait.inner.args.parenthesized.output.inner.lifetime" "\"'b\"" pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32; + +// @is - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[0].trait.inner.name" '"Send"' +// @is - "$.index[*][?(@.name=='WeirdOrder')].inner.type.inner.args.angle_bracketed.args[0].type.inner.traits[1].trait.inner.name" '"Debug"' +pub type WeirdOrder = Box<dyn Send + Debug>; diff --git a/src/test/rustdoc-json/type/hrtb.rs b/src/test/rustdoc-json/type/hrtb.rs index 55bc043ad29..9311737be0f 100644 --- a/src/test/rustdoc-json/type/hrtb.rs +++ b/src/test/rustdoc-json/type/hrtb.rs @@ -1,3 +1,4 @@ +// ignore-tidy-linelength // @has hrtb.json @@ -14,9 +15,11 @@ where // @is - "$.index[*][?(@.name=='dynfn')].inner.generics" '{"params": [], "where_predicates": []}' // @is - "$.index[*][?(@.name=='dynfn')].inner.generics" '{"params": [], "where_predicates": []}' // @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].kind" '"borrowed_ref"' -// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].kind" '"borrowed_ref"' -// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.kind" '"resolved_path"' -// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.name" '"Fn"' +// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.kind" '"dyn_trait"' +// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.lifetime" null +// @count - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[*]" 1 +// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' +// @is - "$.index[*][?(@.name=='dynfn')].inner.decl.inputs[0][1].inner.type.inner.traits[0].trait.inner.name" '"Fn"' pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) { let zero = 0; f(&zero, &zero); |
