Skip to content

rustdoc: make the Type enum smaller #97929

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

Closed
wants to merge 1 commit into from
Closed
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
19 changes: 12 additions & 7 deletions src/librustdoc/clean/auto_trait.rs
Original file line number Diff line number Diff line change
@@ -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<Item=u8>'
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),
}
2 changes: 1 addition & 1 deletion src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
@@ -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_, .. }),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

box syntax is being phased out? #97293

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, indeed.

If this shows max-rss improvements, I'll fix this line to use Box::new instead.

bounds,
..
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
31 changes: 17 additions & 14 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -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"),
}
28 changes: 16 additions & 12 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
@@ -1564,13 +1564,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,
@@ -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 {
7 changes: 6 additions & 1 deletion src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
@@ -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))?
4 changes: 2 additions & 2 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
@@ -2629,8 +2629,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());
}
_ => {}
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/search_index.rs
Original file line number Diff line number Diff line change
@@ -235,7 +235,7 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
| clean::Tuple(_)
| clean::Slice(_)
| clean::Array(_, _)
| clean::QPath { .. }
| clean::QPath(_)
| clean::Infer => None,
}
}
4 changes: 2 additions & 2 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
@@ -473,13 +473,13 @@ impl FromWithTcx<clean::Type> 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_),
}
}