diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 4c46771fd7170..ddf547084399b 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -121,7 +121,7 @@ crate fn try_inline(
     };
 
     let target_attrs = load_attrs(cx, did);
-    let attrs = merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
+    let attrs = box merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
 
     cx.renderinfo.borrow_mut().inlined.insert(did);
     let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx);
@@ -444,7 +444,7 @@ crate fn build_impl(
         }),
         cx,
     );
-    item.attrs = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
+    item.attrs = box merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
     debug!("merged_attrs={:?}", item.attrs);
     ret.push(item);
 }
@@ -466,7 +466,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
                 // Primitive types can't be inlined so generate an import instead.
                 items.push(clean::Item {
                     name: None,
-                    attrs: clean::Attributes::default(),
+                    attrs: box clean::Attributes::default(),
                     source: clean::Span::dummy(),
                     def_id: DefId::local(CRATE_DEF_INDEX),
                     visibility: clean::Public,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 14564e7f64aa5..ff3c45ccac7ca 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2169,7 +2169,7 @@ fn clean_extern_crate(
     // FIXME: using `from_def_id_and_kind` breaks `rustdoc/masked` for some reason
     vec![Item {
         name: None,
-        attrs: krate.attrs.clean(cx),
+        attrs: box krate.attrs.clean(cx),
         source: krate.span.clean(cx),
         def_id: crate_def_id,
         visibility: krate.vis.clean(cx),
@@ -2251,7 +2251,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
                 ) {
                     items.push(Item {
                         name: None,
-                        attrs: self.attrs.clean(cx),
+                        attrs: box self.attrs.clean(cx),
                         source: self.span.clean(cx),
                         def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
                         visibility: self.vis.clean(cx),
@@ -2269,7 +2269,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
 
         vec![Item {
             name: None,
-            attrs: self.attrs.clean(cx),
+            attrs: box self.attrs.clean(cx),
             source: self.span.clean(cx),
             def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
             visibility: self.vis.clean(cx),
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7e567bedc7875..1f63fe5b95708 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -82,7 +82,7 @@ crate struct Item {
     crate source: Span,
     /// Not everything has a name. E.g., impls
     crate name: Option<Symbol>,
-    crate attrs: Attributes,
+    crate attrs: Box<Attributes>,
     crate visibility: Visibility,
     crate kind: Box<ItemKind>,
     crate def_id: DefId,
@@ -90,7 +90,7 @@ crate struct Item {
 
 // `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-rustc_data_structures::static_assert_size!(Item, 136);
+rustc_data_structures::static_assert_size!(Item, 48);
 
 impl fmt::Debug for Item {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -159,7 +159,7 @@ impl Item {
             kind: box kind,
             name,
             source: source.clean(cx),
-            attrs: cx.tcx.get_attrs(def_id).clean(cx),
+            attrs: box cx.tcx.get_attrs(def_id).clean(cx),
             visibility: cx.tcx.visibility(def_id).clean(cx),
         }
     }