diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fb178cbd95e7b..bd69c8cb47996 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -6,7 +6,7 @@ use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; use std::fmt::Debug; -use super::*; +use crate::clean::{self, *}; #[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)] enum RegionTarget<'tcx> { @@ -485,7 +485,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // of the type. // Therefore, we make sure that we never add a ?Sized // bound for projections - if let Type::QPath { .. } = ty { + if let Type::QPath(_) = ty { has_sized.insert(ty.clone()); } @@ -546,13 +546,18 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } WherePredicate::EqPredicate { lhs, rhs } => { match lhs { - Type::QPath { ref assoc, ref self_type, ref trait_, .. } => { + Type::QPath(box clean::QPathData { + ref assoc, + ref self_type, + ref trait_, + .. + }) => { let ty = &*self_type; let mut new_trait = trait_.clone(); if self.is_fn_trait(trait_) && assoc.name == sym::Output { ty_to_fn - .entry(*ty.clone()) + .entry(ty.clone()) .and_modify(|e| { *e = (e.0.clone(), Some(rhs.ty().unwrap().clone())) }) @@ -571,7 +576,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // to 'T: Iterator' GenericArgs::AngleBracketed { ref mut bindings, .. } => { bindings.push(TypeBinding { - assoc: *assoc.clone(), + assoc: assoc.clone(), kind: TypeBindingKind::Equality { term: rhs }, }); } @@ -585,7 +590,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } } - let bounds = ty_to_bounds.entry(*ty.clone()).or_default(); + let bounds = ty_to_bounds.entry(ty.clone()).or_default(); bounds.insert(GenericBound::TraitBound( PolyTrait { trait_: new_trait, generic_params: Vec::new() }, @@ -602,7 +607,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { )); // Avoid creating any new duplicate bounds later in the outer // loop - ty_to_traits.entry(*ty.clone()).or_default().insert(trait_.clone()); + ty_to_traits.entry(ty.clone()).or_default().insert(trait_.clone()); } _ => panic!("Unexpected LHS {:?} for {:?}", lhs, item_def_id), } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index a82abe6692655..cd933976218b8 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -640,7 +640,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean: g.where_predicates.retain(|pred| match pred { clean::WherePredicate::BoundPredicate { - ty: clean::QPath { self_type: box clean::Generic(ref s), trait_, .. }, + ty: clean::QPath(box clean::QPathData { self_type: clean::Generic(ref s), trait_, .. }), bounds, .. } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f3070fb35f1d0..d5694b4ad356e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -395,12 +395,12 @@ fn clean_projection<'tcx>( self_type.def_id(&cx.cache) }; let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); - Type::QPath { - assoc: Box::new(projection_to_path_segment(ty, cx)), + Type::QPath(Box::new(QPathData { + assoc: projection_to_path_segment(ty, cx), should_show_cast, - self_type: box self_type, + self_type: self_type, trait_, - } + })) } impl<'tcx> Clean<'tcx, Type> for ty::ProjectionTy<'tcx> { @@ -1180,7 +1180,10 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { .where_predicates .drain_filter(|pred| match *pred { WherePredicate::BoundPredicate { - ty: QPath { ref assoc, ref self_type, ref trait_, .. }, + ty: + QPath(box QPathData { + ref assoc, ref self_type, ref trait_, .. + }), .. } => { if assoc.name != my_name { @@ -1189,7 +1192,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { if trait_.def_id() != self.container.id() { return false; } - match **self_type { + match *self_type { Generic(ref s) if *s == kw::SelfUpper => {} _ => return false, } @@ -1315,12 +1318,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type let self_def_id = DefId::local(qself.hir_id.owner.local_def_index); let self_type = qself.clean(cx); let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type); - Type::QPath { - assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)), + Type::QPath(Box::new(QPathData { + assoc: p.segments.last().expect("segments were empty").clean(cx), should_show_cast, - self_type: box self_type, + self_type, trait_, - } + })) } hir::QPath::TypeRelative(qself, segment) => { let ty = hir_ty_to_ty(cx.tcx, hir_ty); @@ -1335,12 +1338,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type let self_def_id = res.opt_def_id(); let self_type = qself.clean(cx); let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); - Type::QPath { - assoc: Box::new(segment.clean(cx)), + Type::QPath(Box::new(QPathData { + assoc: segment.clean(cx), should_show_cast, - self_type: box self_type, + self_type, trait_, - } + })) } hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"), } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4605793d0df94..25679e49adb45 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1564,13 +1564,7 @@ pub(crate) enum Type { BorrowedRef { lifetime: Option, mutability: Mutability, type_: Box }, /// A qualified path to an associated item: `::Name` - QPath { - assoc: Box, - self_type: Box, - /// FIXME: compute this field on demand. - should_show_cast: bool, - trait_: Path, - }, + QPath(Box), /// A type that is inferred: `_` Infer, @@ -1581,7 +1575,16 @@ pub(crate) enum Type { // `Type` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Type, 72); +rustc_data_structures::static_assert_size!(Type, 56); + +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub(crate) struct QPathData { + pub(crate) assoc: PathSegment, + pub(crate) self_type: Type, + /// FIXME: compute this field on demand. + pub(crate) should_show_cast: bool, + pub(crate) trait_: Path, +} impl Type { /// When comparing types for equality, it can help to ignore `&` wrapping. @@ -1676,8 +1679,9 @@ impl Type { } pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { - if let QPath { self_type, trait_, assoc, .. } = self { - Some((self_type, trait_.def_id(), *assoc.clone())) + if let QPath(qpath) = self { + let QPathData { self_type, trait_, assoc, .. } = &**qpath; + Some((self_type, trait_.def_id(), assoc.clone())) } else { None } @@ -1701,7 +1705,7 @@ impl Type { Slice(..) => PrimitiveType::Slice, Array(..) => PrimitiveType::Array, RawPointer(..) => PrimitiveType::RawPointer, - QPath { ref self_type, .. } => return self_type.inner_def_id(cache), + QPath(ref qpath) => return qpath.self_type.inner_def_id(cache), Generic(_) | Infer | ImplTrait(_) => return None, }; cache.and_then(|c| Primitive(t).def_id(c)) @@ -2222,7 +2226,7 @@ pub(crate) enum GenericArg { // `GenericArg` can occur many times in a single `Path`, so make sure it // doesn't increase in size unexpectedly. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(GenericArg, 80); +rustc_data_structures::static_assert_size!(GenericArg, 64); #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericArgs { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index b7789493df647..eaa7cf72dfe55 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -980,7 +980,12 @@ fn fmt_type<'cx>( write!(f, "impl {}", print_generic_bounds(bounds, cx)) } } - clean::QPath { ref assoc, ref self_type, ref trait_, should_show_cast } => { + clean::QPath(box clean::QPathData { + ref assoc, + ref self_type, + ref trait_, + should_show_cast, + }) => { if f.alternate() { if should_show_cast { write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))? diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index cb887d16906a1..8ddd44025849c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2629,8 +2629,8 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec { clean::Type::BorrowedRef { type_, .. } => { work.push_back(*type_); } - clean::Type::QPath { self_type, trait_, .. } => { - work.push_back(*self_type); + clean::Type::QPath(box clean::QPathData { self_type, trait_, .. }) => { + work.push_back(self_type); process_path(trait_.def_id()); } _ => {} diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 9f302cc256659..8938470a15c2b 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -235,7 +235,7 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option { | clean::Tuple(_) | clean::Slice(_) | clean::Array(_, _) - | clean::QPath { .. } + | clean::QPath(_) | clean::Infer => None, } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 51a2abc50bc2b..054e7e3f3190c 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -473,13 +473,13 @@ impl FromWithTcx for Type { mutable: mutability == ast::Mutability::Mut, type_: Box::new((*type_).into_tcx(tcx)), }, - QPath { assoc, self_type, trait_, .. } => { + QPath(box clean::QPathData { assoc, self_type, trait_, .. }) => { // FIXME: should `trait_` be a clean::Path equivalent in JSON? let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx); Type::QualifiedPath { name: assoc.name.to_string(), args: Box::new(assoc.args.clone().into_tcx(tcx)), - self_type: Box::new((*self_type).into_tcx(tcx)), + self_type: Box::new(self_type.into_tcx(tcx)), trait_: Box::new(trait_), } }