Coalesce item tree data maps
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 4b3890a..b295767 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -89,11 +89,12 @@
 /// The item tree of a source file.
 #[derive(Debug, Default, Eq, PartialEq)]
 pub struct ItemTree {
-    top_level: SmallVec<[ModItem; 1]>,
+    top_level: SmallVec<[ModItemId; 1]>,
     // Consider splitting this into top level RawAttrs and the map?
     attrs: FxHashMap<AttrOwner, RawAttrs>,
 
-    data: Option<Box<ItemTreeData>>,
+    vis: ItemVisibilities,
+    data: FxHashMap<FileAstId<ast::Item>, ModItem>,
 }
 
 impl ItemTree {
@@ -130,14 +131,15 @@
         if let Some(attrs) = top_attrs {
             item_tree.attrs.insert(AttrOwner::TopLevel, attrs);
         }
-        if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
+        if item_tree.data.is_empty() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
         {
             EMPTY
                 .get_or_init(|| {
                     Arc::new(ItemTree {
                         top_level: SmallVec::new_const(),
                         attrs: FxHashMap::default(),
-                        data: None,
+                        data: FxHashMap::default(),
+                        vis: ItemVisibilities { arena: Box::new([]) },
                     })
                 })
                 .clone()
@@ -156,14 +158,15 @@
 
         let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
         let mut item_tree = ctx.lower_block(&block);
-        if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
+        if item_tree.data.is_empty() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
         {
             EMPTY
                 .get_or_init(|| {
                     Arc::new(ItemTree {
                         top_level: SmallVec::new_const(),
                         attrs: FxHashMap::default(),
-                        data: None,
+                        data: FxHashMap::default(),
+                        vis: ItemVisibilities { arena: Box::new([]) },
                     })
                 })
                 .clone()
@@ -175,7 +178,7 @@
 
     /// Returns an iterator over all items located at the top level of the `HirFileId` this
     /// `ItemTree` was created from.
-    pub(crate) fn top_level_items(&self) -> &[ModItem] {
+    pub(crate) fn top_level_items(&self) -> &[ModItemId] {
         &self.top_level
     }
 
@@ -200,74 +203,33 @@
     ///
     /// For more detail, see [`ItemTreeDataStats`].
     pub fn item_tree_stats(&self) -> ItemTreeDataStats {
-        match self.data {
-            Some(ref data) => ItemTreeDataStats {
-                traits: data.traits.len(),
-                impls: data.impls.len(),
-                mods: data.mods.len(),
-                macro_calls: data.macro_calls.len(),
-                macro_rules: data.macro_rules.len(),
-            },
-            None => ItemTreeDataStats::default(),
+        let mut traits = 0;
+        let mut impls = 0;
+        let mut mods = 0;
+        let mut macro_calls = 0;
+        let mut macro_rules = 0;
+        for item in self.data.values() {
+            match item {
+                ModItem::Trait(_) => traits += 1,
+                ModItem::Impl(_) => impls += 1,
+                ModItem::Mod(_) => mods += 1,
+                ModItem::MacroCall(_) => macro_calls += 1,
+                ModItem::MacroRules(_) => macro_rules += 1,
+                _ => {}
+            }
         }
+        ItemTreeDataStats { traits, impls, mods, macro_calls, macro_rules }
     }
 
     pub fn pretty_print(&self, db: &dyn DefDatabase, edition: Edition) -> String {
         pretty::print_item_tree(db, self, edition)
     }
 
-    fn data(&self) -> &ItemTreeData {
-        self.data.as_ref().expect("attempted to access data of empty ItemTree")
-    }
-
-    fn data_mut(&mut self) -> &mut ItemTreeData {
-        self.data.get_or_insert_with(Box::default)
-    }
-
     fn shrink_to_fit(&mut self) {
-        let ItemTree { top_level, attrs, data } = self;
+        let ItemTree { top_level, attrs, data, vis: _ } = self;
         top_level.shrink_to_fit();
         attrs.shrink_to_fit();
-        if let Some(data) = data {
-            let ItemTreeData {
-                uses,
-                extern_crates,
-                extern_blocks,
-                functions,
-                structs,
-                unions,
-                enums,
-                consts,
-                statics,
-                traits,
-                trait_aliases,
-                impls,
-                type_aliases,
-                mods,
-                macro_calls,
-                macro_rules,
-                macro_defs,
-                vis: _,
-            } = &mut **data;
-
-            uses.shrink_to_fit();
-            extern_crates.shrink_to_fit();
-            extern_blocks.shrink_to_fit();
-            functions.shrink_to_fit();
-            structs.shrink_to_fit();
-            unions.shrink_to_fit();
-            enums.shrink_to_fit();
-            consts.shrink_to_fit();
-            statics.shrink_to_fit();
-            traits.shrink_to_fit();
-            trait_aliases.shrink_to_fit();
-            impls.shrink_to_fit();
-            type_aliases.shrink_to_fit();
-            mods.shrink_to_fit();
-            macro_calls.shrink_to_fit();
-            macro_rules.shrink_to_fit();
-            macro_defs.shrink_to_fit();
-        }
+        data.shrink_to_fit();
     }
 }
 
@@ -276,29 +238,26 @@
     arena: Box<[RawVisibility]>,
 }
 
-#[derive(Default, Debug, Eq, PartialEq)]
-struct ItemTreeData {
-    uses: FxHashMap<ItemTreeAstId<Use>, Use>,
-    extern_crates: FxHashMap<ItemTreeAstId<ExternCrate>, ExternCrate>,
-    extern_blocks: FxHashMap<ItemTreeAstId<ExternBlock>, ExternBlock>,
-    functions: FxHashMap<ItemTreeAstId<Function>, Function>,
-    structs: FxHashMap<ItemTreeAstId<Struct>, Struct>,
-    unions: FxHashMap<ItemTreeAstId<Union>, Union>,
-    enums: FxHashMap<ItemTreeAstId<Enum>, Enum>,
-    consts: FxHashMap<ItemTreeAstId<Const>, Const>,
-    statics: FxHashMap<ItemTreeAstId<Static>, Static>,
-    traits: FxHashMap<ItemTreeAstId<Trait>, Trait>,
-    trait_aliases: FxHashMap<ItemTreeAstId<TraitAlias>, TraitAlias>,
-    impls: FxHashMap<ItemTreeAstId<Impl>, Impl>,
-    type_aliases: FxHashMap<ItemTreeAstId<TypeAlias>, TypeAlias>,
-    mods: FxHashMap<ItemTreeAstId<Mod>, Mod>,
-    macro_calls: FxHashMap<ItemTreeAstId<MacroCall>, MacroCall>,
-    macro_rules: FxHashMap<ItemTreeAstId<MacroRules>, MacroRules>,
-    macro_defs: FxHashMap<ItemTreeAstId<Macro2>, Macro2>,
-
-    vis: ItemVisibilities,
+#[derive(Debug, Clone, Eq, PartialEq)]
+enum ModItem {
+    Const(Const),
+    Enum(Enum),
+    ExternBlock(ExternBlock),
+    ExternCrate(ExternCrate),
+    Function(Function),
+    Impl(Impl),
+    Macro2(Macro2),
+    MacroCall(MacroCall),
+    MacroRules(MacroRules),
+    Mod(Mod),
+    Static(Static),
+    Struct(Struct),
+    Trait(Trait),
+    TraitAlias(TraitAlias),
+    TypeAlias(TypeAlias),
+    Union(Union),
+    Use(Use),
 }
-
 #[derive(Default, Debug, Eq, PartialEq)]
 pub struct ItemTreeDataStats {
     pub traits: usize,
@@ -316,9 +275,9 @@
     TopLevel,
 }
 
-impl From<ModItem> for AttrOwner {
+impl From<ModItemId> for AttrOwner {
     #[inline]
-    fn from(value: ModItem) -> Self {
+    fn from(value: ModItemId) -> Self {
         AttrOwner::Item(value.ast_id().erase())
     }
 }
@@ -385,7 +344,7 @@
         $(
             impl From<FileAstId<$ast>> for $mod_item {
                 fn from(id: FileAstId<$ast>) -> $mod_item {
-                    ModItem::$typ(id)
+                    ModItemId::$typ(id)
                 }
             }
         )+
@@ -399,7 +358,10 @@
                 }
 
                 fn lookup(tree: &ItemTree, index: FileAstId<$ast>) -> &Self {
-                    &tree.data().$fld[&index]
+                    match &tree.data[&index.upcast()] {
+                        ModItem::$typ(item) => item,
+                        _ => panic!("expected item of type `{}` at index `{:?}`", stringify!($typ), index),
+                    }
                 }
             }
 
@@ -407,7 +369,10 @@
                 type Output = $typ;
 
                 fn index(&self, index: FileAstId<$ast>) -> &Self::Output {
-                    &self.data().$fld[&index]
+                    match &self.data[&index.upcast()] {
+                        ModItem::$typ(item) => item,
+                        _ => panic!("expected item of type `{}` at index `{:?}`", stringify!($typ), index),
+                    }
                 }
             }
         )+
@@ -415,7 +380,7 @@
 }
 
 mod_items! {
-ModItem ->
+ModItemId ->
     Use in uses -> ast::Use,
     ExternCrate in extern_crates -> ast::ExternCrate,
     ExternBlock in extern_blocks -> ast::ExternBlock,
@@ -463,7 +428,7 @@
                     VisibilityExplicitness::Explicit,
                 )
             }),
-            _ => &self.data().vis.arena[index.0 as usize],
+            _ => &self.vis.arena[index.0 as usize],
         }
     }
 }
@@ -541,7 +506,7 @@
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct ExternBlock {
     pub ast_id: FileAstId<ast::ExternBlock>,
-    pub(crate) children: Box<[ModItem]>,
+    pub(crate) children: Box<[ModItemId]>,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
@@ -656,7 +621,7 @@
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub(crate) enum ModKind {
     /// `mod m { ... }`
-    Inline { items: Box<[ModItem]> },
+    Inline { items: Box<[ModItemId]> },
     /// `mod m;`
     Outline,
 }
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 17b115b..f3e71ef 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -21,10 +21,9 @@
     db::DefDatabase,
     item_tree::{
         AttrOwner, Const, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl, ImportAlias,
-        Interned, ItemTree, ItemTreeAstId, ItemTreeData, Macro2, MacroCall, MacroRules, Mod,
-        ModItem, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct,
-        StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
-        VisibilityExplicitness,
+        Interned, ItemTree, ItemTreeAstId, Macro2, MacroCall, MacroRules, Mod, ModItem, ModItemId,
+        ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct, StructKind,
+        Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind, VisibilityExplicitness,
     },
 };
 
@@ -56,9 +55,7 @@
     pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> ItemTree {
         self.tree.top_level =
             item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect();
-        if let Some(data) = &mut self.tree.data {
-            data.vis.arena = self.visibilities.into_iter().collect();
-        }
+        self.tree.vis.arena = self.visibilities.into_iter().collect();
         self.tree
     }
 
@@ -92,9 +89,7 @@
             }
         }
 
-        if let Some(data) = &mut self.tree.data {
-            data.vis.arena = self.visibilities.into_iter().collect();
-        }
+        self.tree.vis.arena = self.visibilities.into_iter().collect();
         self.tree
     }
 
@@ -120,18 +115,12 @@
                 }
             }
         }
-        if let Some(data) = &mut self.tree.data {
-            data.vis.arena = self.visibilities.into_iter().collect();
-        }
+        self.tree.vis.arena = self.visibilities.into_iter().collect();
         self.tree
     }
 
-    fn data(&mut self) -> &mut ItemTreeData {
-        self.tree.data_mut()
-    }
-
-    fn lower_mod_item(&mut self, item: &ast::Item) -> Option<ModItem> {
-        let mod_item: ModItem = match item {
+    fn lower_mod_item(&mut self, item: &ast::Item) -> Option<ModItemId> {
+        let mod_item: ModItemId = match item {
             ast::Item::Struct(ast) => self.lower_struct(ast)?.into(),
             ast::Item::Union(ast) => self.lower_union(ast)?.into(),
             ast::Item::Enum(ast) => self.lower_enum(ast)?.into(),
@@ -175,7 +164,7 @@
         let ast_id = self.source_ast_id_map.ast_id(strukt);
         let shape = adt_shape(strukt.kind());
         let res = Struct { name, visibility, shape, ast_id };
-        self.data().structs.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Struct(res));
 
         Some(ast_id)
     }
@@ -185,7 +174,7 @@
         let name = union.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(union);
         let res = Union { name, visibility, ast_id };
-        self.data().unions.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Union(res));
         Some(ast_id)
     }
 
@@ -194,7 +183,7 @@
         let name = enum_.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(enum_);
         let res = Enum { name, visibility, ast_id };
-        self.data().enums.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Enum(res));
         Some(ast_id)
     }
 
@@ -206,7 +195,7 @@
 
         let res = Function { name, visibility, ast_id };
 
-        self.data().functions.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Function(res));
         Some(ast_id)
     }
 
@@ -218,7 +207,7 @@
         let visibility = self.lower_visibility(type_alias);
         let ast_id = self.source_ast_id_map.ast_id(type_alias);
         let res = TypeAlias { name, visibility, ast_id };
-        self.data().type_aliases.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::TypeAlias(res));
         Some(ast_id)
     }
 
@@ -227,7 +216,7 @@
         let visibility = self.lower_visibility(static_);
         let ast_id = self.source_ast_id_map.ast_id(static_);
         let res = Static { name, visibility, ast_id };
-        self.data().statics.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Static(res));
         Some(ast_id)
     }
 
@@ -236,7 +225,7 @@
         let visibility = self.lower_visibility(konst);
         let ast_id = self.source_ast_id_map.ast_id(konst);
         let res = Const { name, visibility, ast_id };
-        self.data().consts.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Const(res));
         ast_id
     }
 
@@ -258,7 +247,7 @@
         };
         let ast_id = self.source_ast_id_map.ast_id(module);
         let res = Mod { name, visibility, kind, ast_id };
-        self.data().mods.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Mod(res));
         Some(ast_id)
     }
 
@@ -268,7 +257,7 @@
         let ast_id = self.source_ast_id_map.ast_id(trait_def);
 
         let def = Trait { name, visibility, ast_id };
-        self.data().traits.insert(ast_id, def);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Trait(def));
         Some(ast_id)
     }
 
@@ -281,7 +270,7 @@
         let ast_id = self.source_ast_id_map.ast_id(trait_alias_def);
 
         let alias = TraitAlias { name, visibility, ast_id };
-        self.data().trait_aliases.insert(ast_id, alias);
+        self.tree.data.insert(ast_id.upcast(), ModItem::TraitAlias(alias));
         Some(ast_id)
     }
 
@@ -290,7 +279,7 @@
         // Note that trait impls don't get implicit `Self` unlike traits, because here they are a
         // type alias rather than a type parameter, so this is handled by the resolver.
         let res = Impl { ast_id };
-        self.data().impls.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Impl(res));
         ast_id
     }
 
@@ -302,7 +291,7 @@
         })?;
 
         let res = Use { visibility, ast_id, use_tree };
-        self.data().uses.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Use(res));
         Some(ast_id)
     }
 
@@ -318,7 +307,7 @@
         let ast_id = self.source_ast_id_map.ast_id(extern_crate);
 
         let res = ExternCrate { name, alias, visibility, ast_id };
-        self.data().extern_crates.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::ExternCrate(res));
         Some(ast_id)
     }
 
@@ -332,7 +321,7 @@
         let ast_id = self.source_ast_id_map.ast_id(m);
         let expand_to = hir_expand::ExpandTo::from_call_site(m);
         let res = MacroCall { path, ast_id, expand_to, ctxt: span_map.span_for_range(range).ctx };
-        self.data().macro_calls.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::MacroCall(res));
         Some(ast_id)
     }
 
@@ -341,7 +330,7 @@
         let ast_id = self.source_ast_id_map.ast_id(m);
 
         let res = MacroRules { name: name.as_name(), ast_id };
-        self.data().macro_rules.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::MacroRules(res));
         Some(ast_id)
     }
 
@@ -352,7 +341,7 @@
         let visibility = self.lower_visibility(m);
 
         let res = Macro2 { name: name.as_name(), ast_id, visibility };
-        self.data().macro_defs.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::Macro2(res));
         Some(ast_id)
     }
 
@@ -365,7 +354,7 @@
                     // (in other words, the knowledge that they're in an extern block must not be used).
                     // This is because an extern block can contain macros whose ItemTree's top-level items
                     // should be considered to be in an extern block too.
-                    let mod_item: ModItem = match &item {
+                    let mod_item: ModItemId = match &item {
                         ast::ExternItem::Fn(ast) => self.lower_function(ast)?.into(),
                         ast::ExternItem::Static(ast) => self.lower_static(ast)?.into(),
                         ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(ty)?.into(),
@@ -379,7 +368,7 @@
         });
 
         let res = ExternBlock { ast_id, children };
-        self.data().extern_blocks.insert(ast_id, res);
+        self.tree.data.insert(ast_id.upcast(), ModItem::ExternBlock(res));
         ast_id
     }
 
diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs
index 0c62b86..9a5ca73 100644
--- a/crates/hir-def/src/item_tree/pretty.rs
+++ b/crates/hir-def/src/item_tree/pretty.rs
@@ -7,8 +7,9 @@
 use crate::{
     item_tree::{
         AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
-        ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, RawAttrs, RawVisibilityId,
-        Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
+        ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItemId, ModKind, RawAttrs,
+        RawVisibilityId, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree,
+        UseTreeKind,
     },
     visibility::RawVisibility,
 };
@@ -159,11 +160,11 @@
         }
     }
 
-    fn print_mod_item(&mut self, item: ModItem) {
+    fn print_mod_item(&mut self, item: ModItemId) {
         self.print_attrs_of(item, "\n");
 
         match item {
-            ModItem::Use(it) => {
+            ModItemId::Use(it) => {
                 let Use { visibility, use_tree, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -171,7 +172,7 @@
                 self.print_use_tree(use_tree);
                 wln!(self, ";");
             }
-            ModItem::ExternCrate(it) => {
+            ModItemId::ExternCrate(it) => {
                 let ExternCrate { name, alias, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -181,7 +182,7 @@
                 }
                 wln!(self, ";");
             }
-            ModItem::ExternBlock(it) => {
+            ModItemId::ExternBlock(it) => {
                 let ExternBlock { ast_id, children } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 w!(self, "extern {{");
@@ -192,13 +193,13 @@
                 });
                 wln!(self, "}}");
             }
-            ModItem::Function(it) => {
+            ModItemId::Function(it) => {
                 let Function { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 wln!(self, "fn {};", name.display(self.db, self.edition));
             }
-            ModItem::Struct(it) => {
+            ModItemId::Struct(it) => {
                 let Struct { visibility, name, shape: kind, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -210,7 +211,7 @@
                     wln!(self, ";");
                 }
             }
-            ModItem::Union(it) => {
+            ModItemId::Union(it) => {
                 let Union { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -218,13 +219,13 @@
                 self.print_fields(FieldsShape::Record);
                 wln!(self);
             }
-            ModItem::Enum(it) => {
+            ModItemId::Enum(it) => {
                 let Enum { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "enum {} {{ ... }}", name.display(self.db, self.edition));
             }
-            ModItem::Const(it) => {
+            ModItemId::Const(it) => {
                 let Const { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -235,7 +236,7 @@
                 }
                 wln!(self, " = _;");
             }
-            ModItem::Static(it) => {
+            ModItemId::Static(it) => {
                 let Static { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -244,24 +245,24 @@
                 w!(self, " = _;");
                 wln!(self);
             }
-            ModItem::Trait(it) => {
+            ModItemId::Trait(it) => {
                 let Trait { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition));
             }
-            ModItem::TraitAlias(it) => {
+            ModItemId::TraitAlias(it) => {
                 let TraitAlias { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 wln!(self, "trait {} = ..;", name.display(self.db, self.edition));
             }
-            ModItem::Impl(it) => {
+            ModItemId::Impl(it) => {
                 let Impl { ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 w!(self, "impl {{ ... }}");
             }
-            ModItem::TypeAlias(it) => {
+            ModItemId::TypeAlias(it) => {
                 let TypeAlias { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -269,7 +270,7 @@
                 w!(self, ";");
                 wln!(self);
             }
-            ModItem::Mod(it) => {
+            ModItemId::Mod(it) => {
                 let Mod { name, visibility, kind, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
@@ -289,7 +290,7 @@
                     }
                 }
             }
-            ModItem::MacroCall(it) => {
+            ModItemId::MacroCall(it) => {
                 let MacroCall { path, ast_id, expand_to, ctxt } = &self.tree[it];
                 let _ = writeln!(
                     self,
@@ -300,12 +301,12 @@
                 );
                 wln!(self, "{}!(...);", path.display(self.db, self.edition));
             }
-            ModItem::MacroRules(it) => {
+            ModItemId::MacroRules(it) => {
                 let MacroRules { name, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db, self.edition));
             }
-            ModItem::Macro2(it) => {
+            ModItemId::Macro2(it) => {
                 let Macro2 { name, visibility, ast_id } = &self.tree[it];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 703cb79..3dc76dc 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -36,7 +36,7 @@
     item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports},
     item_tree::{
         self, AttrOwner, FieldsShape, ImportAlias, ImportKind, ItemTree, ItemTreeAstId,
-        ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind,
+        ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItemId, ModKind, TreeId, UseTreeKind,
     },
     macro_call_as_call_id,
     nameres::{
@@ -208,7 +208,7 @@
     Attr {
         ast_id: AstIdWithPath<ast::Item>,
         attr: Attr,
-        mod_item: ModItem,
+        mod_item: ModItemId,
         /* is this needed? */ tree: TreeId,
     },
 }
@@ -1436,9 +1436,9 @@
 
                         let item_tree = tree.item_tree(self.db);
                         let ast_adt_id: FileAstId<ast::Adt> = match *mod_item {
-                            ModItem::Struct(strukt) => item_tree[strukt].ast_id().upcast(),
-                            ModItem::Union(union) => item_tree[union].ast_id().upcast(),
-                            ModItem::Enum(enum_) => item_tree[enum_].ast_id().upcast(),
+                            ModItemId::Struct(strukt) => item_tree[strukt].ast_id().upcast(),
+                            ModItemId::Union(union) => item_tree[union].ast_id().upcast(),
+                            ModItemId::Enum(enum_) => item_tree[enum_].ast_id().upcast(),
                             _ => {
                                 let diag = DefDiagnostic::invalid_derive_target(
                                     directive.module_id,
@@ -1682,12 +1682,12 @@
 }
 
 impl ModCollector<'_, '_> {
-    fn collect_in_top_module(&mut self, items: &[ModItem]) {
+    fn collect_in_top_module(&mut self, items: &[ModItemId]) {
         let module = self.def_collector.def_map.module_id(self.module_id);
         self.collect(items, module.into())
     }
 
-    fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
+    fn collect(&mut self, items: &[ModItemId], container: ItemContainerId) {
         let krate = self.def_collector.def_map.krate;
         let is_crate_root =
             self.module_id == DefMap::ROOT && self.def_collector.def_map.block.is_none();
@@ -1726,7 +1726,7 @@
                 .unwrap_or(Visibility::Public)
         };
 
-        let mut process_mod_item = |item: ModItem| {
+        let mut process_mod_item = |item: ModItemId| {
             let attrs = self.item_tree.attrs(db, krate, item.into());
             if let Some(cfg) = attrs.cfg() {
                 if !self.is_cfg_enabled(&cfg) {
@@ -1748,8 +1748,8 @@
                 self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map);
 
             match item {
-                ModItem::Mod(m) => self.collect_module(m, &attrs),
-                ModItem::Use(item_tree_id) => {
+                ModItemId::Mod(m) => self.collect_module(m, &attrs),
+                ModItemId::Use(item_tree_id) => {
                     let id = UseLoc {
                         container: module,
                         id: InFile::new(self.file_id(), self.item_tree[item_tree_id].ast_id),
@@ -1771,7 +1771,7 @@
                         },
                     )
                 }
-                ModItem::ExternCrate(item_tree_id) => {
+                ModItemId::ExternCrate(item_tree_id) => {
                     let item_tree::ExternCrate { name, visibility, alias, ast_id } =
                         &self.item_tree[item_tree_id];
 
@@ -1845,7 +1845,7 @@
                         );
                     }
                 }
-                ModItem::ExternBlock(block) => {
+                ModItemId::ExternBlock(block) => {
                     let extern_block_id = ExternBlockLoc {
                         container: module,
                         id: InFile::new(self.file_id(), self.item_tree[block].ast_id),
@@ -1859,10 +1859,12 @@
                         ItemContainerId::ExternBlockId(extern_block_id),
                     )
                 }
-                ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
-                ModItem::MacroRules(id) => self.collect_macro_rules(id, module),
-                ModItem::Macro2(id) => self.collect_macro_def(id, module),
-                ModItem::Impl(imp) => {
+                ModItemId::MacroCall(mac) => {
+                    self.collect_macro_call(&self.item_tree[mac], container)
+                }
+                ModItemId::MacroRules(id) => self.collect_macro_rules(id, module),
+                ModItemId::Macro2(id) => self.collect_macro_def(id, module),
+                ModItemId::Impl(imp) => {
                     let impl_id = ImplLoc {
                         container: module,
                         id: InFile::new(self.file_id(), self.item_tree[imp].ast_id),
@@ -1870,7 +1872,7 @@
                     .intern(db);
                     self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
                 }
-                ModItem::Function(id) => {
+                ModItemId::Function(id) => {
                     let it = &self.item_tree[id];
                     let fn_id = FunctionLoc {
                         container,
@@ -1895,7 +1897,7 @@
 
                     update_def(self.def_collector, fn_id.into(), &it.name, vis, false);
                 }
-                ModItem::Struct(id) => {
+                ModItemId::Struct(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -1909,7 +1911,7 @@
                         !matches!(it.shape, FieldsShape::Record),
                     );
                 }
-                ModItem::Union(id) => {
+                ModItemId::Union(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -1923,7 +1925,7 @@
                         false,
                     );
                 }
-                ModItem::Enum(id) => {
+                ModItemId::Enum(id) => {
                     let it = &self.item_tree[id];
                     let enum_ = EnumLoc {
                         container: module,
@@ -1934,7 +1936,7 @@
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(self.def_collector, enum_.into(), &it.name, vis, false);
                 }
-                ModItem::Const(id) => {
+                ModItemId::Const(id) => {
                     let it = &self.item_tree[id];
                     let const_id =
                         ConstLoc { container, id: InFile::new(self.tree_id.file_id(), it.ast_id) }
@@ -1954,7 +1956,7 @@
                         }
                     }
                 }
-                ModItem::Static(id) => {
+                ModItemId::Static(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -1968,7 +1970,7 @@
                         false,
                     );
                 }
-                ModItem::Trait(id) => {
+                ModItemId::Trait(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -1982,7 +1984,7 @@
                         false,
                     );
                 }
-                ModItem::TraitAlias(id) => {
+                ModItemId::TraitAlias(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -1999,7 +2001,7 @@
                         false,
                     );
                 }
-                ModItem::TypeAlias(id) => {
+                ModItemId::TypeAlias(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
@@ -2022,12 +2024,12 @@
         if is_crate_root {
             items
                 .iter()
-                .filter(|it| matches!(it, ModItem::ExternCrate(..)))
+                .filter(|it| matches!(it, ModItemId::ExternCrate(..)))
                 .copied()
                 .for_each(&mut process_mod_item);
             items
                 .iter()
-                .filter(|it| !matches!(it, ModItem::ExternCrate(..)))
+                .filter(|it| !matches!(it, ModItemId::ExternCrate(..)))
                 .copied()
                 .for_each(process_mod_item);
         } else {
@@ -2237,7 +2239,7 @@
     fn resolve_attributes(
         &mut self,
         attrs: &Attrs,
-        mod_item: ModItem,
+        mod_item: ModItemId,
         container: ItemContainerId,
     ) -> Result<(), ()> {
         let mut ignore_up_to = self