1
Fork 0

rustdoc: factor Type::QPath out into its own box

This reduces the size of Type.
This commit is contained in:
Michael Howell 2022-08-16 12:48:04 -07:00
parent a39bdb1d6b
commit 2aa4aa70dd
7 changed files with 47 additions and 40 deletions

View file

@ -551,13 +551,15 @@ where
} }
WherePredicate::EqPredicate { lhs, rhs } => { WherePredicate::EqPredicate { lhs, rhs } => {
match lhs { 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 ty = &*self_type;
let mut new_trait = trait_.clone(); let mut new_trait = trait_.clone();
if self.is_fn_trait(trait_) && assoc.name == sym::Output { if self.is_fn_trait(trait_) && assoc.name == sym::Output {
ty_to_fn ty_to_fn
.entry(*ty.clone()) .entry(ty.clone())
.and_modify(|e| { .and_modify(|e| {
*e = (e.0.clone(), Some(rhs.ty().unwrap().clone())) *e = (e.0.clone(), Some(rhs.ty().unwrap().clone()))
}) })
@ -582,7 +584,7 @@ where
// to 'T: Iterator<Item=u8>' // to 'T: Iterator<Item=u8>'
GenericArgs::AngleBracketed { ref mut bindings, .. } => { GenericArgs::AngleBracketed { ref mut bindings, .. } => {
bindings.push(TypeBinding { bindings.push(TypeBinding {
assoc: *assoc.clone(), assoc: assoc.clone(),
kind: TypeBindingKind::Equality { term: rhs }, 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( bounds.insert(GenericBound::TraitBound(
PolyTrait { trait_: new_trait, generic_params: Vec::new() }, PolyTrait { trait_: new_trait, generic_params: Vec::new() },
@ -613,7 +615,7 @@ where
)); ));
// Avoid creating any new duplicate bounds later in the outer // Avoid creating any new duplicate bounds later in the outer
// loop // 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), _ => panic!("Unexpected LHS {:?} for {:?}", lhs, item_def_id),
} }

View file

@ -672,7 +672,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
g.where_predicates.retain(|pred| match pred { g.where_predicates.retain(|pred| match pred {
clean::WherePredicate::BoundPredicate { 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,
.. ..
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did), } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),

View file

@ -410,12 +410,12 @@ fn clean_projection<'tcx>(
self_type.def_id(&cx.cache) self_type.def_id(&cx.cache)
}; };
let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
Type::QPath { Type::QPath(Box::new(QPathData {
assoc: Box::new(projection_to_path_segment(ty, cx)), assoc: projection_to_path_segment(ty, cx),
should_show_cast, should_show_cast,
self_type: Box::new(self_type), self_type,
trait_, trait_,
} }))
} }
fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type: &Type) -> bool { fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type: &Type) -> bool {
@ -1182,7 +1182,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
.where_predicates .where_predicates
.drain_filter(|pred| match *pred { .drain_filter(|pred| match *pred {
WherePredicate::BoundPredicate { 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 { 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) { if trait_.def_id() != assoc_item.container_id(tcx) {
return false; return false;
} }
match **self_type { match *self_type {
Generic(ref s) if *s == kw::SelfUpper => {} Generic(ref s) if *s == kw::SelfUpper => {}
_ => return false, _ => 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_def_id = DefId::local(qself.hir_id.owner.local_def_index);
let self_type = clean_ty(qself, cx); let self_type = clean_ty(qself, cx);
let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type); let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type);
Type::QPath { Type::QPath(Box::new(QPathData {
assoc: Box::new(clean_path_segment( assoc: clean_path_segment(p.segments.last().expect("segments were empty"), cx),
p.segments.last().expect("segments were empty"),
cx,
)),
should_show_cast, should_show_cast,
self_type: Box::new(self_type), self_type,
trait_, trait_,
} }))
} }
hir::QPath::TypeRelative(qself, segment) => { hir::QPath::TypeRelative(qself, segment) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty); 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_def_id = res.opt_def_id();
let self_type = clean_ty(qself, cx); let self_type = clean_ty(qself, cx);
let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type); let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
Type::QPath { Type::QPath(Box::new(QPathData {
assoc: Box::new(clean_path_segment(segment, cx)), assoc: clean_path_segment(segment, cx),
should_show_cast, should_show_cast,
self_type: Box::new(self_type), self_type,
trait_, trait_,
} }))
} }
hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"), hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
} }

View file

@ -1556,13 +1556,7 @@ pub(crate) enum Type {
BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> }, BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> },
/// A qualified path to an associated item: `<Type as Trait>::Name` /// A qualified path to an associated item: `<Type as Trait>::Name`
QPath { QPath(Box<QPathData>),
assoc: Box<PathSegment>,
self_type: Box<Type>,
/// FIXME: compute this field on demand.
should_show_cast: bool,
trait_: Path,
},
/// A type that is inferred: `_` /// A type that is inferred: `_`
Infer, Infer,
@ -1660,8 +1654,8 @@ impl Type {
} }
pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> { pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
if let QPath { self_type, trait_, assoc, .. } = self { if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self {
Some((self_type, trait_.def_id(), *assoc.clone())) Some((self_type, trait_.def_id(), assoc.clone()))
} else { } else {
None None
} }
@ -1685,7 +1679,7 @@ impl Type {
Slice(..) => PrimitiveType::Slice, Slice(..) => PrimitiveType::Slice,
Array(..) => PrimitiveType::Array, Array(..) => PrimitiveType::Array,
RawPointer(..) => PrimitiveType::RawPointer, 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, Generic(_) | Infer | ImplTrait(_) => return None,
}; };
cache.and_then(|c| Primitive(t).def_id(c)) 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. /// A primitive (aka, builtin) type.
/// ///
/// This represents things like `i32`, `str`, etc. /// This represents things like `i32`, `str`, etc.
@ -2490,11 +2493,11 @@ mod size_asserts {
// These are in alphabetical order, which is easy to maintain. // These are in alphabetical order, which is easy to maintain.
static_assert_size!(Crate, 72); // frequently moved by-value static_assert_size!(Crate, 72); // frequently moved by-value
static_assert_size!(DocFragment, 32); static_assert_size!(DocFragment, 32);
static_assert_size!(GenericArg, 80); static_assert_size!(GenericArg, 64);
static_assert_size!(GenericArgs, 32); static_assert_size!(GenericArgs, 32);
static_assert_size!(GenericParamDef, 56); static_assert_size!(GenericParamDef, 56);
static_assert_size!(Item, 56); static_assert_size!(Item, 56);
static_assert_size!(ItemKind, 112); static_assert_size!(ItemKind, 112);
static_assert_size!(PathSegment, 40); static_assert_size!(PathSegment, 40);
static_assert_size!(Type, 72); static_assert_size!(Type, 56);
} }

View file

@ -1079,7 +1079,12 @@ fn fmt_type<'cx>(
write!(f, "impl {}", print_generic_bounds(bounds, 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 f.alternate() {
if should_show_cast { if should_show_cast {
write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))? write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?

View file

@ -2623,8 +2623,8 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
clean::Type::BorrowedRef { type_, .. } => { clean::Type::BorrowedRef { type_, .. } => {
work.push_back(*type_); work.push_back(*type_);
} }
clean::Type::QPath { self_type, trait_, .. } => { clean::Type::QPath(box clean::QPathData { self_type, trait_, .. }) => {
work.push_back(*self_type); work.push_back(self_type);
process_path(trait_.def_id()); process_path(trait_.def_id());
} }
_ => {} _ => {}

View file

@ -480,10 +480,10 @@ impl FromWithTcx<clean::Type> for Type {
mutable: mutability == ast::Mutability::Mut, mutable: mutability == ast::Mutability::Mut,
type_: Box::new((*type_).into_tcx(tcx)), 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(), name: assoc.name.to_string(),
args: Box::new(assoc.args.clone().into_tcx(tcx)), 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), trait_: trait_.into_tcx(tcx),
}, },
} }