From e29f46ce3761e7a3e8bf535bc55b7f8b58e4c0a7 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jyn514@gmail.com>
Date: Thu, 22 Apr 2021 20:14:24 -0400
Subject: [PATCH] rustdoc: Remove unnecessary `is_crate` field from
 doctree::Module and clean::Module

It can be calculated on-demand even without a TyCtxt.

This also changed `from_item_kind` to take a whole item, which avoids
having to add more and more parameters.
---
 src/librustdoc/clean/inline.rs           |  2 +-
 src/librustdoc/clean/mod.rs              |  8 ++----
 src/librustdoc/clean/types.rs            | 10 ++-----
 src/librustdoc/doctree.rs                |  2 --
 src/librustdoc/fold.rs                   |  5 +---
 src/librustdoc/html/render/print_item.rs |  4 +--
 src/librustdoc/json/conversions.rs       | 36 +++++++++++-------------
 src/librustdoc/visit_ast.rs              |  1 -
 8 files changed, 26 insertions(+), 42 deletions(-)

diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 277ec91f15ed7..01936da57467a 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -487,7 +487,7 @@ fn build_module(
         }
     }
 
-    clean::Module { items, is_crate: false }
+    clean::Module { items }
 }
 
 crate fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 72046645e3a97..9b0be6aec3942 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -112,12 +112,8 @@ impl Clean<Item> for doctree::Module<'_> {
             }
         };
 
-        let what_rustc_thinks = Item::from_hir_id_and_parts(
-            self.id,
-            Some(self.name),
-            ModuleItem(Module { is_crate: self.is_crate, items }),
-            cx,
-        );
+        let what_rustc_thinks =
+            Item::from_hir_id_and_parts(self.id, Some(self.name), ModuleItem(Module { items }), cx);
         Item { span: span.clean(cx), ..what_rustc_thinks }
     }
 }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 1acde8401b21e..1308ff769ba8e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -391,12 +391,9 @@ impl Item {
     }
 
     crate fn is_crate(&self) -> bool {
-        matches!(
-            *self.kind,
-            StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
-                | ModuleItem(Module { is_crate: true, .. })
-        )
+        self.is_mod() && self.def_id.index == CRATE_DEF_INDEX
     }
+
     crate fn is_mod(&self) -> bool {
         self.type_() == ItemType::Module
     }
@@ -608,7 +605,6 @@ impl ItemKind {
 #[derive(Clone, Debug)]
 crate struct Module {
     crate items: Vec<Item>,
-    crate is_crate: bool,
 }
 
 crate struct ListAttributesIter<'a> {
@@ -1983,7 +1979,7 @@ crate enum Variant {
 
 /// Small wrapper around [`rustc_span::Span]` that adds helper methods
 /// and enforces calling [`rustc_span::Span::source_callsite()`].
-#[derive(Clone, Debug)]
+#[derive(Copy, Clone, Debug)]
 crate struct Span(rustc_span::Span);
 
 impl Span {
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 189624c0d809c..d3f4353a58b7b 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -14,7 +14,6 @@ crate struct Module<'hir> {
     crate items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>)>,
     crate foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
     crate macros: Vec<(&'hir hir::MacroDef<'hir>, Option<Symbol>)>,
-    crate is_crate: bool,
 }
 
 impl Module<'hir> {
@@ -28,7 +27,6 @@ impl Module<'hir> {
             items: Vec::new(),
             foreigns: Vec::new(),
             macros: Vec::new(),
-            is_crate: false,
         }
     }
 }
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 376fef6568af7..ed91a56057574 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -80,10 +80,7 @@ crate trait DocFolder: Sized {
     }
 
     fn fold_mod(&mut self, m: Module) -> Module {
-        Module {
-            is_crate: m.is_crate,
-            items: m.items.into_iter().filter_map(|i| self.fold_item(i)).collect(),
-        }
+        Module { items: m.items.into_iter().filter_map(|i| self.fold_item(i)).collect() }
     }
 
     fn fold_crate(&mut self, mut c: Crate) -> Crate {
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index a303ca956d8fe..4d338417b922d 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -28,8 +28,8 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer)
     // Write the breadcrumb trail header for the top
     buf.write_str("<h1 class=\"fqn\"><span class=\"in-band\">");
     let name = match *item.kind {
-        clean::ModuleItem(ref m) => {
-            if m.is_crate {
+        clean::ModuleItem(_) => {
+            if item.is_crate() {
                 "Crate "
             } else {
                 "Module "
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 10d5b9807b010..80ef0073da8a4 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -10,7 +10,6 @@ use rustc_ast::ast;
 use rustc_hir::def::CtorKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
-use rustc_span::symbol::Symbol;
 use rustc_span::Pos;
 
 use rustdoc_json_types::*;
@@ -34,10 +33,17 @@ impl JsonRenderer<'_> {
                 did.map(|did| (link.clone(), from_def_id(did)))
             })
             .collect();
-        let clean::Item { span, name, attrs, kind, visibility, def_id } = item;
-        let inner = match *kind {
+        let docs = item.attrs.collapsed_doc_value();
+        let attrs = item
+            .attrs
+            .other_attrs
+            .iter()
+            .map(rustc_ast_pretty::pprust::attribute_to_string)
+            .collect();
+        let clean::Item { span, name, attrs: _, kind: _, visibility, def_id } = item;
+        let inner = match *item.kind {
             clean::StrippedItem(_) => return None,
-            kind => from_clean_item_kind(kind, self.tcx, &name),
+            _ => from_clean_item(item, self.tcx),
         };
         Some(Item {
             id: from_def_id(def_id),
@@ -45,12 +51,8 @@ impl JsonRenderer<'_> {
             name: name.map(|sym| sym.to_string()),
             span: self.convert_span(span),
             visibility: self.convert_visibility(visibility),
-            docs: attrs.collapsed_doc_value(),
-            attrs: attrs
-                .other_attrs
-                .iter()
-                .map(rustc_ast_pretty::pprust::attribute_to_string)
-                .collect(),
+            docs,
+            attrs,
             deprecation: deprecation.map(from_deprecation),
             inner,
             links,
@@ -172,10 +174,12 @@ crate fn from_def_id(did: DefId) -> Id {
     Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index)))
 }
 
-fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>, name: &Option<Symbol>) -> ItemEnum {
+fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
     use clean::ItemKind::*;
-    match item {
-        ModuleItem(m) => ItemEnum::Module(m.into_tcx(tcx)),
+    let name = item.name;
+    let is_crate = item.is_crate();
+    match *item.kind {
+        ModuleItem(m) => ItemEnum::Module(Module { is_crate, items: ids(m.items) }),
         ImportItem(i) => ItemEnum::Import(i.into_tcx(tcx)),
         StructItem(s) => ItemEnum::Struct(s.into_tcx(tcx)),
         UnionItem(u) => ItemEnum::Union(u.into_tcx(tcx)),
@@ -214,12 +218,6 @@ fn from_clean_item_kind(item: clean::ItemKind, tcx: TyCtxt<'_>, name: &Option<Sy
     }
 }
 
-impl FromWithTcx<clean::Module> for Module {
-    fn from_tcx(module: clean::Module, _tcx: TyCtxt<'_>) -> Self {
-        Module { is_crate: module.is_crate, items: ids(module.items) }
-    }
-}
-
 impl FromWithTcx<clean::Struct> for Struct {
     fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self {
         let clean::Struct { struct_type, generics, fields, fields_stripped } = struct_;
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ca30d8f0d4623..22c7751a710b9 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -78,7 +78,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             &krate.item,
             self.cx.tcx.crate_name,
         );
-        top_level_module.is_crate = true;
         // Attach the crate's exported macros to the top-level module.
         // In the case of macros 2.0 (`pub macro`), and for built-in `derive`s or attributes as
         // well (_e.g._, `Copy`), these are wrongly bundled in there too, so we need to fix that by