From 95729dcc733edd9f639855081cae8e24bc44fb30 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Tue, 26 Jul 2022 14:34:26 +0100 Subject: [PATCH 1/5] check_missing_items.py: Don't overwrite `ty` in loop Because python doesn't have lexical scope, loop variables persist after the loop is exited, set to the value of the last itteration ``` >>> i = 0 >>> for i in range(10): pass ... >>> i 9 ``` This causes the `ty` variable to be changed, causing unexpected crashes on ``` pub type RefFn<'a> = &'a dyn for<'b> Fn(&'a i32) -> i32; ``` --- src/etc/check_missing_items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index 343dd0387f479..a705e2384959f 100644 --- a/src/etc/check_missing_items.py +++ b/src/etc/check_missing_items.py @@ -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"]): From 2143e48e36e48223e00fffed71acadaf5330f61a Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Tue, 26 Jul 2022 15:02:01 +0100 Subject: [PATCH 2/5] Rustdoc-Json: Add tests for dyn and HRTBs --- src/test/rustdoc-json/type/dyn.rs | 19 +++++++++++++++++-- src/test/rustdoc-json/type/hrtb.rs | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc-json/type/hrtb.rs diff --git a/src/test/rustdoc-json/type/dyn.rs b/src/test/rustdoc-json/type/dyn.rs index f53dc03f4b47f..79eeb996dcc5d 100644 --- a/src/test/rustdoc-json/type/dyn.rs +++ b/src/test/rustdoc-json/type/dyn.rs @@ -1,8 +1,10 @@ // ignore-tidy-linelength -// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items" 1 +// @count dyn.json "$.index[*][?(@.name=='dyn')].inner.items[*]" 2 // @set sync_int_gen = - "$.index[*][?(@.name=='SyncIntGen')].id" -// @is - "$.index[*][?(@.name=='dyn')].inner.items[0]" $sync_int_gen +// @set ref_fn = - "$.index[*][?(@.name=='RefFn')].id" +// @has - "$.index[*][?(@.name=='dyn')].inner.items[*]" $sync_int_gen +// @has - "$.index[*][?(@.name=='dyn')].inner.items[*]" $ref_fn // @is - "$.index[*][?(@.name=='SyncIntGen')].kind" \"typedef\" // @is - "$.index[*][?(@.name=='SyncIntGen')].inner.generics" '{"params": [], "where_predicates": []}' @@ -19,3 +21,16 @@ // @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"}}}' pub type SyncIntGen = Box i32 + Send + Sync + 'static>; + +// @is - "$.index[*][?(@.name=='RefFn')].kind" \"typedef\" +// @is - "$.index[*][?(@.name=='RefFn')].inner.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}' +// @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\"" +pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32; diff --git a/src/test/rustdoc-json/type/hrtb.rs b/src/test/rustdoc-json/type/hrtb.rs new file mode 100644 index 0000000000000..55bc043ad29cd --- /dev/null +++ b/src/test/rustdoc-json/type/hrtb.rs @@ -0,0 +1,23 @@ + +// @has hrtb.json + +// @is - "$.index[*][?(@.name=='genfn')].inner.generics.where_predicates[0].bound_predicate.type" '{"inner": "F","kind": "generic"}' +// @is - "$.index[*][?(@.name=='genfn')].inner.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' +pub fn genfn(f: F) +where + for<'a, 'b> F: Fn(&'a i32, &'b i32), +{ + let zero = 0; + f(&zero, &zero); +} + +// @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"' +pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) { + let zero = 0; + f(&zero, &zero); +} From a856e57f6cc8ba8bb83c5abadce338f589df6b10 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Tue, 26 Jul 2022 17:51:55 +0100 Subject: [PATCH 3/5] Rustdoc-Json: Document HRTB's on DynTrait Closes #99118 --- src/librustdoc/json/conversions.rs | 48 ++++++++++++++---------------- src/rustdoc-json-types/lib.rs | 38 ++++++++++++++++++++--- src/test/rustdoc-json/type/dyn.rs | 45 ++++++++++++++++++---------- 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 716a4c9ea4319..f5c089ce1e4bf 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 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 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 for Trait { } } -impl FromWithTcx> for Impl { - fn from_tcx(impl_: Box, tcx: TyCtxt<'_>) -> Self { +impl FromWithTcx 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 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 761e94c7ebbc4..bd4ea98441d66 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 @@ -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, + /// The lifetime of the whole dyn object + /// ```text + /// dyn Debug + 'static + /// ^^^^^^^ + /// | + /// this part + /// ``` + pub lifetime: Option, +} + +#[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, +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum GenericArgs { @@ -395,7 +424,7 @@ pub enum WherePredicate { type_: Type, bounds: Vec, /// 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>, param_names: Vec, }, + 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 79eeb996dcc5d..c18b54d1fdf0e 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 i32 + Send + Sync + 'static>; // @is - "$.index[*][?(@.name=='RefFn')].kind" \"typedef\" @@ -27,10 +32,18 @@ pub type SyncIntGen = Box 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; diff --git a/src/test/rustdoc-json/type/hrtb.rs b/src/test/rustdoc-json/type/hrtb.rs index 55bc043ad29cd..9311737be0fec 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); From 625c4d70ffa53e36d2b724d191f759937a131bff Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Tue, 26 Jul 2022 17:55:40 +0100 Subject: [PATCH 4/5] Rustdoc-Json: Extract `convert_lifetime` to function --- src/librustdoc/json/conversions.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index f5c089ce1e4bf..8d63c3409c270 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -145,7 +145,7 @@ impl FromWithTcx 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, @@ -347,6 +347,10 @@ fn convert_abi(a: RustcAbi) -> Abi { } } +fn convert_lifetime(l: clean::Lifetime) -> String { + l.0.to_string() +} + impl FromWithTcx for Generics { fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self { Generics { @@ -374,7 +378,7 @@ impl FromWithTcx 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(), @@ -405,7 +409,7 @@ impl FromWithTcx for WherePredicate { .collect(), }, RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate { - lifetime: lifetime.0.to_string(), + lifetime: convert_lifetime(lifetime) bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), }, EqPredicate { lhs, rhs } => { @@ -428,7 +432,7 @@ impl FromWithTcx for GenericBound { modifier: from_trait_bound_modifier(modifier), } } - Outlives(lifetime) => GenericBound::Outlives(lifetime.0.to_string()), + Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)), } } } @@ -459,7 +463,7 @@ impl FromWithTcx for Type { param_names: Vec::new(), }, clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait { - lifetime: lt.map(|lt| lt.0.to_string()), + lifetime: lt.map(convert_lifetime), traits: bounds.into_iter().map(|t| t.into_tcx(tcx)).collect(), }), Generic(s) => Type::Generic(s.to_string()), @@ -475,7 +479,7 @@ impl FromWithTcx for Type { 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)), }, From 6290f92d07fd7ecdbd2f752fde9b12f926b592fa Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Wed, 27 Jul 2022 00:58:59 +0100 Subject: [PATCH 5/5] Rustdoc-Json: Add and use `FromWithTcx` for `Vec` --- src/librustdoc/json/conversions.rs | 64 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 8d63c3409c270..8caba8cb9029c 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -119,6 +119,16 @@ where } } +impl FromWithTcx for Vec +where + I: IntoIterator, + U: FromWithTcx, +{ + fn from_tcx(f: I, tcx: TyCtxt<'_>) -> Vec { + 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; @@ -130,11 +140,11 @@ impl FromWithTcx 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)), }, } @@ -177,9 +187,7 @@ impl FromWithTcx 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)), } } } @@ -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. @@ -354,12 +362,8 @@ fn convert_lifetime(l: clean::Lifetime) -> String { impl FromWithTcx 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), } } } @@ -381,7 +385,7 @@ impl FromWithTcx for GenericParamDefKind { 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, }, @@ -399,7 +403,7 @@ impl FromWithTcx 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 { @@ -409,8 +413,8 @@ impl FromWithTcx for WherePredicate { .collect(), }, RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate { - lifetime: convert_lifetime(lifetime) - 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) } @@ -428,7 +432,7 @@ impl FromWithTcx 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), } } @@ -464,15 +468,15 @@ impl FromWithTcx for Type { }, clean::Type::DynTrait(bounds, lt) => Type::DynTrait(DynTrait { lifetime: lt.map(convert_lifetime), - traits: bounds.into_iter().map(|t| t.into_tcx(tcx)).collect(), + 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, @@ -516,7 +520,7 @@ impl FromWithTcx 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), } } @@ -550,7 +554,7 @@ impl FromWithTcx 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 } } @@ -563,7 +567,7 @@ impl FromWithTcx for PolyTrait { ) -> Self { PolyTrait { trait_: clean::Type::Path { path: trait_ }.into_tcx(tcx), - generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(), + generic_params: generic_params.into_tcx(tcx), } } } @@ -730,10 +734,7 @@ impl FromWithTcx> for Typedef { impl FromWithTcx 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) } } } @@ -749,10 +750,7 @@ impl FromWithTcx for Static { impl FromWithTcx 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) } } }