From f2ecfc7e2e4ef3c54363f8f939249932bbb352d4 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:18:52 -0800 Subject: [PATCH 01/11] rustdoc: Rename bounds to bindings where appropriate --- src/librustdoc/clean/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9c3484b4a3167..3267e30871069 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -119,7 +119,7 @@ impl Clean for hir::GenericBound<'_> { impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { fn clean(&self, cx: &mut DocContext<'_>) -> Path { - let (trait_ref, bounds) = *self; + let (trait_ref, bindings) = *self; let kind = cx.tcx.def_kind(trait_ref.def_id).into(); if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) { span_bug!( @@ -129,7 +129,7 @@ impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { ); } inline::record_extern_fqn(cx, trait_ref.def_id, kind); - let path = external_path(cx, trait_ref.def_id, true, bounds.to_vec(), trait_ref.substs); + let path = external_path(cx, trait_ref.def_id, true, bindings.to_vec(), trait_ref.substs); debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); @@ -145,7 +145,7 @@ impl Clean for ty::TraitRef<'tcx> { impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { - let (poly_trait_ref, bounds) = *self; + let (poly_trait_ref, bindings) = *self; let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap(); // collect any late bound regions @@ -164,7 +164,7 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { GenericBound::TraitBound( PolyTrait { - trait_: (poly_trait_ref.skip_binder(), bounds).clean(cx), + trait_: (poly_trait_ref.skip_binder(), bindings).clean(cx), generic_params: late_bound_regions, }, hir::TraitBoundModifier::None, From 2fbdc79ae66185b6f32289acd43e48c98d270a05 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:23:18 -0800 Subject: [PATCH 02/11] Remove a Clean impl for a tuple (1) This commit removes the first of nine Clean impls on tuples, converting it to a function instead. The fact that these are impls causes several problems: 1. They are nameless, so it's unclear what they do. 2. It's hard to find where they're used apart from removing them and seeing what errors occur (this applies to all Clean impls, not just the tuple ones). 3. Rustc doesn't currently warn when impls are unused, so dead code can accumulate easily (all Clean impls). 4. Their bodies often use tuple field indexing syntax (e.g., `self.1`) to refer to their "arguments", which makes reading the code more difficult. As I noted, some of these problems apply to all Clean impls, but even those problems are exacerbated by the tuple impls since they make general understanding of the code harder. Converting the impls to functions solves all four of these problems. --- src/librustdoc/clean/mod.rs | 43 ++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3267e30871069..95724cfd00513 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -102,11 +102,9 @@ impl Clean for hir::GenericBound<'_> { _ => bug!("clean: parenthesized `GenericBound::LangItemTrait`"), }; + let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, &bindings); GenericBound::TraitBound( - PolyTrait { - trait_: (trait_ref, &bindings[..]).clean(cx), - generic_params: vec![], - }, + PolyTrait { trait_, generic_params: vec![] }, hir::TraitBoundModifier::None, ) } @@ -117,29 +115,26 @@ impl Clean for hir::GenericBound<'_> { } } -impl Clean for (ty::TraitRef<'_>, &[TypeBinding]) { - fn clean(&self, cx: &mut DocContext<'_>) -> Path { - let (trait_ref, bindings) = *self; - let kind = cx.tcx.def_kind(trait_ref.def_id).into(); - if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) { - span_bug!( - cx.tcx.def_span(trait_ref.def_id), - "`TraitRef` had unexpected kind {:?}", - kind - ); - } - inline::record_extern_fqn(cx, trait_ref.def_id, kind); - let path = external_path(cx, trait_ref.def_id, true, bindings.to_vec(), trait_ref.substs); +fn clean_trait_ref_with_bindings( + cx: &mut DocContext<'_>, + trait_ref: ty::TraitRef<'_>, + bindings: &[TypeBinding], +) -> Path { + let kind = cx.tcx.def_kind(trait_ref.def_id).into(); + if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) { + span_bug!(cx.tcx.def_span(trait_ref.def_id), "`TraitRef` had unexpected kind {:?}", kind); + } + inline::record_extern_fqn(cx, trait_ref.def_id, kind); + let path = external_path(cx, trait_ref.def_id, true, bindings.to_vec(), trait_ref.substs); - debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); + debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); - path - } + path } impl Clean for ty::TraitRef<'tcx> { fn clean(&self, cx: &mut DocContext<'_>) -> Path { - (*self, &[][..]).clean(cx) + clean_trait_ref_with_bindings(cx, *self, &[]) } } @@ -162,11 +157,9 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { }) .collect(); + let trait_ = clean_trait_ref_with_bindings(cx, poly_trait_ref.skip_binder(), bindings); GenericBound::TraitBound( - PolyTrait { - trait_: (poly_trait_ref.skip_binder(), bindings).clean(cx), - generic_params: late_bound_regions, - }, + PolyTrait { trait_, generic_params: late_bound_regions }, hir::TraitBoundModifier::None, ) } From 63d434a36334c10851e72172484c32abf98533c2 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:26:59 -0800 Subject: [PATCH 03/11] Remove a Clean impl for a tuple (2) --- src/librustdoc/clean/mod.rs | 55 +++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 95724cfd00513..54e4cf02232a0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -138,36 +138,37 @@ impl Clean for ty::TraitRef<'tcx> { } } -impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { - let (poly_trait_ref, bindings) = *self; - let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap(); - - // collect any late bound regions - let late_bound_regions: Vec<_> = cx - .tcx - .collect_referenced_late_bound_regions(&poly_trait_ref) - .into_iter() - .filter_map(|br| match br { - ty::BrNamed(_, name) => Some(GenericParamDef { - name, - kind: GenericParamDefKind::Lifetime { outlives: vec![] }, - }), - _ => None, - }) - .collect(); +fn clean_poly_trait_ref_with_bindings( + cx: &mut DocContext<'_>, + poly_trait_ref: ty::PolyTraitRef<'_>, + bindings: &[TypeBinding], +) -> GenericBound { + let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap(); + + // collect any late bound regions + let late_bound_regions: Vec<_> = cx + .tcx + .collect_referenced_late_bound_regions(&poly_trait_ref) + .into_iter() + .filter_map(|br| match br { + ty::BrNamed(_, name) => Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + }), + _ => None, + }) + .collect(); - let trait_ = clean_trait_ref_with_bindings(cx, poly_trait_ref.skip_binder(), bindings); - GenericBound::TraitBound( - PolyTrait { trait_, generic_params: late_bound_regions }, - hir::TraitBoundModifier::None, - ) - } + let trait_ = clean_trait_ref_with_bindings(cx, poly_trait_ref.skip_binder(), bindings); + GenericBound::TraitBound( + PolyTrait { trait_, generic_params: late_bound_regions }, + hir::TraitBoundModifier::None, + ) } impl<'tcx> Clean for ty::PolyTraitRef<'tcx> { fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound { - (*self, &[][..]).clean(cx) + clean_poly_trait_ref_with_bindings(cx, *self, &[]) } } @@ -1513,7 +1514,7 @@ impl<'tcx> Clean for Ty<'tcx> { } } - let bounds: Vec<_> = bounds + let bindings: Vec<_> = bounds .iter() .filter_map(|bound| { if let ty::PredicateKind::Projection(proj) = @@ -1541,7 +1542,7 @@ impl<'tcx> Clean for Ty<'tcx> { }) .collect(); - Some((trait_ref, &bounds[..]).clean(cx)) + Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, &bindings)) }) .collect::>(); bounds.extend(regions); From 927a5e393ccb68fc7166f7737459dad42d5e50ca Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:34:46 -0800 Subject: [PATCH 04/11] Remove a Clean impl for a tuple (3) --- src/librustdoc/clean/auto_trait.rs | 19 +- src/librustdoc/clean/blanket_impl.rs | 6 +- src/librustdoc/clean/inline.rs | 23 ++- src/librustdoc/clean/mod.rs | 289 +++++++++++++-------------- 4 files changed, 172 insertions(+), 165 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 2ccf17387d1c7..7b66ff7d41136 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -100,9 +100,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // Instead, we generate `impl !Send for Foo`, which better // expresses the fact that `Foo` never implements `Send`, // regardless of the choice of `T`. - let params = (tcx.generics_of(item_def_id), ty::GenericPredicates::default()) - .clean(self.cx) - .params; + let raw_generics = clean_ty_generics( + self.cx, + tcx.generics_of(item_def_id), + ty::GenericPredicates::default(), + ); + let params = raw_generics.params; Generics { params, where_predicates: Vec::new() } } @@ -451,10 +454,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { }) .map(|p| p.fold_with(&mut replacer)); - let mut generic_params = - (tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id)) - .clean(self.cx) - .params; + let raw_generics = clean_ty_generics( + self.cx, + tcx.generics_of(item_def_id), + tcx.explicit_predicates_of(item_def_id), + ); + let mut generic_params = raw_generics.params; debug!("param_env_to_generics({:?}): generic_params={:?}", item_def_id, generic_params); diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index f44589f60675f..80e3bb5c6624f 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -107,11 +107,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, - generics: ( + generics: clean_ty_generics( + self.cx, self.cx.tcx.generics_of(impl_def_id), self.cx.tcx.explicit_predicates_of(impl_def_id), - ) - .clean(self.cx), + ), // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. trait_: Some(trait_ref.clean(self.cx)), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ba67030d59fb0..7e5089d0d3741 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -15,13 +15,12 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ - self, utils, Attributes, AttributesExt, ImplKind, ItemId, NestedAttributesExt, Type, + self, clean_ty_generics, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, + NestedAttributesExt, Type, Visibility, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; -use super::{Clean, Visibility}; - type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>; /// Attempt to inline a definition into this AST. @@ -208,7 +207,7 @@ crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Tra .collect(); let predicates = cx.tcx.predicates_of(did); - let generics = (cx.tcx.generics_of(did), predicates).clean(cx); + let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); let is_auto = cx.tcx.trait_is_auto(did); @@ -230,7 +229,9 @@ fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Functi let predicates = cx.tcx.predicates_of(did); let (generics, decl) = clean::enter_impl_trait(cx, |cx| { // NOTE: generics need to be cleaned before the decl! - ((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx)) + let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + let decl = (did, sig).clean(cx); + (generics, decl) }); clean::Function { decl, @@ -243,7 +244,7 @@ fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum { let predicates = cx.tcx.explicit_predicates_of(did); clean::Enum { - generics: (cx.tcx.generics_of(did), predicates).clean(cx), + generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), variants_stripped: false, variants: cx.tcx.adt_def(did).variants.iter().map(|v| v.clean(cx)).collect(), } @@ -255,7 +256,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct { clean::Struct { struct_type: variant.ctor_kind, - generics: (cx.tcx.generics_of(did), predicates).clean(cx), + generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), fields: variant.fields.iter().map(|x| x.clean(cx)).collect(), fields_stripped: false, } @@ -265,7 +266,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 = (cx.tcx.generics_of(did), predicates).clean(cx); + let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); let fields = variant.fields.iter().map(|x| x.clean(cx)).collect(); clean::Union { generics, fields, fields_stripped: false } } @@ -276,7 +277,7 @@ fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef { clean::Typedef { type_, - generics: (cx.tcx.generics_of(did), predicates).clean(cx), + generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), item_type: None, } } @@ -440,7 +441,9 @@ crate fn build_impl( } }) .collect::>(), - clean::enter_impl_trait(cx, |cx| (tcx.generics_of(did), predicates).clean(cx)), + clean::enter_impl_trait(cx, |cx| { + clean_ty_generics(cx, tcx.generics_of(did), predicates) + }), ), }; let polarity = tcx.impl_polarity(did); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 54e4cf02232a0..110ee839f7cd4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -522,170 +522,167 @@ impl Clean for hir::Generics<'_> { } } -impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { - fn clean(&self, cx: &mut DocContext<'_>) -> Generics { - use self::WherePredicate as WP; - use std::collections::BTreeMap; - - let (gens, preds) = *self; - - // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, - // since `Clean for ty::Predicate` would consume them. - let mut impl_trait = BTreeMap::>::default(); - - // Bounds in the type_params and lifetimes fields are repeated in the - // predicates field (see rustc_typeck::collect::ty_generics), so remove - // them. - let stripped_params = gens - .params - .iter() - .filter_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), - ty::GenericParamDefKind::Type { synthetic, .. } => { - if param.name == kw::SelfUpper { - assert_eq!(param.index, 0); - return None; - } - if synthetic { - impl_trait.insert(param.index.into(), vec![]); - return None; - } - Some(param.clean(cx)) +fn clean_ty_generics( + cx: &mut DocContext<'_>, + gens: &ty::Generics, + preds: ty::GenericPredicates<'tcx>, +) -> Generics { + use self::WherePredicate as WP; + use std::collections::BTreeMap; + + // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, + // since `Clean for ty::Predicate` would consume them. + let mut impl_trait = BTreeMap::>::default(); + + // Bounds in the type_params and lifetimes fields are repeated in the + // predicates field (see rustc_typeck::collect::ty_generics), so remove + // them. + let stripped_params = gens + .params + .iter() + .filter_map(|param| match param.kind { + ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), + ty::GenericParamDefKind::Type { synthetic, .. } => { + if param.name == kw::SelfUpper { + assert_eq!(param.index, 0); + return None; } - ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), - }) - .collect::>(); + if synthetic { + impl_trait.insert(param.index.into(), vec![]); + return None; + } + Some(param.clean(cx)) + } + ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), + }) + .collect::>(); - // param index -> [(DefId of trait, associated type name, type)] - let mut impl_trait_proj = FxHashMap::)>>::default(); + // param index -> [(DefId of trait, associated type name, type)] + let mut impl_trait_proj = FxHashMap::)>>::default(); - let where_predicates = preds - .predicates - .iter() - .flat_map(|(p, _)| { - let mut projection = None; - let param_idx = (|| { - let bound_p = p.kind(); - match bound_p.skip_binder() { - ty::PredicateKind::Trait(pred) => { - if let ty::Param(param) = pred.self_ty().kind() { - return Some(param.index); - } - } - ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { - if let ty::Param(param) = ty.kind() { - return Some(param.index); - } + let where_predicates = preds + .predicates + .iter() + .flat_map(|(p, _)| { + let mut projection = None; + let param_idx = (|| { + let bound_p = p.kind(); + match bound_p.skip_binder() { + ty::PredicateKind::Trait(pred) => { + if let ty::Param(param) = pred.self_ty().kind() { + return Some(param.index); } - ty::PredicateKind::Projection(p) => { - if let ty::Param(param) = p.projection_ty.self_ty().kind() { - projection = Some(bound_p.rebind(p)); - return Some(param.index); - } + } + ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { + if let ty::Param(param) = ty.kind() { + return Some(param.index); } - _ => (), } - - None - })(); - - if let Some(param_idx) = param_idx { - if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { - let p = p.clean(cx)?; - - b.extend( - p.get_bounds() - .into_iter() - .flatten() - .cloned() - .filter(|b| !b.is_sized_bound(cx)), - ); - - let proj = projection - .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty)); - if let Some(((_, trait_did, name), rhs)) = - proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) - { - impl_trait_proj - .entry(param_idx) - .or_default() - .push((trait_did, name, rhs)); + ty::PredicateKind::Projection(p) => { + if let ty::Param(param) = p.projection_ty.self_ty().kind() { + projection = Some(bound_p.rebind(p)); + return Some(param.index); } - - return None; } + _ => (), } - Some(p) - }) - .collect::>(); - - for (param, mut bounds) in impl_trait { - // Move trait bounds to the front. - bounds.sort_by_key(|b| !matches!(b, GenericBound::TraitBound(..))); - - if let crate::core::ImplTraitParam::ParamIndex(idx) = param { - if let Some(proj) = impl_trait_proj.remove(&idx) { - for (trait_did, name, rhs) in proj { - let rhs = rhs.clean(cx); - simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs); + None + })(); + + if let Some(param_idx) = param_idx { + if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { + let p = p.clean(cx)?; + + b.extend( + p.get_bounds() + .into_iter() + .flatten() + .cloned() + .filter(|b| !b.is_sized_bound(cx)), + ); + + let proj = projection + .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty)); + if let Some(((_, trait_did, name), rhs)) = + proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) + { + impl_trait_proj.entry(param_idx).or_default().push((trait_did, name, rhs)); } + + return None; } - } else { - unreachable!(); } - cx.impl_trait_bounds.insert(param, bounds); - } + Some(p) + }) + .collect::>(); - // Now that `cx.impl_trait_bounds` is populated, we can process - // remaining predicates which could contain `impl Trait`. - let mut where_predicates = - where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::>(); - - // Type parameters have a Sized bound by default unless removed with - // ?Sized. Scan through the predicates and mark any type parameter with - // a Sized bound, removing the bounds as we find them. - // - // Note that associated types also have a sized bound by default, but we - // don't actually know the set of associated types right here so that's - // handled in cleaning associated types - let mut sized_params = FxHashSet::default(); - where_predicates.retain(|pred| match *pred { - WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => { - if bounds.iter().any(|b| b.is_sized_bound(cx)) { - sized_params.insert(*g); - false - } else { - true + for (param, mut bounds) in impl_trait { + // Move trait bounds to the front. + bounds.sort_by_key(|b| !matches!(b, GenericBound::TraitBound(..))); + + if let crate::core::ImplTraitParam::ParamIndex(idx) = param { + if let Some(proj) = impl_trait_proj.remove(&idx) { + for (trait_did, name, rhs) in proj { + let rhs = rhs.clean(cx); + simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs); } } - _ => true, - }); + } else { + unreachable!(); + } - // Run through the type parameters again and insert a ?Sized - // unbound for any we didn't find to be Sized. - for tp in &stripped_params { - if matches!(tp.kind, types::GenericParamDefKind::Type { .. }) - && !sized_params.contains(&tp.name) - { - where_predicates.push(WP::BoundPredicate { - ty: Type::Generic(tp.name), - bounds: vec![GenericBound::maybe_sized(cx)], - bound_params: Vec::new(), - }) + cx.impl_trait_bounds.insert(param, bounds); + } + + // Now that `cx.impl_trait_bounds` is populated, we can process + // remaining predicates which could contain `impl Trait`. + let mut where_predicates = + where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::>(); + + // Type parameters have a Sized bound by default unless removed with + // ?Sized. Scan through the predicates and mark any type parameter with + // a Sized bound, removing the bounds as we find them. + // + // Note that associated types also have a sized bound by default, but we + // don't actually know the set of associated types right here so that's + // handled in cleaning associated types + let mut sized_params = FxHashSet::default(); + where_predicates.retain(|pred| match *pred { + WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => { + if bounds.iter().any(|b| b.is_sized_bound(cx)) { + sized_params.insert(*g); + false + } else { + true } } + _ => true, + }); - // It would be nice to collect all of the bounds on a type and recombine - // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a` - // and instead see `where T: Foo + Bar + Sized + 'a` - - Generics { - params: stripped_params, - where_predicates: simplify::where_clauses(cx, where_predicates), + // Run through the type parameters again and insert a ?Sized + // unbound for any we didn't find to be Sized. + for tp in &stripped_params { + if matches!(tp.kind, types::GenericParamDefKind::Type { .. }) + && !sized_params.contains(&tp.name) + { + where_predicates.push(WP::BoundPredicate { + ty: Type::Generic(tp.name), + bounds: vec![GenericBound::maybe_sized(cx)], + bound_params: Vec::new(), + }) } } + + // It would be nice to collect all of the bounds on a type and recombine + // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a` + // and instead see `where T: Foo + Bar + Sized + 'a` + + Generics { + params: stripped_params, + where_predicates: simplify::where_clauses(cx, where_predicates), + } } fn clean_fn_or_proc_macro( @@ -1007,9 +1004,11 @@ impl Clean for ty::AssocItem { AssocConstItem(ty.clean(cx), default) } ty::AssocKind::Fn => { - let generics = - (tcx.generics_of(self.def_id), tcx.explicit_predicates_of(self.def_id)) - .clean(cx); + let generics = clean_ty_generics( + cx, + tcx.generics_of(self.def_id), + tcx.explicit_predicates_of(self.def_id), + ); let sig = tcx.fn_sig(self.def_id); let mut decl = (self.def_id, sig).clean(cx); @@ -1080,7 +1079,7 @@ impl Clean for ty::AssocItem { if let ty::TraitContainer(_) = self.container { let bounds = tcx.explicit_item_bounds(self.def_id); let predicates = ty::GenericPredicates { parent: None, predicates: bounds }; - let generics = (tcx.generics_of(self.def_id), predicates).clean(cx); + let generics = clean_ty_generics(cx, tcx.generics_of(self.def_id), predicates); let mut bounds = generics .where_predicates .iter() From f9ed012000e6b97878abe6ad41c7842be23590c3 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:36:06 -0800 Subject: [PATCH 05/11] Clean up definition of `clean_ty_generics` a bit --- src/librustdoc/clean/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 110ee839f7cd4..116364ea31085 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -31,6 +31,7 @@ use rustc_typeck::hir_ty_to_ty; use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; +use std::collections::BTreeMap; use std::default::Default; use std::hash::Hash; use std::{mem, vec}; @@ -527,9 +528,6 @@ fn clean_ty_generics( gens: &ty::Generics, preds: ty::GenericPredicates<'tcx>, ) -> Generics { - use self::WherePredicate as WP; - use std::collections::BTreeMap; - // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, // since `Clean for ty::Predicate` would consume them. let mut impl_trait = BTreeMap::>::default(); @@ -650,7 +648,7 @@ fn clean_ty_generics( // handled in cleaning associated types let mut sized_params = FxHashSet::default(); where_predicates.retain(|pred| match *pred { - WP::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => { + WherePredicate::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => { if bounds.iter().any(|b| b.is_sized_bound(cx)) { sized_params.insert(*g); false @@ -667,7 +665,7 @@ fn clean_ty_generics( if matches!(tp.kind, types::GenericParamDefKind::Type { .. }) && !sized_params.contains(&tp.name) { - where_predicates.push(WP::BoundPredicate { + where_predicates.push(WherePredicate::BoundPredicate { ty: Type::Generic(tp.name), bounds: vec![GenericBound::maybe_sized(cx)], bound_params: Vec::new(), From 9b51072309baf1f22048d59ab127fd7d5b7cc0d8 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:42:38 -0800 Subject: [PATCH 06/11] Remove a Clean impl for a tuple (4) --- src/librustdoc/clean/mod.rs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 116364ea31085..efc0e1945a13a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -730,7 +730,7 @@ fn clean_fn_or_proc_macro( ProcMacroItem(ProcMacro { kind, helpers }) } None => { - let mut func = (sig, generics, body_id).clean(cx); + let mut func = clean_function(cx, sig, generics, body_id); let def_id = item.def_id.to_def_id(); func.header.constness = if cx.tcx.is_const_fn(def_id) && is_unstable_const_fn(cx.tcx, def_id).is_none() { @@ -774,17 +774,20 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib } } -impl<'a> Clean for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId) { - fn clean(&self, cx: &mut DocContext<'_>) -> Function { - let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args - let generics = self.1.clean(cx); - let args = (self.0.decl.inputs, self.2).clean(cx); - let decl = clean_fn_decl_with_args(cx, self.0.decl, args); - (generics, decl) - }); - Function { decl, generics, header: self.0.header } - } +fn clean_function( + cx: &mut DocContext<'_>, + sig: &hir::FnSig<'_>, + generics: &hir::Generics<'_>, + body_id: hir::BodyId, +) -> Function { + let (generics, decl) = enter_impl_trait(cx, |cx| { + // NOTE: generics must be cleaned before args + let generics = generics.clean(cx); + let args = (sig.decl.inputs, body_id).clean(cx); + let decl = clean_fn_decl_with_args(cx, sig.decl, args); + (generics, decl) + }); + Function { decl, generics, header: sig.header } } impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { @@ -901,7 +904,7 @@ impl Clean for hir::TraitItem<'_> { AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx.tcx, e))) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let mut m = (sig, &self.generics, body).clean(cx); + let mut m = clean_function(cx, sig, &self.generics, body); if m.header.constness == hir::Constness::Const && is_unstable_const_fn(cx.tcx, local_did).is_some() { @@ -948,7 +951,7 @@ impl Clean for hir::ImplItem<'_> { AssocConstItem(ty.clean(cx), Some(print_const_expr(cx.tcx, expr))) } hir::ImplItemKind::Fn(ref sig, body) => { - let mut m = (sig, &self.generics, body).clean(cx); + let mut m = clean_function(cx, sig, &self.generics, body); if m.header.constness == hir::Constness::Const && is_unstable_const_fn(cx.tcx, local_did).is_some() { From c39ef72d741a42025f581ceda115858ec3878e9f Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:44:47 -0800 Subject: [PATCH 07/11] Remove a Clean impl for a tuple (5) --- src/librustdoc/clean/mod.rs | 39 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index efc0e1945a13a..3b553cf78e4e6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -790,22 +790,23 @@ fn clean_function( Function { decl, generics, header: sig.header } } -impl<'a> Clean for (&'a [hir::Ty<'a>], &'a [Ident]) { - fn clean(&self, cx: &mut DocContext<'_>) -> Arguments { - Arguments { - values: self - .0 - .iter() - .enumerate() - .map(|(i, ty)| { - let mut name = self.1.get(i).map_or(kw::Empty, |ident| ident.name); - if name.is_empty() { - name = kw::Underscore; - } - Argument { name, type_: ty.clean(cx), is_const: false } - }) - .collect(), - } +fn clean_args_from_types_and_names( + cx: &mut DocContext<'_>, + types: &[hir::Ty<'_>], + names: &[Ident], +) -> Arguments { + Arguments { + values: types + .iter() + .enumerate() + .map(|(i, ty)| { + let mut name = names.get(i).map_or(kw::Empty, |ident| ident.name); + if name.is_empty() { + name = kw::Underscore; + } + Argument { name, type_: ty.clean(cx), is_const: false } + }) + .collect(), } } @@ -916,7 +917,7 @@ impl Clean for hir::TraitItem<'_> { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = self.generics.clean(cx); - let args = (sig.decl.inputs, names).clean(cx); + let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names); let decl = clean_fn_decl_with_args(cx, sig.decl, args); (generics, decl) }); @@ -1714,7 +1715,7 @@ impl Clean for hir::BareFnTy<'_> { let (generic_params, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generic_params = self.generic_params.iter().map(|x| x.clean(cx)).collect(); - let args = (self.decl.inputs, self.param_names).clean(cx); + let args = clean_args_from_types_and_names(cx, self.decl.inputs, self.param_names); let decl = clean_fn_decl_with_args(cx, self.decl, args); (generic_params, decl) }); @@ -2034,7 +2035,7 @@ impl Clean for (&hir::ForeignItem<'_>, Option) { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = generics.clean(cx); - let args = (decl.inputs, names).clean(cx); + let args = clean_args_from_types_and_names(cx, decl.inputs, names); let decl = clean_fn_decl_with_args(cx, decl, args); (generics, decl) }); From 4ede1f8a75ecbc1286ab7ef5b41b562a506bc96e Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:46:19 -0800 Subject: [PATCH 08/11] Remove a Clean impl for a tuple (6) --- src/librustdoc/clean/mod.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3b553cf78e4e6..cbc5537aea6d9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -783,7 +783,7 @@ fn clean_function( let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = generics.clean(cx); - let args = (sig.decl.inputs, body_id).clean(cx); + let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id); let decl = clean_fn_decl_with_args(cx, sig.decl, args); (generics, decl) }); @@ -810,22 +810,23 @@ fn clean_args_from_types_and_names( } } -impl<'a> Clean for (&'a [hir::Ty<'a>], hir::BodyId) { - fn clean(&self, cx: &mut DocContext<'_>) -> Arguments { - let body = cx.tcx.hir().body(self.1); +fn clean_args_from_types_and_body_id( + cx: &mut DocContext<'_>, + types: &[hir::Ty<'_>], + body_id: hir::BodyId, +) -> Arguments { + let body = cx.tcx.hir().body(body_id); - Arguments { - values: self - .0 - .iter() - .enumerate() - .map(|(i, ty)| Argument { - name: name_from_pat(body.params[i].pat), - type_: ty.clean(cx), - is_const: false, - }) - .collect(), - } + Arguments { + values: types + .iter() + .enumerate() + .map(|(i, ty)| Argument { + name: name_from_pat(body.params[i].pat), + type_: ty.clean(cx), + is_const: false, + }) + .collect(), } } From 38c6b13c3a1d390edd248d04ac40eb491b65cf92 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:52:38 -0800 Subject: [PATCH 09/11] Remove a Clean impl for a tuple (7) --- src/librustdoc/clean/inline.rs | 6 ++--- src/librustdoc/clean/mod.rs | 48 ++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 7e5089d0d3741..39544fa843de8 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -15,8 +15,8 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use crate::clean::{ - self, clean_ty_generics, utils, Attributes, AttributesExt, Clean, ImplKind, ItemId, - NestedAttributesExt, Type, Visibility, + self, clean_fn_decl_from_did_and_sig, clean_ty_generics, utils, Attributes, AttributesExt, + Clean, ImplKind, ItemId, NestedAttributesExt, Type, Visibility, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -230,7 +230,7 @@ fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Functi let (generics, decl) = clean::enter_impl_trait(cx, |cx| { // NOTE: generics need to be cleaned before the decl! let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); - let decl = (did, sig).clean(cx); + let decl = clean_fn_decl_from_did_and_sig(cx, did, sig); (generics, decl) }); clean::Function { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cbc5537aea6d9..1103f51513d87 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -838,27 +838,28 @@ fn clean_fn_decl_with_args( FnDecl { inputs: args, output: decl.output.clean(cx), c_variadic: decl.c_variadic } } -impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { - fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl { - let (did, sig) = *self; - let mut names = if did.is_local() { &[] } else { cx.tcx.fn_arg_names(did) }.iter(); - - FnDecl { - output: Return(sig.skip_binder().output().clean(cx)), - c_variadic: sig.skip_binder().c_variadic, - inputs: Arguments { - values: sig - .skip_binder() - .inputs() - .iter() - .map(|t| Argument { - type_: t.clean(cx), - name: names.next().map_or(kw::Empty, |i| i.name), - is_const: false, - }) - .collect(), - }, - } +fn clean_fn_decl_from_did_and_sig( + cx: &mut DocContext<'_>, + did: DefId, + sig: ty::PolyFnSig<'_>, +) -> FnDecl { + let mut names = if did.is_local() { &[] } else { cx.tcx.fn_arg_names(did) }.iter(); + + FnDecl { + output: Return(sig.skip_binder().output().clean(cx)), + c_variadic: sig.skip_binder().c_variadic, + inputs: Arguments { + values: sig + .skip_binder() + .inputs() + .iter() + .map(|t| Argument { + type_: t.clean(cx), + name: names.next().map_or(kw::Empty, |i| i.name), + is_const: false, + }) + .collect(), + }, } } @@ -1013,7 +1014,7 @@ impl Clean for ty::AssocItem { tcx.explicit_predicates_of(self.def_id), ); let sig = tcx.fn_sig(self.def_id); - let mut decl = (self.def_id, sig).clean(cx); + let mut decl = clean_fn_decl_from_did_and_sig(cx, self.def_id, sig); if self.fn_has_self_parameter { let self_ty = match self.container { @@ -1407,10 +1408,11 @@ impl<'tcx> Clean for Ty<'tcx> { let ty = cx.tcx.lift(*self).expect("FnPtr lift failed"); let sig = ty.fn_sig(cx.tcx); let def_id = DefId::local(CRATE_DEF_INDEX); + let decl = clean_fn_decl_from_did_and_sig(cx, def_id, sig); BareFunction(box BareFunctionDecl { unsafety: sig.unsafety(), generic_params: Vec::new(), - decl: (def_id, sig).clean(cx), + decl, abi: sig.abi(), }) } From de5ea80437fbeb5fe0c80547f53bc5a48bc129be Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:55:59 -0800 Subject: [PATCH 10/11] Remove a Clean impl for a tuple (8) --- src/librustdoc/clean/mod.rs | 175 ++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 86 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1103f51513d87..bd2a69acfb07a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -54,7 +54,11 @@ impl Clean for DocModule<'_> { let mut items: Vec = vec![]; items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); - items.extend(self.items.iter().map(|x| x.clean(cx)).flatten()); + items.extend( + self.items + .iter() + .flat_map(|(item, renamed)| clean_maybe_renamed_item(cx, item, *renamed)), + ); // determine if we should display the inner contents or // the outer `mod` item for the source code. @@ -1726,94 +1730,93 @@ impl Clean for hir::BareFnTy<'_> { } } -impl Clean> for (&hir::Item<'_>, Option) { - fn clean(&self, cx: &mut DocContext<'_>) -> Vec { - use hir::ItemKind; - - let (item, renamed) = self; - let def_id = item.def_id.to_def_id(); - let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); - cx.with_param_env(def_id, |cx| { - let kind = match item.kind { - ItemKind::Static(ty, mutability, body_id) => { - StaticItem(Static { type_: ty.clean(cx), mutability, expr: Some(body_id) }) - } - ItemKind::Const(ty, body_id) => ConstantItem(Constant { - type_: ty.clean(cx), - kind: ConstantKind::Local { body: body_id, def_id }, - }), - ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy { - bounds: ty.bounds.iter().map(|x| x.clean(cx)).collect(), - generics: ty.generics.clean(cx), - }), - ItemKind::TyAlias(hir_ty, ref generics) => { - let rustdoc_ty = hir_ty.clean(cx); - let ty = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx); - TypedefItem( - Typedef { - type_: rustdoc_ty, - generics: generics.clean(cx), - item_type: Some(ty), - }, - false, - ) - } - ItemKind::Enum(ref def, ref generics) => EnumItem(Enum { - variants: def.variants.iter().map(|v| v.clean(cx)).collect(), - generics: generics.clean(cx), - variants_stripped: false, - }), - ItemKind::TraitAlias(ref generics, bounds) => TraitAliasItem(TraitAlias { +fn clean_maybe_renamed_item( + cx: &mut DocContext<'_>, + item: &hir::Item<'_>, + renamed: Option, +) -> Vec { + use hir::ItemKind; + + let def_id = item.def_id.to_def_id(); + let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + cx.with_param_env(def_id, |cx| { + let kind = match item.kind { + ItemKind::Static(ty, mutability, body_id) => { + StaticItem(Static { type_: ty.clean(cx), mutability, expr: Some(body_id) }) + } + ItemKind::Const(ty, body_id) => ConstantItem(Constant { + type_: ty.clean(cx), + kind: ConstantKind::Local { body: body_id, def_id }, + }), + ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy { + bounds: ty.bounds.iter().map(|x| x.clean(cx)).collect(), + generics: ty.generics.clean(cx), + }), + ItemKind::TyAlias(hir_ty, ref generics) => { + let rustdoc_ty = hir_ty.clean(cx); + let ty = hir_ty_to_ty(cx.tcx, hir_ty).clean(cx); + TypedefItem( + Typedef { + type_: rustdoc_ty, + generics: generics.clean(cx), + item_type: Some(ty), + }, + false, + ) + } + ItemKind::Enum(ref def, ref generics) => EnumItem(Enum { + variants: def.variants.iter().map(|v| v.clean(cx)).collect(), + generics: generics.clean(cx), + variants_stripped: false, + }), + ItemKind::TraitAlias(ref generics, bounds) => TraitAliasItem(TraitAlias { + generics: generics.clean(cx), + bounds: bounds.iter().map(|x| x.clean(cx)).collect(), + }), + ItemKind::Union(ref variant_data, ref generics) => UnionItem(Union { + generics: generics.clean(cx), + fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(), + fields_stripped: false, + }), + ItemKind::Struct(ref variant_data, ref generics) => StructItem(Struct { + struct_type: CtorKind::from_hir(variant_data), + generics: generics.clean(cx), + fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(), + fields_stripped: false, + }), + ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.hir_id(), cx), + // proc macros can have a name set by attributes + ItemKind::Fn(ref sig, ref generics, body_id) => { + clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) + } + ItemKind::Macro(ref macro_def) => { + let ty_vis = cx.tcx.visibility(def_id).clean(cx); + MacroItem(Macro { + source: display_macro_source(cx, name, macro_def, def_id, ty_vis), + }) + } + ItemKind::Trait(is_auto, unsafety, ref generics, bounds, item_ids) => { + let items = + item_ids.iter().map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)).collect(); + TraitItem(Trait { + unsafety, + items, generics: generics.clean(cx), bounds: bounds.iter().map(|x| x.clean(cx)).collect(), - }), - ItemKind::Union(ref variant_data, ref generics) => UnionItem(Union { - generics: generics.clean(cx), - fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, - }), - ItemKind::Struct(ref variant_data, ref generics) => StructItem(Struct { - struct_type: CtorKind::from_hir(variant_data), - generics: generics.clean(cx), - fields: variant_data.fields().iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, - }), - ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.hir_id(), cx), - // proc macros can have a name set by attributes - ItemKind::Fn(ref sig, ref generics, body_id) => { - clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) - } - ItemKind::Macro(ref macro_def) => { - let ty_vis = cx.tcx.visibility(def_id).clean(cx); - MacroItem(Macro { - source: display_macro_source(cx, name, macro_def, def_id, ty_vis), - }) - } - ItemKind::Trait(is_auto, unsafety, ref generics, bounds, item_ids) => { - let items = item_ids - .iter() - .map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)) - .collect(); - TraitItem(Trait { - unsafety, - items, - generics: generics.clean(cx), - bounds: bounds.iter().map(|x| x.clean(cx)).collect(), - is_auto: is_auto.clean(cx), - }) - } - ItemKind::ExternCrate(orig_name) => { - return clean_extern_crate(item, name, orig_name, cx); - } - ItemKind::Use(path, kind) => { - return clean_use_statement(item, name, path, kind, cx); - } - _ => unreachable!("not yet converted"), - }; + is_auto: is_auto.clean(cx), + }) + } + ItemKind::ExternCrate(orig_name) => { + return clean_extern_crate(item, name, orig_name, cx); + } + ItemKind::Use(path, kind) => { + return clean_use_statement(item, name, path, kind, cx); + } + _ => unreachable!("not yet converted"), + }; - vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] - }) - } + vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] + }) } impl Clean for hir::Variant<'_> { From e36561dbddd9a91f84a93e2d9956d79d960c44cf Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 3 Dec 2021 13:58:17 -0800 Subject: [PATCH 11/11] Remove a Clean impl for a tuple (9) This was the last one! --- src/librustdoc/clean/mod.rs | 91 +++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bd2a69acfb07a..f11fa0295c522 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -52,7 +52,11 @@ crate trait Clean { impl Clean for DocModule<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> Item { let mut items: Vec = vec![]; - items.extend(self.foreigns.iter().map(|x| x.clean(cx))); + items.extend( + self.foreigns + .iter() + .map(|(item, renamed)| clean_maybe_renamed_foreign_item(cx, item, *renamed)), + ); items.extend(self.mods.iter().map(|x| x.clean(cx))); items.extend( self.items @@ -2030,50 +2034,51 @@ fn clean_use_statement( vec![Item::from_def_id_and_parts(import.def_id.to_def_id(), None, ImportItem(inner), cx)] } -impl Clean for (&hir::ForeignItem<'_>, Option) { - fn clean(&self, cx: &mut DocContext<'_>) -> Item { - let (item, renamed) = self; - let def_id = item.def_id.to_def_id(); - cx.with_param_env(def_id, |cx| { - let kind = match item.kind { - hir::ForeignItemKind::Fn(decl, names, ref generics) => { - let abi = cx.tcx.hir().get_foreign_abi(item.hir_id()); - let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args - let generics = generics.clean(cx); - let args = clean_args_from_types_and_names(cx, decl.inputs, names); - let decl = clean_fn_decl_with_args(cx, decl, args); - (generics, decl) - }); - ForeignFunctionItem(Function { - decl, - generics, - header: hir::FnHeader { - unsafety: if abi == Abi::RustIntrinsic { - intrinsic_operation_unsafety(item.ident.name) - } else { - hir::Unsafety::Unsafe - }, - abi, - constness: hir::Constness::NotConst, - asyncness: hir::IsAsync::NotAsync, +fn clean_maybe_renamed_foreign_item( + cx: &mut DocContext<'_>, + item: &hir::ForeignItem<'_>, + renamed: Option, +) -> Item { + let def_id = item.def_id.to_def_id(); + cx.with_param_env(def_id, |cx| { + let kind = match item.kind { + hir::ForeignItemKind::Fn(decl, names, ref generics) => { + let abi = cx.tcx.hir().get_foreign_abi(item.hir_id()); + let (generics, decl) = enter_impl_trait(cx, |cx| { + // NOTE: generics must be cleaned before args + let generics = generics.clean(cx); + let args = clean_args_from_types_and_names(cx, decl.inputs, names); + let decl = clean_fn_decl_with_args(cx, decl, args); + (generics, decl) + }); + ForeignFunctionItem(Function { + decl, + generics, + header: hir::FnHeader { + unsafety: if abi == Abi::RustIntrinsic { + intrinsic_operation_unsafety(item.ident.name) + } else { + hir::Unsafety::Unsafe }, - }) - } - hir::ForeignItemKind::Static(ref ty, mutability) => { - ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: None }) - } - hir::ForeignItemKind::Type => ForeignTypeItem, - }; + abi, + constness: hir::Constness::NotConst, + asyncness: hir::IsAsync::NotAsync, + }, + }) + } + hir::ForeignItemKind::Static(ref ty, mutability) => { + ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: None }) + } + hir::ForeignItemKind::Type => ForeignTypeItem, + }; - Item::from_hir_id_and_parts( - item.hir_id(), - Some(renamed.unwrap_or(item.ident.name)), - kind, - cx, - ) - }) - } + Item::from_hir_id_and_parts( + item.hir_id(), + Some(renamed.unwrap_or(item.ident.name)), + kind, + cx, + ) + }) } impl Clean for hir::TypeBinding<'_> {