From 2aa4aa70ddd11ebc56667dbb3907c93a5a0176c2 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 16 Aug 2022 12:48:04 -0700 Subject: [PATCH] rustdoc: factor Type::QPath out into its own box This reduces the size of Type. --- src/librustdoc/clean/auto_trait.rs | 12 +++++++----- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 31 ++++++++++++++---------------- src/librustdoc/clean/types.rs | 27 ++++++++++++++------------ src/librustdoc/html/format.rs | 7 ++++++- src/librustdoc/html/render/mod.rs | 4 ++-- src/librustdoc/json/conversions.rs | 4 ++-- 7 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a94520b12192..5441a7bd29ec 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -551,13 +551,15 @@ where } WherePredicate::EqPredicate { lhs, rhs } => { match lhs { - Type::QPath { ref assoc, ref self_type, ref trait_, .. } => { + Type::QPath(box 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())) }) @@ -582,7 +584,7 @@ where // to 'T: Iterator' GenericArgs::AngleBracketed { ref mut bindings, .. } => { bindings.push(TypeBinding { - assoc: *assoc.clone(), + assoc: assoc.clone(), kind: TypeBindingKind::Equality { term: rhs }, }); } @@ -596,7 +598,7 @@ where } } - 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() }, @@ -613,7 +615,7 @@ where )); // 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 e56a715e8578..bd5dfa4947b4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -672,7 +672,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 971617a84003..5e34134597fa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -410,12 +410,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::new(self_type), + self_type, trait_, - } + })) } fn compute_should_show_cast(self_def_id: Option, trait_: &Path, self_type: &Type) -> bool { @@ -1182,7 +1182,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( .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 { @@ -1191,7 +1191,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( if trait_.def_id() != assoc_item.container_id(tcx) { return false; } - match **self_type { + match *self_type { Generic(ref s) if *s == kw::SelfUpper => {} _ => return false, } @@ -1324,15 +1324,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 = clean_ty(qself, cx); let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type); - Type::QPath { - assoc: Box::new(clean_path_segment( - p.segments.last().expect("segments were empty"), - cx, - )), + Type::QPath(Box::new(QPathData { + assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx), should_show_cast, - self_type: Box::new(self_type), + self_type, trait_, - } + })) } hir::QPath::TypeRelative(qself, segment) => { let ty = hir_ty_to_ty(cx.tcx, hir_ty); @@ -1347,12 +1344,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 = clean_ty(qself, cx); let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); - Type::QPath { - assoc: Box::new(clean_path_segment(segment, cx)), + Type::QPath(Box::new(QPathData { + assoc: clean_path_segment(segment, cx), should_show_cast, - self_type: Box::new(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 1a4786c9b066..7bbd2b19f2e0 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1556,13 +1556,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, @@ -1660,8 +1654,8 @@ 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(box QPathData { self_type, trait_, assoc, .. }) = self { + Some((self_type, trait_.def_id(), assoc.clone())) } else { None } @@ -1685,7 +1679,7 @@ impl Type { Slice(..) => PrimitiveType::Slice, Array(..) => PrimitiveType::Array, RawPointer(..) => PrimitiveType::RawPointer, - QPath { ref self_type, .. } => return self_type.inner_def_id(cache), + QPath(box QPathData { ref self_type, .. }) => return self_type.inner_def_id(cache), Generic(_) | Infer | ImplTrait(_) => return None, }; cache.and_then(|c| Primitive(t).def_id(c)) @@ -1699,6 +1693,15 @@ impl Type { } } +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub(crate) struct QPathData { + pub assoc: PathSegment, + pub self_type: Type, + /// FIXME: compute this field on demand. + pub should_show_cast: bool, + pub trait_: Path, +} + /// A primitive (aka, builtin) type. /// /// This represents things like `i32`, `str`, etc. @@ -2490,11 +2493,11 @@ mod size_asserts { // These are in alphabetical order, which is easy to maintain. static_assert_size!(Crate, 72); // frequently moved by-value static_assert_size!(DocFragment, 32); - static_assert_size!(GenericArg, 80); + static_assert_size!(GenericArg, 64); static_assert_size!(GenericArgs, 32); static_assert_size!(GenericParamDef, 56); static_assert_size!(Item, 56); static_assert_size!(ItemKind, 112); static_assert_size!(PathSegment, 40); - static_assert_size!(Type, 72); + static_assert_size!(Type, 56); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 3dee4d1acc81..b023792e95a5 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1079,7 +1079,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 5ed5299e09bc..1ac5186f9f6a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2623,8 +2623,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/json/conversions.rs b/src/librustdoc/json/conversions.rs index 1fedb0144d1d..6221591ca25e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -480,10 +480,10 @@ impl FromWithTcx for Type { mutable: mutability == ast::Mutability::Mut, type_: Box::new((*type_).into_tcx(tcx)), }, - QPath { assoc, self_type, trait_, .. } => Type::QualifiedPath { + QPath(box clean::QPathData { assoc, self_type, trait_, .. }) => 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_: trait_.into_tcx(tcx), }, }