diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fbc2c3c5af459..ae756f2b1fc74 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -106,6 +106,7 @@ where self.cx, tcx.generics_of(item_def_id), ty::GenericPredicates::default(), + item_def_id, ); let params = raw_generics.params; @@ -456,6 +457,7 @@ where self.cx, tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id), + item_def_id, ); let mut generic_params = raw_generics.params; diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 47cfe651e319d..983d3be2d474c 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -101,6 +101,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { cx, cx.tcx.generics_of(impl_def_id), cx.tcx.explicit_predicates_of(impl_def_id), + impl_def_id, ), // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 03f62f41a26f4..3486a986c88eb 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -270,7 +270,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean .collect(); let predicates = cx.tcx.predicates_of(did); - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates, did); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } @@ -282,8 +282,12 @@ pub(crate) fn build_function<'tcx>( ) -> Box { let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); // The generics need to be cleaned before the signature. - let mut generics = - clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id)); + let mut generics = clean_ty_generics( + cx, + cx.tcx.generics_of(def_id), + cx.tcx.explicit_predicates_of(def_id), + def_id, + ); let bound_vars = clean_bound_vars(sig.bound_vars()); // At the time of writing early & late-bound params are stored separately in rustc, @@ -315,7 +319,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum { let predicates = cx.tcx.explicit_predicates_of(did); clean::Enum { - generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), + generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates, did), variants: cx.tcx.adt_def(did).variants().iter().map(|v| clean_variant_def(v, cx)).collect(), } } @@ -326,7 +330,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct { clean::Struct { ctor_kind: variant.ctor_kind(), - generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), + generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates, did), fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(), } } @@ -335,7 +339,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { let predicates = cx.tcx.explicit_predicates_of(did); let variant = cx.tcx.adt_def(did).non_enum_variant(); - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates, did); let fields = variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(); clean::Union { generics, fields } } @@ -352,7 +356,7 @@ fn build_type_alias( Box::new(clean::TypeAlias { type_, - generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), + generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates, did), inner_type, item_type: None, }) @@ -530,7 +534,7 @@ pub(crate) fn build_impl( }) .map(|item| clean_impl_item(item, cx)) .collect::>(), - clean_generics(impl_.generics, cx), + clean_generics(impl_.generics, cx, did), ), None => ( tcx.associated_items(did) @@ -558,7 +562,7 @@ pub(crate) fn build_impl( .map(|item| clean_middle_assoc_item(item, cx)) .collect::>(), clean::enter_impl_trait(cx, |cx| { - clean_ty_generics(cx, tcx.generics_of(did), predicates) + clean_ty_generics(cx, tcx.generics_of(did), predicates, did) }), ), }; @@ -716,8 +720,12 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { } fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { - let mut generics = - clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id)); + let mut generics = clean_ty_generics( + cx, + cx.tcx.generics_of(def_id), + cx.tcx.explicit_predicates_of(def_id), + def_id, + ); clean::simplify::move_bounds_to_generic_parameters(&mut generics); clean::Constant { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b32d3ad562d03..f4110428e5c27 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -631,22 +631,18 @@ fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool { } pub(crate) fn clean_generics<'tcx>( - gens: &hir::Generics<'tcx>, + generics: &hir::Generics<'tcx>, cx: &mut DocContext<'tcx>, + _item_def_id: DefId, ) -> Generics { - let impl_trait_params = gens + let impl_trait_params = generics .params .iter() .filter(|param| is_impl_trait(param)) .map(|param| { - let param = clean_generic_param(cx, Some(gens), param); - match param.kind { - GenericParamDefKind::Lifetime { .. } => unreachable!(), - GenericParamDefKind::Type { ref bounds, .. } => { - cx.impl_trait_bounds.insert(param.def_id.into(), bounds.to_vec()); - } - GenericParamDefKind::Const { .. } => unreachable!(), - } + let param = clean_generic_param(cx, Some(generics), param); + let GenericParamDefKind::Type { bounds, .. } = ¶m.kind else { unreachable!() }; + cx.impl_trait_bounds.insert(param.def_id.into(), bounds.to_vec()); param }) .collect::>(); @@ -654,7 +650,7 @@ pub(crate) fn clean_generics<'tcx>( let mut bound_predicates = FxIndexMap::default(); let mut region_predicates = FxIndexMap::default(); let mut eq_predicates = ThinVec::default(); - for pred in gens.predicates.iter().filter_map(|x| clean_where_predicate(x, cx)) { + for pred in generics.predicates.iter().filter_map(|x| clean_where_predicate(x, cx)) { match pred { WherePredicate::BoundPredicate { ty, bounds, bound_params } => { match bound_predicates.entry(ty) { @@ -697,15 +693,15 @@ pub(crate) fn clean_generics<'tcx>( } } - let mut params = ThinVec::with_capacity(gens.params.len()); + let mut params = ThinVec::with_capacity(generics.params.len()); // In this loop, we gather the generic parameters (`<'a, B: 'a>`) and check if they have // bounds in the where predicates. If so, we move their bounds into the where predicates // while also preventing duplicates. - for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { - let mut p = clean_generic_param(cx, Some(gens), p); - match &mut p.kind { - GenericParamDefKind::Lifetime { ref mut outlives } => { - if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) { + for param in generics.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { + let mut param = clean_generic_param(cx, Some(generics), param); + match &mut param.kind { + GenericParamDefKind::Lifetime { outlives } => { + if let Some(region_pred) = region_predicates.get_mut(&Lifetime(param.name)) { // We merge bounds in the `where` clause. for outlive in outlives.drain(..) { let outlive = GenericBound::Outlives(outlive); @@ -716,7 +712,7 @@ pub(crate) fn clean_generics<'tcx>( } } GenericParamDefKind::Type { bounds, synthetic: false, .. } => { - if let Some(bound_pred) = bound_predicates.get_mut(&Type::Generic(p.name)) { + if let Some(bound_pred) = bound_predicates.get_mut(&Type::Generic(param.name)) { // We merge bounds in the `where` clause. for bound in bounds.drain(..) { if !bound_pred.0.contains(&bound) { @@ -729,7 +725,7 @@ pub(crate) fn clean_generics<'tcx>( // nothing to do here. } } - params.push(p); + params.push(param); } params.extend(impl_trait_params); @@ -754,8 +750,9 @@ pub(crate) fn clean_generics<'tcx>( fn clean_ty_generics<'tcx>( cx: &mut DocContext<'tcx>, - gens: &ty::Generics, - preds: ty::GenericPredicates<'tcx>, + generics: &ty::Generics, + predicates: ty::GenericPredicates<'tcx>, + _item_def_id: DefId, ) -> Generics { // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, // since `Clean for ty::Predicate` would consume them. @@ -764,7 +761,7 @@ fn clean_ty_generics<'tcx>( // Bounds in the type_params and lifetimes fields are repeated in the // predicates field (see rustc_hir_analysis::collect::ty_generics), so remove // them. - let stripped_params = gens + let stripped_params = generics .params .iter() .filter_map(|param| match param.kind { @@ -790,7 +787,7 @@ fn clean_ty_generics<'tcx>( let mut impl_trait_proj = FxHashMap::>)>>::default(); - let where_predicates = preds + let where_predicates = predicates .predicates .iter() .flat_map(|(pred, _)| { @@ -1040,7 +1037,13 @@ fn clean_fn_or_proc_macro<'tcx>( match macro_kind { Some(kind) => clean_proc_macro(item, name, kind, cx), None => { - let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id)); + let mut func = clean_function( + cx, + item.owner_id.to_def_id(), + sig, + generics, + FunctionArgs::Body(body_id), + ); clean_fn_decl_legacy_const_generics(&mut func, attrs); FunctionItem(func) } @@ -1087,13 +1090,14 @@ enum FunctionArgs<'tcx> { fn clean_function<'tcx>( cx: &mut DocContext<'tcx>, + did: DefId, sig: &hir::FnSig<'tcx>, generics: &hir::Generics<'tcx>, args: FunctionArgs<'tcx>, ) -> Box { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args - let generics = clean_generics(generics, cx); + let generics = clean_generics(generics, cx, did); let args = match args { FunctionArgs::Body(body_id) => { clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id) @@ -1232,31 +1236,41 @@ fn clean_poly_trait_ref<'tcx>( } fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext<'tcx>) -> Item { - let local_did = trait_item.owner_id.to_def_id(); - cx.with_param_env(local_did, |cx| { + let def_id = trait_item.owner_id.to_def_id(); + cx.with_param_env(def_id, |cx| { let inner = match trait_item.kind { hir::TraitItemKind::Const(ty, Some(default)) => { - let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); + let generics = + enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx, def_id)); AssocConstItem( generics, Box::new(clean_ty(ty, cx)), - ConstantKind::Local { def_id: local_did, body: default }, + ConstantKind::Local { def_id, body: default }, ) } hir::TraitItemKind::Const(ty, None) => { - let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); + let generics = + enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx, def_id)); TyAssocConstItem(generics, Box::new(clean_ty(ty, cx))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); + let m = + clean_function(cx, def_id, sig, trait_item.generics, FunctionArgs::Body(body)); MethodItem(m, None) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { - let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names)); + let m = clean_function( + cx, + def_id, + sig, + trait_item.generics, + FunctionArgs::Names(names), + ); TyMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { - let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); + let generics = + enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx, def_id)); let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(); let item_type = clean_middle_ty( ty::Binder::dummy(hir_ty_to_ty(cx.tcx, default)), @@ -1275,12 +1289,13 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext ) } hir::TraitItemKind::Type(bounds, None) => { - let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); + let generics = + enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx, def_id)); let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(); TyAssocTypeItem(generics, bounds) } }; - Item::from_def_id_and_parts(local_did, Some(trait_item.ident.name), inner, cx) + Item::from_def_id_and_parts(def_id, Some(trait_item.ident.name), inner, cx) }) } @@ -1288,22 +1303,22 @@ pub(crate) fn clean_impl_item<'tcx>( impl_: &hir::ImplItem<'tcx>, cx: &mut DocContext<'tcx>, ) -> Item { - let local_did = impl_.owner_id.to_def_id(); - cx.with_param_env(local_did, |cx| { + let def_id = impl_.owner_id.to_def_id(); + cx.with_param_env(def_id, |cx| { let inner = match impl_.kind { hir::ImplItemKind::Const(ty, expr) => { - let generics = clean_generics(impl_.generics, cx); - let default = ConstantKind::Local { def_id: local_did, body: expr }; + let generics = clean_generics(impl_.generics, cx, def_id); + let default = ConstantKind::Local { def_id, body: expr }; AssocConstItem(generics, Box::new(clean_ty(ty, cx)), default) } hir::ImplItemKind::Fn(ref sig, body) => { - let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body)); + let m = clean_function(cx, def_id, sig, impl_.generics, FunctionArgs::Body(body)); let defaultness = cx.tcx.defaultness(impl_.owner_id); MethodItem(m, Some(defaultness)) } hir::ImplItemKind::Type(hir_ty) => { let type_ = clean_ty(hir_ty, cx); - let generics = clean_generics(impl_.generics, cx); + let generics = clean_generics(impl_.generics, cx, def_id); let item_type = clean_middle_ty( ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)), cx, @@ -1322,7 +1337,7 @@ pub(crate) fn clean_impl_item<'tcx>( } }; - Item::from_def_id_and_parts(local_did, Some(impl_.ident.name), inner, cx) + Item::from_def_id_and_parts(def_id, Some(impl_.ident.name), inner, cx) }) } @@ -1344,6 +1359,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( cx, tcx.generics_of(assoc_item.def_id), tcx.explicit_predicates_of(assoc_item.def_id), + assoc_item.def_id, ); simplify::move_bounds_to_generic_parameters(&mut generics); @@ -1428,6 +1444,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( cx, tcx.generics_of(assoc_item.def_id), ty::GenericPredicates { parent: None, predicates }, + assoc_item.def_id, ); simplify::move_bounds_to_generic_parameters(&mut generics); @@ -2731,12 +2748,12 @@ fn clean_maybe_renamed_item<'tcx>( } ItemKind::Const(ty, generics, body_id) => ConstantItem(Constant { type_: Box::new(clean_ty(ty, cx)), - generics: clean_generics(generics, cx), + generics: clean_generics(generics, cx, def_id), kind: ConstantKind::Local { body: body_id, def_id }, }), ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy { bounds: ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), - generics: clean_generics(ty.generics, cx), + generics: clean_generics(ty.generics, cx, def_id), }), ItemKind::TyAlias(hir_ty, generics) => { *cx.current_type_aliases.entry(def_id).or_insert(0) += 1; @@ -2747,7 +2764,7 @@ fn clean_maybe_renamed_item<'tcx>( None, None, ); - let generics = clean_generics(generics, cx); + let generics = clean_generics(generics, cx, def_id); if let Some(count) = cx.current_type_aliases.get_mut(&def_id) { *count -= 1; if *count == 0 { @@ -2777,19 +2794,19 @@ fn clean_maybe_renamed_item<'tcx>( } ItemKind::Enum(ref def, generics) => EnumItem(Enum { variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(), - generics: clean_generics(generics, cx), + generics: clean_generics(generics, cx, def_id), }), ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias { - generics: clean_generics(generics, cx), + generics: clean_generics(generics, cx, def_id), bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), }), ItemKind::Union(ref variant_data, generics) => UnionItem(Union { - generics: clean_generics(generics, cx), + generics: clean_generics(generics, cx, def_id), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), ItemKind::Struct(ref variant_data, generics) => StructItem(Struct { ctor_kind: variant_data.ctor_kind(), - generics: clean_generics(generics, cx), + generics: clean_generics(generics, cx, def_id), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), @@ -2813,7 +2830,7 @@ fn clean_maybe_renamed_item<'tcx>( TraitItem(Box::new(Trait { def_id, items, - generics: clean_generics(generics, cx), + generics: clean_generics(generics, cx, def_id), bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), })) } @@ -2876,7 +2893,7 @@ fn clean_impl<'tcx>( let mut make_item = |trait_: Option, for_: Type, items: Vec| { let kind = ImplItem(Box::new(Impl { unsafety: impl_.unsafety, - generics: clean_generics(impl_.generics, cx), + generics: clean_generics(impl_.generics, cx, def_id.to_def_id()), trait_, for_, items, @@ -3086,7 +3103,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>( hir::ForeignItemKind::Fn(decl, names, generics) => { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args - let generics = clean_generics(generics, cx); + let generics = clean_generics(generics, cx, def_id); let args = clean_args_from_types_and_names(cx, decl.inputs, names); let decl = clean_fn_decl_with_args(cx, decl, None, args); (generics, decl)