Skip to content

Commit 3924dac

Browse files
committed
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.
2 parents 5dda74a + fabb4b0 commit 3924dac

File tree

13 files changed

+67
-64
lines changed

13 files changed

+67
-64
lines changed

src/librustdoc/clean/auto_trait.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,15 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
117117
attrs: Default::default(),
118118
visibility: Inherited,
119119
item_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
120-
kind: Box::new(ImplItem(Impl {
120+
kind: Box::new(ImplItem(Box::new(Impl {
121121
unsafety: hir::Unsafety::Normal,
122122
generics: new_generics,
123123
trait_: Some(trait_ref.clean(self.cx)),
124124
for_: clean_middle_ty(ty, self.cx, None),
125125
items: Vec::new(),
126126
polarity,
127127
kind: ImplKind::Auto,
128-
})),
128+
}))),
129129
cfg: None,
130130
})
131131
}

src/librustdoc/clean/blanket_impl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
106106
attrs: Default::default(),
107107
visibility: Inherited,
108108
item_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
109-
kind: Box::new(ImplItem(Impl {
109+
kind: Box::new(ImplItem(Box::new(Impl {
110110
unsafety: hir::Unsafety::Normal,
111111
generics: clean_ty_generics(
112112
cx,
@@ -124,7 +124,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
124124
.collect::<Vec<_>>(),
125125
polarity: ty::ImplPolarity::Positive,
126126
kind: ImplKind::Blanket(Box::new(clean_middle_ty(trait_ref.0.self_ty(), cx, None))),
127-
})),
127+
}))),
128128
cfg: None,
129129
});
130130
}

src/librustdoc/clean/inline.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
218218
clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
219219
}
220220

221-
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> clean::Function {
221+
fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> {
222222
let sig = cx.tcx.fn_sig(did);
223223

224224
let predicates = cx.tcx.predicates_of(did);
@@ -228,7 +228,7 @@ fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> clean
228228
let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
229229
(generics, decl)
230230
});
231-
clean::Function { decl, generics }
231+
Box::new(clean::Function { decl, generics })
232232
}
233233

234234
fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
@@ -260,15 +260,15 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
260260
clean::Union { generics, fields }
261261
}
262262

263-
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
263+
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef> {
264264
let predicates = cx.tcx.explicit_predicates_of(did);
265265
let type_ = clean_middle_ty(cx.tcx.type_of(did), cx, Some(did));
266266

267-
clean::Typedef {
267+
Box::new(clean::Typedef {
268268
type_,
269269
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
270270
item_type: None,
271-
}
271+
})
272272
}
273273

274274
/// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
@@ -493,7 +493,7 @@ pub(crate) fn build_impl(
493493
ret.push(clean::Item::from_def_id_and_attrs_and_parts(
494494
did,
495495
None,
496-
clean::ImplItem(clean::Impl {
496+
clean::ImplItem(Box::new(clean::Impl {
497497
unsafety: hir::Unsafety::Normal,
498498
generics,
499499
trait_,
@@ -505,7 +505,7 @@ pub(crate) fn build_impl(
505505
} else {
506506
ImplKind::Normal
507507
},
508-
}),
508+
})),
509509
Box::new(merged_attrs),
510510
cx,
511511
cfg,
@@ -538,7 +538,7 @@ fn build_module(
538538
attrs: Box::new(clean::Attributes::default()),
539539
item_id: ItemId::Primitive(prim_ty, did.krate),
540540
visibility: clean::Public,
541-
kind: box clean::ImportItem(clean::Import::new_simple(
541+
kind: Box::new(clean::ImportItem(clean::Import::new_simple(
542542
item.ident.name,
543543
clean::ImportSource {
544544
path: clean::Path {
@@ -554,7 +554,7 @@ fn build_module(
554554
did: None,
555555
},
556556
true,
557-
)),
557+
))),
558558
cfg: None,
559559
});
560560
} else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {

src/librustdoc/clean/mod.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -908,15 +908,15 @@ fn clean_function<'tcx>(
908908
sig: &hir::FnSig<'tcx>,
909909
generics: &hir::Generics<'tcx>,
910910
body_id: hir::BodyId,
911-
) -> Function {
911+
) -> Box<Function> {
912912
let (generics, decl) = enter_impl_trait(cx, |cx| {
913913
// NOTE: generics must be cleaned before args
914914
let generics = generics.clean(cx);
915915
let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id);
916916
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
917917
(generics, decl)
918918
});
919-
Function { decl, generics }
919+
Box::new(Function { decl, generics })
920920
}
921921

922922
fn clean_args_from_types_and_names<'tcx>(
@@ -1061,18 +1061,18 @@ impl<'tcx> Clean<'tcx, Item> for hir::TraitItem<'tcx> {
10611061
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
10621062
(generics, decl)
10631063
});
1064-
TyMethodItem(Function { decl, generics })
1064+
TyMethodItem(Box::new(Function { decl, generics }))
10651065
}
10661066
hir::TraitItemKind::Type(bounds, Some(default)) => {
10671067
let generics = enter_impl_trait(cx, |cx| self.generics.clean(cx));
10681068
let bounds = bounds.iter().filter_map(|x| x.clean(cx)).collect();
10691069
let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, default), cx, None);
10701070
AssocTypeItem(
1071-
Typedef {
1071+
Box::new(Typedef {
10721072
type_: clean_ty(default, cx),
10731073
generics,
10741074
item_type: Some(item_type),
1075-
},
1075+
}),
10761076
bounds,
10771077
)
10781078
}
@@ -1109,7 +1109,7 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> {
11091109
let generics = self.generics.clean(cx);
11101110
let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
11111111
AssocTypeItem(
1112-
Typedef { type_, generics, item_type: Some(item_type) },
1112+
Box::new(Typedef { type_, generics, item_type: Some(item_type) }),
11131113
Vec::new(),
11141114
)
11151115
}
@@ -1186,9 +1186,9 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
11861186
ty::ImplContainer(_) => Some(self.defaultness),
11871187
ty::TraitContainer(_) => None,
11881188
};
1189-
MethodItem(Function { generics, decl }, defaultness)
1189+
MethodItem(Box::new(Function { generics, decl }), defaultness)
11901190
} else {
1191-
TyMethodItem(Function { generics, decl })
1191+
TyMethodItem(Box::new(Function { generics, decl }))
11921192
}
11931193
}
11941194
ty::AssocKind::Type => {
@@ -1282,7 +1282,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
12821282

12831283
if self.defaultness.has_value() {
12841284
AssocTypeItem(
1285-
Typedef {
1285+
Box::new(Typedef {
12861286
type_: clean_middle_ty(
12871287
tcx.type_of(self.def_id),
12881288
cx,
@@ -1291,7 +1291,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
12911291
generics,
12921292
// FIXME: should we obtain the Type from HIR and pass it on here?
12931293
item_type: None,
1294-
},
1294+
}),
12951295
bounds,
12961296
)
12971297
} else {
@@ -1300,11 +1300,11 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
13001300
} else {
13011301
// FIXME: when could this happen? Associated items in inherent impls?
13021302
AssocTypeItem(
1303-
Typedef {
1303+
Box::new(Typedef {
13041304
type_: clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)),
13051305
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
13061306
item_type: None,
1307-
},
1307+
}),
13081308
Vec::new(),
13091309
)
13101310
}
@@ -1949,11 +1949,11 @@ fn clean_maybe_renamed_item<'tcx>(
19491949
ItemKind::TyAlias(hir_ty, generics) => {
19501950
let rustdoc_ty = clean_ty(hir_ty, cx);
19511951
let ty = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
1952-
TypedefItem(Typedef {
1952+
TypedefItem(Box::new(Typedef {
19531953
type_: rustdoc_ty,
19541954
generics: generics.clean(cx),
19551955
item_type: Some(ty),
1956-
})
1956+
}))
19571957
}
19581958
ItemKind::Enum(ref def, generics) => EnumItem(Enum {
19591959
variants: def.variants.iter().map(|v| v.clean(cx)).collect(),
@@ -2041,7 +2041,7 @@ fn clean_impl<'tcx>(
20412041
_ => None,
20422042
});
20432043
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
2044-
let kind = ImplItem(Impl {
2044+
let kind = ImplItem(Box::new(Impl {
20452045
unsafety: impl_.unsafety,
20462046
generics: impl_.generics.clean(cx),
20472047
trait_,
@@ -2053,7 +2053,7 @@ fn clean_impl<'tcx>(
20532053
} else {
20542054
ImplKind::Normal
20552055
},
2056-
});
2056+
}));
20572057
Item::from_hir_id_and_parts(hir_id, None, kind, cx)
20582058
};
20592059
if let Some(type_alias) = type_alias {
@@ -2108,7 +2108,7 @@ fn clean_extern_crate<'tcx>(
21082108
attrs: Box::new(attrs.clean(cx)),
21092109
item_id: crate_def_id.into(),
21102110
visibility: clean_visibility(ty_vis),
2111-
kind: box ExternCrateItem { src: orig_name },
2111+
kind: Box::new(ExternCrateItem { src: orig_name }),
21122112
cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
21132113
}]
21142114
}
@@ -2243,7 +2243,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
22432243
let decl = clean_fn_decl_with_args(cx, decl, args);
22442244
(generics, decl)
22452245
});
2246-
ForeignFunctionItem(Function { decl, generics })
2246+
ForeignFunctionItem(Box::new(Function { decl, generics }))
22472247
}
22482248
hir::ForeignItemKind::Static(ty, mutability) => {
22492249
ForeignStaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: None })

src/librustdoc/clean/types.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ impl Item {
430430
};
431431
match kind {
432432
ItemKind::ModuleItem(Module { span, .. }) => *span,
433-
ItemKind::ImplItem(Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
434-
ItemKind::ImplItem(Impl { kind: ImplKind::Blanket(_), .. }) => {
433+
ItemKind::ImplItem(box Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
434+
ItemKind::ImplItem(box Impl { kind: ImplKind::Blanket(_), .. }) => {
435435
if let ItemId::Blanket { impl_id, .. } = self.item_id {
436436
rustc_span(impl_id, tcx)
437437
} else {
@@ -502,7 +502,7 @@ impl Item {
502502
clean_visibility(cx.tcx.visibility(def_id))
503503
};
504504

505-
Item { item_id: def_id.into(), kind: box kind, name, attrs, visibility, cfg }
505+
Item { item_id: def_id.into(), kind: Box::new(kind), name, attrs, visibility, cfg }
506506
}
507507

508508
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@@ -730,25 +730,25 @@ pub(crate) enum ItemKind {
730730
StructItem(Struct),
731731
UnionItem(Union),
732732
EnumItem(Enum),
733-
FunctionItem(Function),
733+
FunctionItem(Box<Function>),
734734
ModuleItem(Module),
735-
TypedefItem(Typedef),
735+
TypedefItem(Box<Typedef>),
736736
OpaqueTyItem(OpaqueTy),
737737
StaticItem(Static),
738738
ConstantItem(Constant),
739739
TraitItem(Trait),
740740
TraitAliasItem(TraitAlias),
741-
ImplItem(Impl),
741+
ImplItem(Box<Impl>),
742742
/// A required method in a trait declaration meaning it's only a function signature.
743-
TyMethodItem(Function),
743+
TyMethodItem(Box<Function>),
744744
/// A method in a trait impl or a provided method in a trait declaration.
745745
///
746746
/// Compared to [TyMethodItem], it also contains a method body.
747-
MethodItem(Function, Option<hir::Defaultness>),
747+
MethodItem(Box<Function>, Option<hir::Defaultness>),
748748
StructFieldItem(Type),
749749
VariantItem(Variant),
750750
/// `fn`s from an extern block
751-
ForeignFunctionItem(Function),
751+
ForeignFunctionItem(Box<Function>),
752752
/// `static`s from an extern block
753753
ForeignStaticItem(Static),
754754
/// `type`s from an extern block
@@ -765,12 +765,16 @@ pub(crate) enum ItemKind {
765765
/// The bounds may be non-empty if there is a `where` clause.
766766
TyAssocTypeItem(Box<Generics>, Vec<GenericBound>),
767767
/// An associated type in a trait impl or a provided one in a trait declaration.
768-
AssocTypeItem(Typedef, Vec<GenericBound>),
768+
AssocTypeItem(Box<Typedef>, Vec<GenericBound>),
769769
/// An item that has been stripped by a rustdoc pass
770770
StrippedItem(Box<ItemKind>),
771771
KeywordItem,
772772
}
773773

774+
// `ItemKind` is an enum and large variants can bloat up memory usage even for smaller ones
775+
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
776+
rustc_data_structures::static_assert_size!(ItemKind, 112);
777+
774778
impl ItemKind {
775779
/// Some items contain others such as structs (for their fields) and Enums
776780
/// (for their variants). This method returns those contained items.

src/librustdoc/doctest.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
740740
rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
741741

742742
let emitter = EmitterWriter::new(
743-
box io::sink(),
743+
Box::new(io::sink()),
744744
None,
745745
None,
746746
fallback_bundle,
@@ -751,7 +751,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
751751
false,
752752
);
753753

754-
let handler = Handler::with_emitter(false, None, box emitter);
754+
let handler = Handler::with_emitter(false, None, Box::new(emitter));
755755
let sess = ParseSess::with_span_handler(handler, sm);
756756
let mut parser =
757757
match maybe_new_parser_from_source_str(&sess, filename, source.to_owned()) {

src/librustdoc/fold.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::clean::*;
22

33
pub(crate) fn strip_item(mut item: Item) -> Item {
44
if !matches!(*item.kind, StrippedItem(..)) {
5-
item.kind = box StrippedItem(item.kind);
5+
item.kind = Box::new(StrippedItem(item.kind));
66
}
77
item
88
}
@@ -75,10 +75,10 @@ pub(crate) trait DocFolder: Sized {
7575

7676
/// don't override!
7777
fn fold_item_recur(&mut self, mut item: Item) -> Item {
78-
item.kind = box match *item.kind {
79-
StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
78+
item.kind = Box::new(match *item.kind {
79+
StrippedItem(box i) => StrippedItem(Box::new(self.fold_inner_recur(i))),
8080
_ => self.fold_inner_recur(*item.kind),
81-
};
81+
});
8282
item
8383
}
8484

src/librustdoc/formats/cache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ enum ParentStackItem {
536536
impl ParentStackItem {
537537
fn new(item: &clean::Item) -> Self {
538538
match &*item.kind {
539-
clean::ItemKind::ImplItem(clean::Impl { for_, trait_, generics, kind, .. }) => {
539+
clean::ItemKind::ImplItem(box clean::Impl { for_, trait_, generics, kind, .. }) => {
540540
ParentStackItem::Impl {
541541
for_: for_.clone(),
542542
trait_: trait_.clone(),

src/librustdoc/html/render/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ fn render_deref_methods(
11601160
.items
11611161
.iter()
11621162
.find_map(|item| match *item.kind {
1163-
clean::AssocTypeItem(ref t, _) => Some(match *t {
1163+
clean::AssocTypeItem(box ref t, _) => Some(match *t {
11641164
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
11651165
_ => (&t.type_, &t.type_),
11661166
}),
@@ -2054,7 +2054,7 @@ fn sidebar_deref_methods(
20542054
debug!("found Deref: {:?}", impl_);
20552055
if let Some((target, real_target)) =
20562056
impl_.inner_impl().items.iter().find_map(|item| match *item.kind {
2057-
clean::AssocTypeItem(ref t, _) => Some(match *t {
2057+
clean::AssocTypeItem(box ref t, _) => Some(match *t {
20582058
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
20592059
_ => (&t.type_, &t.type_),
20602060
}),

0 commit comments

Comments
 (0)