Skip to content

Commit 6590336

Browse files
committed
rustdoc: use a single box to store Attributes and ItemKind
1 parent e80c9ac commit 6590336

28 files changed

+195
-179
lines changed

src/librustdoc/clean/auto_trait.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,19 @@ fn synthesize_auto_trait_impl<'tcx>(
115115

116116
Some(clean::Item {
117117
name: None,
118-
attrs: Default::default(),
118+
inner: Box::new(clean::ItemInner {
119+
attrs: Default::default(),
120+
kind: clean::ImplItem(Box::new(clean::Impl {
121+
safety: hir::Safety::Safe,
122+
generics,
123+
trait_: Some(clean_trait_ref_with_constraints(cx, trait_ref, ThinVec::new())),
124+
for_: clean_middle_ty(ty::Binder::dummy(ty), cx, None, None),
125+
items: Vec::new(),
126+
polarity,
127+
kind: clean::ImplKind::Auto,
128+
})),
129+
}),
119130
item_id: clean::ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
120-
kind: Box::new(clean::ImplItem(Box::new(clean::Impl {
121-
safety: hir::Safety::Safe,
122-
generics,
123-
trait_: Some(clean_trait_ref_with_constraints(cx, trait_ref, ThinVec::new())),
124-
for_: clean_middle_ty(ty::Binder::dummy(ty), cx, None, None),
125-
items: Vec::new(),
126-
polarity,
127-
kind: clean::ImplKind::Auto,
128-
}))),
129131
cfg: None,
130132
inline_stmt_id: None,
131133
})

src/librustdoc/clean/blanket_impl.rs

+37-35
Original file line numberDiff line numberDiff line change
@@ -84,42 +84,44 @@ pub(crate) fn synthesize_blanket_impls(
8484

8585
blanket_impls.push(clean::Item {
8686
name: None,
87-
attrs: Default::default(),
8887
item_id: clean::ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
89-
kind: Box::new(clean::ImplItem(Box::new(clean::Impl {
90-
safety: hir::Safety::Safe,
91-
generics: clean_ty_generics(
92-
cx,
93-
tcx.generics_of(impl_def_id),
94-
tcx.explicit_predicates_of(impl_def_id),
95-
),
96-
// FIXME(eddyb) compute both `trait_` and `for_` from
97-
// the post-inference `trait_ref`, as it's more accurate.
98-
trait_: Some(clean_trait_ref_with_constraints(
99-
cx,
100-
ty::Binder::dummy(trait_ref.instantiate_identity()),
101-
ThinVec::new(),
102-
)),
103-
for_: clean_middle_ty(
104-
ty::Binder::dummy(ty.instantiate_identity()),
105-
cx,
106-
None,
107-
None,
108-
),
109-
items: tcx
110-
.associated_items(impl_def_id)
111-
.in_definition_order()
112-
.filter(|item| !item.is_impl_trait_in_trait())
113-
.map(|item| clean_middle_assoc_item(item, cx))
114-
.collect(),
115-
polarity: ty::ImplPolarity::Positive,
116-
kind: clean::ImplKind::Blanket(Box::new(clean_middle_ty(
117-
ty::Binder::dummy(trait_ref.instantiate_identity().self_ty()),
118-
cx,
119-
None,
120-
None,
121-
))),
122-
}))),
88+
inner: Box::new(clean::ItemInner {
89+
attrs: Default::default(),
90+
kind: clean::ImplItem(Box::new(clean::Impl {
91+
safety: hir::Safety::Safe,
92+
generics: clean_ty_generics(
93+
cx,
94+
tcx.generics_of(impl_def_id),
95+
tcx.explicit_predicates_of(impl_def_id),
96+
),
97+
// FIXME(eddyb) compute both `trait_` and `for_` from
98+
// the post-inference `trait_ref`, as it's more accurate.
99+
trait_: Some(clean_trait_ref_with_constraints(
100+
cx,
101+
ty::Binder::dummy(trait_ref.instantiate_identity()),
102+
ThinVec::new(),
103+
)),
104+
for_: clean_middle_ty(
105+
ty::Binder::dummy(ty.instantiate_identity()),
106+
cx,
107+
None,
108+
None,
109+
),
110+
items: tcx
111+
.associated_items(impl_def_id)
112+
.in_definition_order()
113+
.filter(|item| !item.is_impl_trait_in_trait())
114+
.map(|item| clean_middle_assoc_item(item, cx))
115+
.collect(),
116+
polarity: ty::ImplPolarity::Positive,
117+
kind: clean::ImplKind::Blanket(Box::new(clean_middle_ty(
118+
ty::Binder::dummy(trait_ref.instantiate_identity().self_ty()),
119+
cx,
120+
None,
121+
None,
122+
))),
123+
})),
124+
}),
123125
cfg: None,
124126
inline_stmt_id: None,
125127
});

src/librustdoc/clean/inline.rs

+24-27
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,8 @@ pub(crate) fn try_inline(
152152
};
153153

154154
cx.inlined.insert(did.into());
155-
let mut item = crate::clean::generate_item_with_correct_attrs(
156-
cx,
157-
kind,
158-
did,
159-
name,
160-
import_def_id,
161-
None,
162-
);
155+
let mut item =
156+
crate::clean::generate_item_with_correct_attrs(cx, kind, did, name, import_def_id, None);
163157
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
164158
item.inline_stmt_id = import_def_id;
165159
ret.push(item);
@@ -623,7 +617,7 @@ pub(crate) fn build_impl(
623617
ImplKind::Normal
624618
},
625619
})),
626-
Box::new(merged_attrs),
620+
merged_attrs,
627621
cfg,
628622
));
629623
}
@@ -673,27 +667,29 @@ fn build_module_items(
673667
let prim_ty = clean::PrimitiveType::from(p);
674668
items.push(clean::Item {
675669
name: None,
676-
attrs: Box::default(),
677670
// We can use the item's `DefId` directly since the only information ever used
678671
// from it is `DefId.krate`.
679672
item_id: ItemId::DefId(did),
680-
kind: Box::new(clean::ImportItem(clean::Import::new_simple(
681-
item.ident.name,
682-
clean::ImportSource {
683-
path: clean::Path {
684-
res,
685-
segments: thin_vec![clean::PathSegment {
686-
name: prim_ty.as_sym(),
687-
args: clean::GenericArgs::AngleBracketed {
688-
args: Default::default(),
689-
constraints: ThinVec::new(),
690-
},
691-
}],
673+
inner: Box::new(clean::ItemInner {
674+
attrs: Default::default(),
675+
kind: clean::ImportItem(clean::Import::new_simple(
676+
item.ident.name,
677+
clean::ImportSource {
678+
path: clean::Path {
679+
res,
680+
segments: thin_vec![clean::PathSegment {
681+
name: prim_ty.as_sym(),
682+
args: clean::GenericArgs::AngleBracketed {
683+
args: Default::default(),
684+
constraints: ThinVec::new(),
685+
},
686+
}],
687+
},
688+
did: None,
692689
},
693-
did: None,
694-
},
695-
true,
696-
))),
690+
true,
691+
)),
692+
}),
697693
cfg: None,
698694
inline_stmt_id: None,
699695
});
@@ -753,7 +749,8 @@ fn build_macro(
753749
LoadedMacro::MacroDef(item_def, _) => match macro_kind {
754750
MacroKind::Bang => {
755751
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
756-
let vis = cx.tcx.visibility(import_def_id.map(|d| d.to_def_id()).unwrap_or(def_id));
752+
let vis =
753+
cx.tcx.visibility(import_def_id.map(|d| d.to_def_id()).unwrap_or(def_id));
757754
clean::MacroItem(clean::Macro {
758755
source: utils::display_macro_source(
759756
cx,

src/librustdoc/clean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ fn generate_item_with_correct_attrs(
203203
let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (&**attr, *did)), false);
204204

205205
let name = renamed.or(Some(name));
206-
let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, Box::new(attrs), cfg);
206+
let mut item = Item::from_def_id_and_attrs_and_parts(def_id, name, kind, attrs, cfg);
207207
item.inline_stmt_id = import_id;
208208
item
209209
}

src/librustdoc/clean/types.rs

+33-22
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,7 @@ pub(crate) struct Item {
320320
/// The name of this item.
321321
/// Optional because not every item has a name, e.g. impls.
322322
pub(crate) name: Option<Symbol>,
323-
pub(crate) attrs: Box<Attributes>,
324-
/// Information about this item that is specific to what kind of item it is.
325-
/// E.g., struct vs enum vs function.
326-
pub(crate) kind: Box<ItemKind>,
323+
pub(crate) inner: Box<ItemInner>,
327324
pub(crate) item_id: ItemId,
328325
/// This is the `LocalDefId` of the `use` statement if the item was inlined.
329326
/// The crate metadata doesn't hold this information, so the `use` statement
@@ -332,6 +329,21 @@ pub(crate) struct Item {
332329
pub(crate) cfg: Option<Arc<Cfg>>,
333330
}
334331

332+
#[derive(Clone)]
333+
pub(crate) struct ItemInner {
334+
/// Information about this item that is specific to what kind of item it is.
335+
/// E.g., struct vs enum vs function.
336+
pub(crate) kind: ItemKind,
337+
pub(crate) attrs: Attributes,
338+
}
339+
340+
impl std::ops::Deref for Item {
341+
type Target = ItemInner;
342+
fn deref(&self) -> &ItemInner {
343+
&*self.inner
344+
}
345+
}
346+
335347
/// NOTE: this does NOT unconditionally print every item, to avoid thousands of lines of logs.
336348
/// If you want to see the debug output for attributes and the `kind` as well, use `{:#?}` instead of `{:?}`.
337349
impl fmt::Debug for Item {
@@ -391,9 +403,9 @@ impl Item {
391403
}
392404

393405
pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option<Span> {
394-
let kind = match &*self.kind {
395-
ItemKind::StrippedItem(k) => k,
396-
_ => &*self.kind,
406+
let kind = match &self.kind {
407+
ItemKind::StrippedItem(k) => &*k,
408+
_ => &self.kind,
397409
};
398410
match kind {
399411
ItemKind::ModuleItem(Module { span, .. }) => Some(*span),
@@ -438,7 +450,7 @@ impl Item {
438450
def_id,
439451
name,
440452
kind,
441-
Box::new(Attributes::from_ast(ast_attrs)),
453+
Attributes::from_ast(ast_attrs),
442454
ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg),
443455
)
444456
}
@@ -447,16 +459,15 @@ impl Item {
447459
def_id: DefId,
448460
name: Option<Symbol>,
449461
kind: ItemKind,
450-
attrs: Box<Attributes>,
462+
attrs: Attributes,
451463
cfg: Option<Arc<Cfg>>,
452464
) -> Item {
453465
trace!("name={name:?}, def_id={def_id:?} cfg={cfg:?}");
454466

455467
Item {
456468
item_id: def_id.into(),
457-
kind: Box::new(kind),
469+
inner: Box::new(ItemInner { kind, attrs }),
458470
name,
459-
attrs,
460471
cfg,
461472
inline_stmt_id: None,
462473
}
@@ -524,16 +535,16 @@ impl Item {
524535
self.type_() == ItemType::Variant
525536
}
526537
pub(crate) fn is_associated_type(&self) -> bool {
527-
matches!(&*self.kind, AssocTypeItem(..) | StrippedItem(box AssocTypeItem(..)))
538+
matches!(self.kind, AssocTypeItem(..) | StrippedItem(box AssocTypeItem(..)))
528539
}
529540
pub(crate) fn is_ty_associated_type(&self) -> bool {
530-
matches!(&*self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..)))
541+
matches!(self.kind, TyAssocTypeItem(..) | StrippedItem(box TyAssocTypeItem(..)))
531542
}
532543
pub(crate) fn is_associated_const(&self) -> bool {
533-
matches!(&*self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..)))
544+
matches!(self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..)))
534545
}
535546
pub(crate) fn is_ty_associated_const(&self) -> bool {
536-
matches!(&*self.kind, TyAssocConstItem(..) | StrippedItem(box TyAssocConstItem(..)))
547+
matches!(self.kind, TyAssocConstItem(..) | StrippedItem(box TyAssocConstItem(..)))
537548
}
538549
pub(crate) fn is_method(&self) -> bool {
539550
self.type_() == ItemType::Method
@@ -557,14 +568,14 @@ impl Item {
557568
self.type_() == ItemType::Keyword
558569
}
559570
pub(crate) fn is_stripped(&self) -> bool {
560-
match *self.kind {
571+
match self.kind {
561572
StrippedItem(..) => true,
562573
ImportItem(ref i) => !i.should_be_displayed,
563574
_ => false,
564575
}
565576
}
566577
pub(crate) fn has_stripped_entries(&self) -> Option<bool> {
567-
match *self.kind {
578+
match self.kind {
568579
StructItem(ref struct_) => Some(struct_.has_stripped_entries()),
569580
UnionItem(ref union_) => Some(union_.has_stripped_entries()),
570581
EnumItem(ref enum_) => Some(enum_.has_stripped_entries()),
@@ -607,7 +618,7 @@ impl Item {
607618
}
608619

609620
pub(crate) fn is_default(&self) -> bool {
610-
match *self.kind {
621+
match self.kind {
611622
ItemKind::MethodItem(_, Some(defaultness)) => {
612623
defaultness.has_value() && !defaultness.is_final()
613624
}
@@ -635,7 +646,7 @@ impl Item {
635646
};
636647
hir::FnHeader { safety: sig.safety(), abi: sig.abi(), constness, asyncness }
637648
}
638-
let header = match *self.kind {
649+
let header = match self.kind {
639650
ItemKind::ForeignFunctionItem(_, safety) => {
640651
let def_id = self.def_id().unwrap();
641652
let abi = tcx.fn_sig(def_id).skip_binder().abi();
@@ -674,7 +685,7 @@ impl Item {
674685
ItemId::DefId(def_id) => def_id,
675686
};
676687

677-
match *self.kind {
688+
match self.kind {
678689
// Primitives and Keywords are written in the source code as private modules.
679690
// The modules need to be private so that nobody actually uses them, but the
680691
// keywords and primitives that they are documenting are public.
@@ -2561,13 +2572,13 @@ mod size_asserts {
25612572

25622573
use super::*;
25632574
// tidy-alphabetical-start
2564-
static_assert_size!(Crate, 64); // frequently moved by-value
2575+
static_assert_size!(Crate, 56); // frequently moved by-value
25652576
static_assert_size!(DocFragment, 32);
25662577
static_assert_size!(GenericArg, 32);
25672578
static_assert_size!(GenericArgs, 32);
25682579
static_assert_size!(GenericParamDef, 40);
25692580
static_assert_size!(Generics, 16);
2570-
static_assert_size!(Item, 56);
2581+
static_assert_size!(Item, 48);
25712582
static_assert_size!(ItemKind, 48);
25722583
static_assert_size!(PathSegment, 40);
25732584
static_assert_size!(Type, 32);

src/librustdoc/clean/utils.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
3636
// understood by rustdoc.
3737
let mut module = clean_doc_module(&module, cx);
3838

39-
match *module.kind {
39+
match module.kind {
4040
ItemKind::ModuleItem(ref module) => {
4141
for it in &module.items {
4242
// `compiler_builtins` should be masked too, but we can't apply
@@ -60,7 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
6060
let primitives = local_crate.primitives(cx.tcx);
6161
let keywords = local_crate.keywords(cx.tcx);
6262
{
63-
let ItemKind::ModuleItem(ref mut m) = *module.kind else { unreachable!() };
63+
let ItemKind::ModuleItem(ref mut m) = &mut module.inner.kind else { unreachable!() };
6464
m.items.extend(primitives.iter().map(|&(def_id, prim)| {
6565
Item::from_def_id_and_parts(
6666
def_id,
@@ -281,7 +281,7 @@ pub(crate) fn build_deref_target_impls(
281281
let tcx = cx.tcx;
282282

283283
for item in items {
284-
let target = match *item.kind {
284+
let target = match item.kind {
285285
ItemKind::AssocTypeItem(ref t, _) => &t.type_,
286286
_ => continue,
287287
};

0 commit comments

Comments
 (0)