From 4054c0f3e6cecddadcc2aa19d7c97efed5611a4b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 12 Apr 2022 15:06:31 +0200 Subject: [PATCH] Reduce clean::Type size by replacing a DefId (only used to check for display) with a boolean --- src/librustdoc/clean/mod.rs | 33 ++++++++++++++++++++++++++------- src/librustdoc/clean/types.rs | 10 ++++------ src/librustdoc/html/format.rs | 6 +----- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6e18f381c59..e133372bc23 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -384,15 +384,24 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type { let lifted = self.lift_to_tcx(cx.tcx).unwrap(); let trait_ = lifted.trait_ref(cx.tcx).clean(cx); let self_type = self.self_ty().clean(cx); + let self_def_id = 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(*self, cx)), - self_def_id: self_type.def_id(&cx.cache), + should_show_cast, self_type: box self_type, trait_, } } } +fn compute_should_show_cast(self_def_id: Option, trait_: &Path, self_type: &Type) -> bool { + !trait_.segments.is_empty() + && self_def_id + .zip(Some(trait_.def_id())) + .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_) +} + fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>) -> PathSegment { let item = cx.tcx.associated_item(ty.item_def_id); let generics = cx.tcx.generics_of(ty.item_def_id); @@ -421,8 +430,12 @@ fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { // the cleaning process of the type itself. To resolve this and have the // `self_def_id` set, we override it here. // See https://github.com/rust-lang/rust/issues/85454 - if let QPath { ref mut self_def_id, .. } = default { - *self_def_id = Some(cx.tcx.parent(self.def_id)); + if let QPath { ref mut should_show_cast, ref trait_, ref self_type, .. } = + default + { + let self_def_id = cx.tcx.parent(self.def_id); + *should_show_cast = + compute_should_show_cast(self_def_id, trait_, self_type); } Some(default) @@ -1309,10 +1322,13 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { segments: trait_segments.iter().map(|x| x.clean(cx)).collect(), }; register_res(cx, trait_.res); + 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)), - self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)), - self_type: box qself.clean(cx), + should_show_cast, + self_type: box self_type, trait_, } } @@ -1326,10 +1342,13 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { }; let trait_ = hir::Path { span, res, segments: &[] }.clean(cx); register_res(cx, trait_.res); + 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)), - self_def_id: res.opt_def_id(), - self_type: box qself.clean(cx), + should_show_cast, + self_type: box self_type, trait_, } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 456d860f125..0bbfc6d6af0 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1560,10 +1560,8 @@ impl FnRetTy { QPath { assoc: Box, self_type: Box, - /// FIXME: This is a hack that should be removed; see [this discussion][1]. - /// - /// [1]: https://github.com/rust-lang/rust/pull/85479#discussion_r635729093 - self_def_id: Option, + /// FIXME: compute this field on demand. + should_show_cast: bool, trait_: Path, }, @@ -1576,7 +1574,7 @@ impl FnRetTy { // `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, 80); +rustc_data_structures::static_assert_size!(Type, 72); impl Type { /// When comparing types for equality, it can help to ignore `&` wrapping. @@ -2180,7 +2178,7 @@ impl Path { // `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, 88); +rustc_data_structures::static_assert_size!(GenericArg, 80); #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate enum GenericArgs { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 528eb6410cb..abfeb96f6bf 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -982,11 +982,7 @@ fn fmt_type<'cx>( write!(f, "impl {}", print_generic_bounds(bounds, cx)) } } - clean::QPath { ref assoc, ref self_type, ref trait_, ref self_def_id } => { - let should_show_cast = !trait_.segments.is_empty() - && self_def_id - .zip(Some(trait_.def_id())) - .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_); + clean::QPath { 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))? -- 2.44.0