Auto merge of #99577 - est31:remove_box_librustdoc, r=jsha

Remove remaining uses of box syntax from librustdoc

Remove the remaining uses of box syntax from librustdoc. Followup of #99066 where these changes were split out because they were responsible for a small but noticeable regression. This PR avoids the regression by boxing some large variants of `ItemKind` to reduce the enum's size by half from 224 bytes to 112 bytes (on x86-64). This should also help with reducing memory usage.
This commit is contained in:
bors 2022-07-29 18:44:53 +00:00
commit 3924dac7bb
13 changed files with 67 additions and 64 deletions

View file

@ -117,7 +117,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
attrs: Default::default(),
visibility: Inherited,
item_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
kind: Box::new(ImplItem(Impl {
kind: Box::new(ImplItem(Box::new(Impl {
unsafety: hir::Unsafety::Normal,
generics: new_generics,
trait_: Some(trait_ref.clean(self.cx)),
@ -125,7 +125,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
items: Vec::new(),
polarity,
kind: ImplKind::Auto,
})),
}))),
cfg: None,
})
}

View file

@ -106,7 +106,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
attrs: Default::default(),
visibility: Inherited,
item_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
kind: Box::new(ImplItem(Impl {
kind: Box::new(ImplItem(Box::new(Impl {
unsafety: hir::Unsafety::Normal,
generics: clean_ty_generics(
cx,
@ -124,7 +124,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.collect::<Vec<_>>(),
polarity: ty::ImplPolarity::Positive,
kind: ImplKind::Blanket(Box::new(clean_middle_ty(trait_ref.0.self_ty(), cx, None))),
})),
}))),
cfg: None,
});
}

View file

@ -218,7 +218,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
}
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> clean::Function {
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
let sig = cx.tcx.fn_sig(did);
let predicates = cx.tcx.predicates_of(did);
@ -228,7 +228,7 @@ fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> clean
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
(generics, decl)
});
clean::Function { decl, generics }
Box::new(clean::Function { decl, generics })
}
fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
@ -260,15 +260,15 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
clean::Union { generics, fields }
}
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef> {
let predicates = cx.tcx.explicit_predicates_of(did);
let type_ = clean_middle_ty(cx.tcx.type_of(did), cx, Some(did));
clean::Typedef {
Box::new(clean::Typedef {
type_,
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
item_type: None,
}
})
}
/// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
@ -493,7 +493,7 @@ pub(crate) fn build_impl(
ret.push(clean::Item::from_def_id_and_attrs_and_parts(
did,
None,
clean::ImplItem(clean::Impl {
clean::ImplItem(Box::new(clean::Impl {
unsafety: hir::Unsafety::Normal,
generics,
trait_,
@ -505,7 +505,7 @@ pub(crate) fn build_impl(
} else {
ImplKind::Normal
},
}),
})),
Box::new(merged_attrs),
cx,
cfg,
@ -538,7 +538,7 @@ fn build_module(
attrs: Box::new(clean::Attributes::default()),
item_id: ItemId::Primitive(prim_ty, did.krate),
visibility: clean::Public,
kind: box clean::ImportItem(clean::Import::new_simple(
kind: Box::new(clean::ImportItem(clean::Import::new_simple(
item.ident.name,
clean::ImportSource {
path: clean::Path {
@ -554,7 +554,7 @@ fn build_module(
did: None,
},
true,
)),
))),
cfg: None,
});
} else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {

View file

@ -908,7 +908,7 @@ fn clean_function<'tcx>(
sig: &hir::FnSig<'tcx>,
generics: &hir::Generics<'tcx>,
body_id: hir::BodyId,
) -> Function {
) -> Box<Function> {
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
let generics = generics.clean(cx);
@ -916,7 +916,7 @@ fn clean_function<'tcx>(
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
(generics, decl)
});
Function { decl, generics }
Box::new(Function { decl, generics })
}
fn clean_args_from_types_and_names<'tcx>(
@ -1061,18 +1061,18 @@ impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> {
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
(generics, decl)
});
TyMethodItem(Function { decl, generics })
TyMethodItem(Box::new(Function { decl, generics }))
}
hir::TraitItemKind::Type(bounds, Some(default)) => {
let generics = enter_impl_trait(cx, |cx| self.generics.clean(cx));
let bounds = bounds.iter().filter_map(|x| x.clean(cx)).collect();
let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, default), cx, None);
AssocTypeItem(
Typedef {
Box::new(Typedef {
type_: clean_ty(default, cx),
generics,
item_type: Some(item_type),
},
}),
bounds,
)
}
@ -1109,7 +1109,7 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> {
let generics = self.generics.clean(cx);
let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
AssocTypeItem(
Typedef { type_, generics, item_type: Some(item_type) },
Box::new(Typedef { type_, generics, item_type: Some(item_type) }),
Vec::new(),
)
}
@ -1186,9 +1186,9 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
ty::ImplContainer(_) => Some(self.defaultness),
ty::TraitContainer(_) => None,
};
MethodItem(Function { generics, decl }, defaultness)
MethodItem(Box::new(Function { generics, decl }), defaultness)
} else {
TyMethodItem(Function { generics, decl })
TyMethodItem(Box::new(Function { generics, decl }))
}
}
ty::AssocKind::Type => {
@ -1282,7 +1282,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
if self.defaultness.has_value() {
AssocTypeItem(
Typedef {
Box::new(Typedef {
type_: clean_middle_ty(
tcx.type_of(self.def_id),
cx,
@ -1291,7 +1291,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
generics,
// FIXME: should we obtain the Type from HIR and pass it on here?
item_type: None,
},
}),
bounds,
)
} else {
@ -1300,11 +1300,11 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
} else {
// FIXME: when could this happen? Associated items in inherent impls?
AssocTypeItem(
Typedef {
Box::new(Typedef {
type_: clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)),
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
item_type: None,
},
}),
Vec::new(),
)
}
@ -1949,11 +1949,11 @@ fn clean_maybe_renamed_item<'tcx>(
ItemKind::TyAlias(hir_ty, generics) => {
let rustdoc_ty = clean_ty(hir_ty, cx);
let ty = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
TypedefItem(Typedef {
TypedefItem(Box::new(Typedef {
type_: rustdoc_ty,
generics: generics.clean(cx),
item_type: Some(ty),
})
}))
}
ItemKind::Enum(ref def, generics) => EnumItem(Enum {
variants: def.variants.iter().map(|v| v.clean(cx)).collect(),
@ -2041,7 +2041,7 @@ fn clean_impl<'tcx>(
_ => None,
});
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Impl {
let kind = ImplItem(Box::new(Impl {
unsafety: impl_.unsafety,
generics: impl_.generics.clean(cx),
trait_,
@ -2053,7 +2053,7 @@ fn clean_impl<'tcx>(
} else {
ImplKind::Normal
},
});
}));
Item::from_hir_id_and_parts(hir_id, None, kind, cx)
};
if let Some(type_alias) = type_alias {
@ -2108,7 +2108,7 @@ fn clean_extern_crate<'tcx>(
attrs: Box::new(attrs.clean(cx)),
item_id: crate_def_id.into(),
visibility: clean_visibility(ty_vis),
kind: box ExternCrateItem { src: orig_name },
kind: Box::new(ExternCrateItem { src: orig_name }),
cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
}]
}
@ -2243,7 +2243,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
let decl = clean_fn_decl_with_args(cx, decl, args);
(generics, decl)
});
ForeignFunctionItem(Function { decl, generics })
ForeignFunctionItem(Box::new(Function { decl, generics }))
}
hir::ForeignItemKind::Static(ty, mutability) => {
ForeignStaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: None })

View file

@ -430,8 +430,8 @@ impl Item {
};
match kind {
ItemKind::ModuleItem(Module { span, .. }) => *span,
ItemKind::ImplItem(Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
ItemKind::ImplItem(Impl { kind: ImplKind::Blanket(_), .. }) => {
ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
ItemKind::ImplItem(box Impl { kind: ImplKind::Blanket(_), .. }) => {
if let ItemId::Blanket { impl_id, .. } = self.item_id {
rustc_span(impl_id, tcx)
} else {
@ -502,7 +502,7 @@ impl Item {
clean_visibility(cx.tcx.visibility(def_id))
};
Item { item_id: def_id.into(), kind: box kind, name, attrs, visibility, cfg }
Item { item_id: def_id.into(), kind: Box::new(kind), name, attrs, visibility, cfg }
}
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@ -730,25 +730,25 @@ pub(crate) enum ItemKind {
StructItem(Struct),
UnionItem(Union),
EnumItem(Enum),
FunctionItem(Function),
FunctionItem(Box<Function>),
ModuleItem(Module),
TypedefItem(Typedef),
TypedefItem(Box<Typedef>),
OpaqueTyItem(OpaqueTy),
StaticItem(Static),
ConstantItem(Constant),
TraitItem(Trait),
TraitAliasItem(TraitAlias),
ImplItem(Impl),
ImplItem(Box<Impl>),
/// A required method in a trait declaration meaning it's only a function signature.
TyMethodItem(Function),
TyMethodItem(Box<Function>),
/// A method in a trait impl or a provided method in a trait declaration.
///
/// Compared to [TyMethodItem], it also contains a method body.
MethodItem(Function, Option<hir::Defaultness>),
MethodItem(Box<Function>, Option<hir::Defaultness>),
StructFieldItem(Type),
VariantItem(Variant),
/// `fn`s from an extern block
ForeignFunctionItem(Function),
ForeignFunctionItem(Box<Function>),
/// `static`s from an extern block
ForeignStaticItem(Static),
/// `type`s from an extern block
@ -765,12 +765,16 @@ pub(crate) enum ItemKind {
/// The bounds may be non-empty if there is a `where` clause.
TyAssocTypeItem(Box<Generics>, Vec<GenericBound>),
/// An associated type in a trait impl or a provided one in a trait declaration.
AssocTypeItem(Typedef, Vec<GenericBound>),
AssocTypeItem(Box<Typedef>, Vec<GenericBound>),
/// An item that has been stripped by a rustdoc pass
StrippedItem(Box<ItemKind>),
KeywordItem,
}
// `ItemKind` is an enum and large variants can bloat up memory usage even for smaller ones
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(ItemKind, 112);
impl ItemKind {
/// Some items contain others such as structs (for their fields) and Enums
/// (for their variants). This method returns those contained items.

View file

@ -740,7 +740,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
let emitter = EmitterWriter::new(
box io::sink(),
Box::new(io::sink()),
None,
None,
fallback_bundle,
@ -751,7 +751,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
false,
);
let handler = Handler::with_emitter(false, None, box emitter);
let handler = Handler::with_emitter(false, None, Box::new(emitter));
let sess = ParseSess::with_span_handler(handler, sm);
let mut parser =
match maybe_new_parser_from_source_str(&sess, filename, source.to_owned()) {

View file

@ -2,7 +2,7 @@ use crate::clean::*;
pub(crate) fn strip_item(mut item: Item) -> Item {
if !matches!(*item.kind, StrippedItem(..)) {
item.kind = box StrippedItem(item.kind);
item.kind = Box::new(StrippedItem(item.kind));
}
item
}
@ -75,10 +75,10 @@ pub(crate) trait DocFolder: Sized {
/// don't override!
fn fold_item_recur(&mut self, mut item: Item) -> Item {
item.kind = box match *item.kind {
StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
item.kind = Box::new(match *item.kind {
StrippedItem(box i) => StrippedItem(Box::new(self.fold_inner_recur(i))),
_ => self.fold_inner_recur(*item.kind),
};
});
item
}

View file

@ -536,7 +536,7 @@ enum ParentStackItem {
impl ParentStackItem {
fn new(item: &clean::Item) -> Self {
match &*item.kind {
clean::ItemKind::ImplItem(clean::Impl { for_, trait_, generics, kind, .. }) => {
clean::ItemKind::ImplItem(box clean::Impl { for_, trait_, generics, kind, .. }) => {
ParentStackItem::Impl {
for_: for_.clone(),
trait_: trait_.clone(),

View file

@ -1160,7 +1160,7 @@ fn render_deref_methods(
.items
.iter()
.find_map(|item| match *item.kind {
clean::AssocTypeItem(ref t, _) => Some(match *t {
clean::AssocTypeItem(box ref t, _) => Some(match *t {
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
_ => (&t.type_, &t.type_),
}),
@ -2054,7 +2054,7 @@ fn sidebar_deref_methods(
debug!("found Deref: {:?}", impl_);
if let Some((target, real_target)) =
impl_.inner_impl().items.iter().find_map(|item| match *item.kind {
clean::AssocTypeItem(ref t, _) => Some(match *t {
clean::AssocTypeItem(box ref t, _) => Some(match *t {
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
_ => (&t.type_, &t.type_),
}),

View file

@ -568,10 +568,10 @@ impl FromWithTcx<clean::Trait> for Trait {
}
}
impl FromWithTcx<clean::Impl> for Impl {
fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
impl FromWithTcx<Box<clean::Impl>> for Impl {
fn from_tcx(impl_: Box<clean::Impl>, tcx: TyCtxt<'_>) -> Self {
let provided_trait_methods = impl_.provided_trait_methods(tcx);
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = *impl_;
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
// FIXME: use something like ImplKind in JSON?
@ -602,11 +602,11 @@ impl FromWithTcx<clean::Impl> for Impl {
}
pub(crate) fn from_function(
function: clean::Function,
function: Box<clean::Function>,
header: rustc_hir::FnHeader,
tcx: TyCtxt<'_>,
) -> Function {
let clean::Function { decl, generics } = function;
let clean::Function { decl, generics } = *function;
Function {
decl: decl.into_tcx(tcx),
generics: generics.into_tcx(tcx),
@ -615,12 +615,12 @@ pub(crate) fn from_function(
}
pub(crate) fn from_function_method(
function: clean::Function,
function: Box<clean::Function>,
has_body: bool,
header: rustc_hir::FnHeader,
tcx: TyCtxt<'_>,
) -> Method {
let clean::Function { decl, generics } = function;
let clean::Function { decl, generics } = *function;
Method {
decl: decl.into_tcx(tcx),
generics: generics.into_tcx(tcx),
@ -721,9 +721,9 @@ pub(crate) fn from_macro_kind(kind: rustc_span::hygiene::MacroKind) -> MacroKind
}
}
impl FromWithTcx<clean::Typedef> for Typedef {
fn from_tcx(typedef: clean::Typedef, tcx: TyCtxt<'_>) -> Self {
let clean::Typedef { type_, generics, item_type: _ } = typedef;
impl FromWithTcx<Box<clean::Typedef>> for Typedef {
fn from_tcx(typedef: Box<clean::Typedef>, tcx: TyCtxt<'_>) -> Self {
let clean::Typedef { type_, generics, item_type: _ } = *typedef;
Typedef { type_: type_.into_tcx(tcx), generics: generics.into_tcx(tcx) }
}
}

View file

@ -7,7 +7,6 @@
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(box_syntax)]
#![feature(drain_filter)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(let_else)]

View file

@ -71,7 +71,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
| clean::PrimitiveItem(_)
| clean::KeywordItem
// check for trait impl
| clean::ImplItem(clean::Impl { trait_: Some(_), .. })
| clean::ImplItem(box clean::Impl { trait_: Some(_), .. })
)
{
return false;

View file

@ -146,7 +146,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
for it in new_items_external.iter().chain(new_items_local.iter()) {
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
if trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait()
&& cleaner.keep_impl(for_, true)
{
@ -187,7 +187,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
// Filter out external items that are not needed
new_items_external.retain(|it| {
if let ImplItem(Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind {
if let ImplItem(box Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind {
cleaner.keep_impl(
for_,
trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait(),