Skip to content

rustdoc: strategic boxing to reduce the size of ItemKind and Type #100645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/librustdoc/clean/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
})
Expand All @@ -582,7 +584,7 @@ where
// to 'T: Iterator<Item=u8>'
GenericArgs::AngleBracketed { ref mut bindings, .. } => {
bindings.push(TypeBinding {
assoc: *assoc.clone(),
assoc: assoc.clone(),
kind: TypeBindingKind::Equality { term: rhs },
});
}
Expand All @@ -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() },
Expand All @@ -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),
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub(crate) fn try_inline(
Res::Def(DefKind::Trait, did) => {
record_extern_fqn(cx, did, ItemType::Trait);
build_impls(cx, Some(parent_module), did, attrs, &mut ret);
clean::TraitItem(build_external_trait(cx, did))
clean::TraitItem(Box::new(build_external_trait(cx, did)))
}
Res::Def(DefKind::Fn, did) => {
record_extern_fqn(cx, did, ItemType::Function);
Expand Down Expand Up @@ -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),
Expand Down
35 changes: 16 additions & 19 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DefId>, trait_: &Path, self_type: &Type) -> bool {
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
}
Expand Down Expand Up @@ -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);
Expand All @@ -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"),
}
Expand Down Expand Up @@ -1954,12 +1951,12 @@ fn clean_maybe_renamed_item<'tcx>(
.map(|ti| clean_trait_item(cx.tcx.hir().trait_item(ti.id), cx))
.collect();

TraitItem(Trait {
TraitItem(Box::new(Trait {
def_id,
items,
generics: clean_generics(generics, cx),
bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
})
}))
}
ItemKind::ExternCrate(orig_name) => {
return clean_extern_crate(item, name, orig_name, cx);
Expand Down
31 changes: 17 additions & 14 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ pub(crate) enum ItemKind {
OpaqueTyItem(OpaqueTy),
StaticItem(Static),
ConstantItem(Constant),
TraitItem(Trait),
TraitItem(Box<Trait>),
TraitAliasItem(TraitAlias),
ImplItem(Box<Impl>),
/// A required method in a trait declaration meaning it's only a function signature.
Expand Down Expand Up @@ -1556,13 +1556,7 @@ pub(crate) enum Type {
BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> },

/// A qualified path to an associated item: `<Type as Trait>::Name`
QPath {
assoc: Box<PathSegment>,
self_type: Box<Type>,
/// FIXME: compute this field on demand.
should_show_cast: bool,
trait_: Path,
},
QPath(Box<QPathData>),

/// A type that is inferred: `_`
Infer,
Expand Down Expand Up @@ -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
}
Expand All @@ -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))
Expand All @@ -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.
Expand Down Expand Up @@ -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!(ItemKind, 96);
static_assert_size!(PathSegment, 40);
static_assert_size!(Type, 72);
static_assert_size!(Type, 56);
}
2 changes: 1 addition & 1 deletion src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
if let clean::TraitItem(ref t) = *item.kind {
self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| {
clean::TraitWithExtraInfo {
trait_: t.clone(),
trait_: *t.clone(),
is_notable: item.attrs.has_doc_flag(sym::notable_trait),
}
});
Expand Down
7 changes: 6 additions & 1 deletion src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))?
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2623,8 +2623,8 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
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());
}
_ => {}
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)),
FunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)),
ForeignFunctionItem(f) => ItemEnum::Function(from_function(f, header.unwrap(), tcx)),
TraitItem(t) => ItemEnum::Trait(t.into_tcx(tcx)),
TraitItem(t) => ItemEnum::Trait((*t).into_tcx(tcx)),
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, header.unwrap(), tcx)),
TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, header.unwrap(), tcx)),
Expand Down Expand Up @@ -480,10 +480,10 @@ impl FromWithTcx<clean::Type> 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),
},
}
Expand Down