about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-01-15 12:03:31 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-01-15 12:22:51 +0100
commit180e9b2bbfa39c2c00cfa944d9823cae4867d651 (patch)
treee27d97b9206174f3ac89a4ad548a0bfbda730871
parent1669344b2a4168afdebc10fba34b9a0c63a29e72 (diff)
downloadrust-180e9b2bbfa39c2c00cfa944d9823cae4867d651.tar.gz
rust-180e9b2bbfa39c2c00cfa944d9823cae4867d651.zip
Cleanup
-rw-r--r--crates/hir-def/src/attr.rs13
-rw-r--r--crates/hir-def/src/body/pretty.rs2
-rw-r--r--crates/hir-def/src/data/adt.rs13
-rw-r--r--crates/hir-def/src/item_tree.rs6
-rw-r--r--crates/hir-def/src/item_tree/lower.rs2
-rw-r--r--crates/hir-def/src/lib.rs63
-rw-r--r--crates/hir-def/src/nameres/collector.rs109
-rw-r--r--crates/hir-def/src/nameres/path_resolution.rs2
-rw-r--r--crates/hir-def/src/src.rs6
-rw-r--r--crates/hir-def/src/trace.rs4
-rw-r--r--crates/hir-def/src/visibility.rs6
-rw-r--r--crates/hir-ty/src/consteval.rs10
-rw-r--r--crates/hir-ty/src/inhabitedness.rs4
-rw-r--r--crates/hir-ty/src/lower.rs53
-rw-r--r--crates/hir-ty/src/mir/eval.rs26
-rw-r--r--crates/hir/src/lib.rs18
-rw-r--r--crates/syntax/src/ast/node_ext.rs6
17 files changed, 175 insertions, 168 deletions
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs
index be69d6f1351..8fbfcc81d28 100644
--- a/crates/hir-def/src/attr.rs
+++ b/crates/hir-def/src/attr.rs
@@ -24,7 +24,7 @@ use triomphe::Arc;
 
 use crate::{
     db::DefDatabase,
-    item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeNode},
+    item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeModItemNode},
     lang_item::LangItem,
     nameres::{ModuleOrigin, ModuleSource},
     src::{HasChildSource, HasSource},
@@ -82,7 +82,7 @@ impl Attrs {
         let (fields, item_tree, krate) = match v {
             VariantId::EnumVariantId(it) => {
                 let loc = it.lookup(db);
-                let krate = loc.container.krate;
+                let krate = loc.parent.lookup(db).container.krate;
                 let item_tree = loc.id.item_tree(db);
                 let variant = &item_tree[loc.id.value];
                 (variant.fields.clone(), item_tree, krate)
@@ -606,13 +606,16 @@ fn any_has_attrs<'db>(
     id.lookup(db).source(db).map(ast::AnyHasAttrs::new)
 }
 
-fn attrs_from_item_tree<N: ItemTreeNode>(db: &dyn DefDatabase, id: ItemTreeId<N>) -> RawAttrs {
+fn attrs_from_item_tree<N: ItemTreeModItemNode>(
+    db: &dyn DefDatabase,
+    id: ItemTreeId<N>,
+) -> RawAttrs {
     let tree = id.item_tree(db);
     let mod_item = N::id_to_mod_item(id.value);
     tree.raw_attrs(mod_item.into()).clone()
 }
 
-fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>(
+fn attrs_from_item_tree_loc<'db, N: ItemTreeModItemNode>(
     db: &(dyn DefDatabase + 'db),
     lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = ItemLoc<N>>,
 ) -> RawAttrs {
@@ -620,7 +623,7 @@ fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>(
     attrs_from_item_tree(db, id)
 }
 
-fn attrs_from_item_tree_assoc<'db, N: ItemTreeNode>(
+fn attrs_from_item_tree_assoc<'db, N: ItemTreeModItemNode>(
     db: &(dyn DefDatabase + 'db),
     lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<N>>,
 ) -> RawAttrs {
diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs
index a389a283b59..deb87f87d5e 100644
--- a/crates/hir-def/src/body/pretty.rs
+++ b/crates/hir-def/src/body/pretty.rs
@@ -18,7 +18,7 @@ use super::*;
 pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String {
     let header = match owner {
         DefWithBodyId::FunctionId(it) => {
-            it.lookup(db).id.resolved(db, |it| format!("fn {} = ", it.name.display(db.upcast())))
+            it.lookup(db).id.resolved(db, |it| format!("fn {}", it.name.display(db.upcast())))
         }
         DefWithBodyId::StaticId(it) => it
             .lookup(db)
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs
index 6e302aea653..5d443715213 100644
--- a/crates/hir-def/src/data/adt.rs
+++ b/crates/hir-def/src/data/adt.rs
@@ -334,7 +334,8 @@ impl EnumVariantData {
         e: EnumVariantId,
     ) -> (Arc<EnumVariantData>, DefDiagnostics) {
         let loc = e.lookup(db);
-        let krate = loc.container.krate;
+        let container = loc.parent.lookup(db).container;
+        let krate = container.krate;
         let item_tree = loc.id.item_tree(db);
         let cfg_options = db.crate_graph()[krate].cfg_options.clone();
         let variant = &item_tree[loc.id.value];
@@ -343,7 +344,7 @@ impl EnumVariantData {
             db,
             krate,
             loc.id.file_id(),
-            loc.container.local_id,
+            container.local_id,
             &item_tree,
             &cfg_options,
             &variant.fields,
@@ -395,7 +396,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
                 (
                     lookup.source(db).map(|it| it.kind()),
                     &item_tree[lookup.id.value].fields,
-                    lookup.container,
+                    lookup.parent.lookup(db).container,
                 )
             }
             VariantId::StructId(it) => {
@@ -411,11 +412,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
                 let lookup = it.lookup(db);
                 item_tree = lookup.id.item_tree(db);
                 (
-                    lookup.source(db).map(|it| {
-                        it.record_field_list()
-                            .map(ast::StructKind::Record)
-                            .unwrap_or(ast::StructKind::Unit)
-                    }),
+                    lookup.source(db).map(|it| it.kind()),
                     &item_tree[lookup.id.value].fields,
                     lookup.container,
                 )
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 173aa817b0d..c37cf521551 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -337,7 +337,7 @@ from_attrs!(
 );
 
 /// Trait implemented by all item nodes in the item tree.
-pub trait ItemTreeNode: Clone {
+pub trait ItemTreeModItemNode: Clone {
     type Source: AstIdNode + Into<ast::Item>;
 
     fn ast_id(&self) -> FileAstId<Self::Source>;
@@ -494,7 +494,7 @@ macro_rules! mod_items {
         )+
 
         $(
-            impl ItemTreeNode for $typ {
+            impl ItemTreeModItemNode for $typ {
                 type Source = $ast;
 
                 fn ast_id(&self) -> FileAstId<Self::Source> {
@@ -577,7 +577,7 @@ impl Index<RawVisibilityId> for ItemTree {
     }
 }
 
-impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
+impl<N: ItemTreeModItemNode> Index<FileItemTreeId<N>> for ItemTree {
     type Output = N;
     fn index(&self, id: FileItemTreeId<N>) -> &N {
         N::lookup(self, id.index())
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 8d19b5000cf..f6086ed6d9b 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -13,7 +13,7 @@ use crate::{
 
 use super::*;
 
-fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
+fn id<N: ItemTreeModItemNode>(index: Idx<N>) -> FileItemTreeId<N> {
     FileItemTreeId(index)
 }
 
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 1712eaede09..bcd1f37bec4 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -99,8 +99,8 @@ use crate::{
     data::adt::VariantData,
     db::DefDatabase,
     item_tree::{
-        Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules,
-        Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
+        Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeModItemNode, Macro2,
+        MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
     },
 };
 
@@ -213,28 +213,28 @@ impl ModuleId {
 pub type LocalModuleId = Idx<nameres::ModuleData>;
 
 #[derive(Debug)]
-pub struct ItemLoc<N: ItemTreeNode> {
+pub struct ItemLoc<N: ItemTreeModItemNode> {
     pub container: ModuleId,
     pub id: ItemTreeId<N>,
 }
 
-impl<N: ItemTreeNode> Clone for ItemLoc<N> {
+impl<N: ItemTreeModItemNode> Clone for ItemLoc<N> {
     fn clone(&self) -> Self {
         Self { container: self.container, id: self.id }
     }
 }
 
-impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
+impl<N: ItemTreeModItemNode> Copy for ItemLoc<N> {}
 
-impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
+impl<N: ItemTreeModItemNode> PartialEq for ItemLoc<N> {
     fn eq(&self, other: &Self) -> bool {
         self.container == other.container && self.id == other.id
     }
 }
 
-impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
+impl<N: ItemTreeModItemNode> Eq for ItemLoc<N> {}
 
-impl<N: ItemTreeNode> Hash for ItemLoc<N> {
+impl<N: ItemTreeModItemNode> Hash for ItemLoc<N> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         self.container.hash(state);
         self.id.hash(state);
@@ -242,28 +242,28 @@ impl<N: ItemTreeNode> Hash for ItemLoc<N> {
 }
 
 #[derive(Debug)]
-pub struct AssocItemLoc<N: ItemTreeNode> {
+pub struct AssocItemLoc<N: ItemTreeModItemNode> {
     pub container: ItemContainerId,
     pub id: ItemTreeId<N>,
 }
 
-impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
+impl<N: ItemTreeModItemNode> Clone for AssocItemLoc<N> {
     fn clone(&self) -> Self {
         Self { container: self.container, id: self.id }
     }
 }
 
-impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
+impl<N: ItemTreeModItemNode> Copy for AssocItemLoc<N> {}
 
-impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
+impl<N: ItemTreeModItemNode> PartialEq for AssocItemLoc<N> {
     fn eq(&self, other: &Self) -> bool {
         self.container == other.container && self.id == other.id
     }
 }
 
-impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
+impl<N: ItemTreeModItemNode> Eq for AssocItemLoc<N> {}
 
-impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
+impl<N: ItemTreeModItemNode> Hash for AssocItemLoc<N> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         self.container.hash(state);
         self.id.hash(state);
@@ -297,15 +297,14 @@ pub struct EnumId(salsa::InternId);
 pub type EnumLoc = ItemLoc<Enum>;
 impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
 
-// FIXME: rename to `VariantId`, only enums can ave variants
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct EnumVariantId(salsa::InternId);
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct EnumVariantLoc {
-    pub container: ModuleId,
     pub id: ItemTreeId<Variant>,
     pub parent: EnumId,
+    pub index: u32,
 }
 impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
 
@@ -992,7 +991,8 @@ impl HasModule for ItemContainerId {
     }
 }
 
-impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> {
+impl<N: ItemTreeModItemNode> HasModule for AssocItemLoc<N> {
+    #[inline]
     fn module(&self, db: &dyn DefDatabase) -> ModuleId {
         self.container.module(db)
     }
@@ -1008,7 +1008,22 @@ impl HasModule for AdtId {
     }
 }
 
+impl HasModule for EnumId {
+    #[inline]
+    fn module(&self, db: &dyn DefDatabase) -> ModuleId {
+        self.lookup(db).container
+    }
+}
+
+impl HasModule for EnumVariantId {
+    #[inline]
+    fn module(&self, db: &dyn DefDatabase) -> ModuleId {
+        self.lookup(db).parent.module(db)
+    }
+}
+
 impl HasModule for ExternCrateId {
+    #[inline]
     fn module(&self, db: &dyn DefDatabase) -> ModuleId {
         self.lookup(db).container
     }
@@ -1017,7 +1032,7 @@ impl HasModule for ExternCrateId {
 impl HasModule for VariantId {
     fn module(&self, db: &dyn DefDatabase) -> ModuleId {
         match self {
-            VariantId::EnumVariantId(it) => it.lookup(db).container,
+            VariantId::EnumVariantId(it) => it.lookup(db).parent.module(db),
             VariantId::StructId(it) => it.lookup(db).container,
             VariantId::UnionId(it) => it.lookup(db).container,
         }
@@ -1046,7 +1061,7 @@ impl HasModule for TypeOwnerId {
             TypeOwnerId::TraitAliasId(it) => it.lookup(db).container,
             TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db),
             TypeOwnerId::ImplId(it) => it.lookup(db).container,
-            TypeOwnerId::EnumVariantId(it) => it.lookup(db).container,
+            TypeOwnerId::EnumVariantId(it) => it.lookup(db).parent.module(db),
         }
     }
 }
@@ -1057,7 +1072,7 @@ impl HasModule for DefWithBodyId {
             DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
             DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
             DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
-            DefWithBodyId::VariantId(it) => it.lookup(db).container,
+            DefWithBodyId::VariantId(it) => it.lookup(db).parent.module(db),
             DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
         }
     }
@@ -1072,19 +1087,21 @@ impl HasModule for GenericDefId {
             GenericDefId::TraitAliasId(it) => it.lookup(db).container,
             GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
             GenericDefId::ImplId(it) => it.lookup(db).container,
-            GenericDefId::EnumVariantId(it) => it.lookup(db).container,
+            GenericDefId::EnumVariantId(it) => it.lookup(db).parent.lookup(db).container,
             GenericDefId::ConstId(it) => it.lookup(db).module(db),
         }
     }
 }
 
 impl HasModule for TypeAliasId {
+    #[inline]
     fn module(&self, db: &dyn DefDatabase) -> ModuleId {
         self.lookup(db).module(db)
     }
 }
 
 impl HasModule for TraitId {
+    #[inline]
     fn module(&self, db: &dyn DefDatabase) -> ModuleId {
         self.lookup(db).container
     }
@@ -1099,7 +1116,7 @@ impl ModuleDefId {
             ModuleDefId::ModuleId(id) => *id,
             ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
             ModuleDefId::AdtId(id) => id.module(db),
-            ModuleDefId::EnumVariantId(id) => id.lookup(db).container,
+            ModuleDefId::EnumVariantId(id) => id.lookup(db).parent.module(db),
             ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
             ModuleDefId::StaticId(id) => id.lookup(db).module(db),
             ModuleDefId::TraitId(id) => id.lookup(db).container,
@@ -1118,7 +1135,7 @@ impl AttrDefId {
             AttrDefId::FieldId(it) => it.parent.module(db).krate,
             AttrDefId::AdtId(it) => it.module(db).krate,
             AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
-            AttrDefId::EnumVariantId(it) => it.lookup(db).container.krate,
+            AttrDefId::EnumVariantId(it) => it.lookup(db).parent.module(db).krate,
             AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
             AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
             AttrDefId::TraitId(it) => it.lookup(db).container.krate,
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 760f811ede6..893ad47e241 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -3,7 +3,7 @@
 //! `DefCollector::collect` contains the fixed-point iteration loop which
 //! resolves imports and expands macros.
 
-use std::{cmp::Ordering, iter, mem};
+use std::{cmp::Ordering, iter, mem, ops::Not};
 
 use base_db::{CrateId, Dependency, Edition, FileId};
 use cfg::{CfgExpr, CfgOptions};
@@ -35,8 +35,8 @@ use crate::{
     derive_macro_as_call_id,
     item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
     item_tree::{
-        self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
-        Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
+        self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId,
+        ItemTreeModItemNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
     },
     macro_call_as_call_id, macro_call_as_call_id_with_eager,
     nameres::{
@@ -1579,7 +1579,10 @@ impl ModCollector<'_, '_> {
             let attrs = self.item_tree.attrs(db, krate, item.into());
             if let Some(cfg) = attrs.cfg() {
                 if !self.is_cfg_enabled(&cfg) {
-                    self.emit_unconfigured_diagnostic(item.ast_id(self.item_tree).erase(), &cfg);
+                    self.emit_unconfigured_diagnostic(
+                        InFile::new(self.file_id(), item.ast_id(self.item_tree).erase()),
+                        &cfg,
+                    );
                     return;
                 }
             }
@@ -1717,27 +1720,37 @@ impl ModCollector<'_, '_> {
                     let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
                     update_def(self.def_collector, enum_.into(), &it.name, vis, false);
 
+                    let mut index = 0;
                     let variants = FileItemTreeId::range_iter(it.variants.clone())
                         .filter_map(|variant| {
-                            let attrs = self.item_tree.attrs(db, krate, variant.into());
-                            if let Some(cfg) = attrs.cfg() {
-                                if !self.is_cfg_enabled(&cfg) {
+                            let is_enabled = self
+                                .item_tree
+                                .attrs(db, krate, variant.into())
+                                .cfg()
+                                .and_then(|cfg| self.is_cfg_enabled(&cfg).not().then_some(cfg))
+                                .map_or(Ok(()), Err);
+                            match is_enabled {
+                                Err(cfg) => {
                                     self.emit_unconfigured_diagnostic(
-                                        self.item_tree[variant.index()].ast_id.erase(),
+                                        InFile::new(
+                                            self.file_id(),
+                                            self.item_tree[variant.index()].ast_id.erase(),
+                                        ),
                                         &cfg,
                                     );
-                                    return None;
+                                    None
                                 }
+                                Ok(()) => Some({
+                                    let loc = EnumVariantLoc {
+                                        id: ItemTreeId::new(self.tree_id, variant),
+                                        parent: enum_,
+                                        index,
+                                    }
+                                    .intern(db);
+                                    index += 1;
+                                    loc
+                                }),
                             }
-
-                            Some(
-                                EnumVariantLoc {
-                                    container: module,
-                                    id: ItemTreeId::new(self.tree_id, variant),
-                                    parent: enum_,
-                                }
-                                .intern(db),
-                            )
                         })
                         .collect();
                     self.def_collector.def_map.enum_definitions.insert(enum_, variants);
@@ -1927,31 +1940,40 @@ impl ModCollector<'_, '_> {
                         let is_enabled = item_tree
                             .top_level_attrs(db, krate)
                             .cfg()
-                            .map_or(true, |cfg| self.is_cfg_enabled(&cfg));
-                        if is_enabled {
-                            let module_id = self.push_child_module(
-                                module.name.clone(),
-                                ast_id.value,
-                                Some((file_id, is_mod_rs)),
-                                &self.item_tree[module.visibility],
-                                module_id,
-                            );
-                            ModCollector {
-                                def_collector: self.def_collector,
-                                macro_depth: self.macro_depth,
-                                module_id,
-                                tree_id: TreeId::new(file_id.into(), None),
-                                item_tree: &item_tree,
-                                mod_dir,
+                            .and_then(|cfg| self.is_cfg_enabled(&cfg).not().then_some(cfg))
+                            .map_or(Ok(()), Err);
+                        match is_enabled {
+                            Err(cfg) => {
+                                self.emit_unconfigured_diagnostic(
+                                    ast_id.map(|it| it.erase()),
+                                    &cfg,
+                                );
                             }
-                            .collect_in_top_module(item_tree.top_level_items());
-                            let is_macro_use = is_macro_use
-                                || item_tree
-                                    .top_level_attrs(db, krate)
-                                    .by_key("macro_use")
-                                    .exists();
-                            if is_macro_use {
-                                self.import_all_legacy_macros(module_id);
+                            Ok(()) => {
+                                let module_id = self.push_child_module(
+                                    module.name.clone(),
+                                    ast_id.value,
+                                    Some((file_id, is_mod_rs)),
+                                    &self.item_tree[module.visibility],
+                                    module_id,
+                                );
+                                ModCollector {
+                                    def_collector: self.def_collector,
+                                    macro_depth: self.macro_depth,
+                                    module_id,
+                                    tree_id: TreeId::new(file_id.into(), None),
+                                    item_tree: &item_tree,
+                                    mod_dir,
+                                }
+                                .collect_in_top_module(item_tree.top_level_items());
+                                let is_macro_use = is_macro_use
+                                    || item_tree
+                                        .top_level_attrs(db, krate)
+                                        .by_key("macro_use")
+                                        .exists();
+                                if is_macro_use {
+                                    self.import_all_legacy_macros(module_id);
+                                }
                             }
                         }
                     }
@@ -2382,8 +2404,7 @@ impl ModCollector<'_, '_> {
         self.def_collector.cfg_options.check(cfg) != Some(false)
     }
 
-    fn emit_unconfigured_diagnostic(&mut self, ast_id: ErasedFileAstId, cfg: &CfgExpr) {
-        let ast_id = InFile::new(self.file_id(), ast_id);
+    fn emit_unconfigured_diagnostic(&mut self, ast_id: InFile<ErasedFileAstId>, cfg: &CfgExpr) {
         self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
             self.module_id,
             ast_id,
diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs
index 7300a0628f5..01f79f042f7 100644
--- a/crates/hir-def/src/nameres/path_resolution.rs
+++ b/crates/hir-def/src/nameres/path_resolution.rs
@@ -355,12 +355,12 @@ impl DefMap {
                 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
                     // enum variant
                     cov_mark::hit!(can_import_enum_variant);
+                    let def_map;
 
                     let loc = e.lookup(db);
                     let tree = loc.id.item_tree(db);
                     let current_def_map =
                         self.krate == loc.container.krate && self.block_id() == loc.container.block;
-                    let def_map;
                     let res = if current_def_map {
                         &self.enum_definitions[&e]
                     } else {
diff --git a/crates/hir-def/src/src.rs b/crates/hir-def/src/src.rs
index 4698e967eb7..9bd8c8d2215 100644
--- a/crates/hir-def/src/src.rs
+++ b/crates/hir-def/src/src.rs
@@ -5,7 +5,7 @@ use la_arena::ArenaMap;
 use syntax::ast;
 
 use crate::{
-    db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup,
+    db::DefDatabase, item_tree::ItemTreeModItemNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup,
     Macro2Loc, MacroRulesLoc, ProcMacroLoc, UseId,
 };
 
@@ -14,7 +14,7 @@ pub trait HasSource {
     fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>;
 }
 
-impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> {
+impl<N: ItemTreeModItemNode> HasSource for AssocItemLoc<N> {
     type Value = N::Source;
 
     fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
@@ -27,7 +27,7 @@ impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> {
     }
 }
 
-impl<N: ItemTreeNode> HasSource for ItemLoc<N> {
+impl<N: ItemTreeModItemNode> HasSource for ItemLoc<N> {
     type Value = N::Source;
 
     fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
diff --git a/crates/hir-def/src/trace.rs b/crates/hir-def/src/trace.rs
index 01654f04ccf..04d5b266194 100644
--- a/crates/hir-def/src/trace.rs
+++ b/crates/hir-def/src/trace.rs
@@ -19,6 +19,10 @@ pub(crate) struct Trace<T, V> {
 
 impl<T, V> Trace<T, V> {
     #[allow(dead_code)]
+    pub(crate) fn new_for_arena() -> Trace<T, V> {
+        Trace { arena: Some(Arena::default()), map: None, len: 0 }
+    }
+
     pub(crate) fn new_for_map() -> Trace<T, V> {
         Trace { arena: None, map: Some(ArenaMap::default()), len: 0 }
     }
diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs
index c73ffa334c3..3294ce29a4a 100644
--- a/crates/hir-def/src/visibility.rs
+++ b/crates/hir-def/src/visibility.rs
@@ -222,11 +222,7 @@ pub(crate) fn field_visibilities_query(
     db: &dyn DefDatabase,
     variant_id: VariantId,
 ) -> Arc<ArenaMap<LocalFieldId, Visibility>> {
-    let var_data = match variant_id {
-        VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
-        VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
-        VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(),
-    };
+    let var_data = variant_id.variant_data(db);
     let resolver = variant_id.module(db).resolver(db);
     let mut res = ArenaMap::default();
     for (field_id, field_data) in var_data.fields().iter() {
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 2e1525ebe17..dae612e6d25 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -257,15 +257,7 @@ pub(crate) fn const_eval_discriminant_variant(
     let body = db.body(def);
     if body.exprs[body.body_expr] == Expr::Missing {
         let loc = variant_id.lookup(db.upcast());
-        let parent_id = loc.parent.lookup(db.upcast()).id;
-        let index = loc.id.value.index().into_raw().into_u32()
-            - parent_id.item_tree(db.upcast())[parent_id.value]
-                .variants
-                .start
-                .index()
-                .into_raw()
-                .into_u32();
-        let prev_idx = index.checked_sub(1);
+        let prev_idx = loc.index.checked_sub(1);
         let value = match prev_idx {
             Some(prev_idx) => {
                 1 + db.const_eval_discriminant(
diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs
index dda5ddd0bae..a63556f450d 100644
--- a/crates/hir-ty/src/inhabitedness.rs
+++ b/crates/hir-ty/src/inhabitedness.rs
@@ -7,7 +7,7 @@ use chalk_ir::{
 };
 use hir_def::{
     attr::Attrs, data::adt::VariantData, visibility::Visibility, AdtId, EnumVariantId, HasModule,
-    Lookup, ModuleId, VariantId,
+    ModuleId, VariantId,
 };
 use rustc_hash::FxHashSet;
 
@@ -30,7 +30,7 @@ pub(crate) fn is_enum_variant_uninhabited_from(
     target_mod: ModuleId,
     db: &dyn HirDatabase,
 ) -> bool {
-    let is_local = variant.lookup(db.upcast()).container.krate() == target_mod.krate();
+    let is_local = variant.module(db.upcast()).krate() == target_mod.krate();
 
     let mut uninhabited_from =
         UninhabitedFrom { target_mod, db, max_depth: 500, recursive_ty: FxHashSet::default() };
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index e160f05b013..f66b584e3b5 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -1729,16 +1729,19 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
 /// Build the type of a tuple struct constructor.
 fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
     let struct_data = db.struct_data(def);
-    if let StructKind::Unit = struct_data.variant_data.kind() {
-        return type_for_adt(db, def.into());
+    match struct_data.variant_data.kind() {
+        StructKind::Record => unreachable!("callers check for valueness of variant"),
+        StructKind::Unit => return type_for_adt(db, def.into()),
+        StructKind::Tuple => {
+            let generics = generics(db.upcast(), AdtId::from(def).into());
+            let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
+            make_binders(
+                db,
+                &generics,
+                TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
+            )
+        }
     }
-    let generics = generics(db.upcast(), AdtId::from(def).into());
-    let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
-    make_binders(
-        db,
-        &generics,
-        TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
-    )
 }
 
 fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1756,16 +1759,20 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
 /// Build the type of a tuple enum variant constructor.
 fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
     let e = def.lookup(db.upcast()).parent;
-    if let StructKind::Unit = db.enum_variant_data(def).variant_data.kind() {
-        return type_for_adt(db, e.into());
+    match db.enum_variant_data(def).variant_data.kind() {
+        StructKind::Record => unreachable!("callers check for valueness of variant"),
+        StructKind::Unit => return type_for_adt(db, e.into()),
+        StructKind::Tuple => {
+            let generics = generics(db.upcast(), e.into());
+            let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
+            make_binders(
+                db,
+                &generics,
+                TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs)
+                    .intern(Interner),
+            )
+        }
     }
-    let generics = generics(db.upcast(), e.into());
-    let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
-    make_binders(
-        db,
-        &generics,
-        TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
-    )
 }
 
 fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
@@ -1813,7 +1820,7 @@ impl CallableDefId {
         match self {
             CallableDefId::FunctionId(f) => f.lookup(db).module(db),
             CallableDefId::StructId(s) => s.lookup(db).container,
-            CallableDefId::EnumVariantId(e) => e.lookup(db).container,
+            CallableDefId::EnumVariantId(e) => e.module(db),
         }
         .krate()
     }
@@ -1894,12 +1901,8 @@ pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders
 }
 
 pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
-    let impl_loc = impl_id.lookup(db.upcast());
     let impl_data = db.impl_data(impl_id);
     let resolver = impl_id.resolver(db.upcast());
-    let _cx = stdx::panic_context::enter(format!(
-        "impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
-    ));
     let generics = generics(db.upcast(), impl_id.into());
     let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
         .with_type_param_mode(ParamLoweringMode::Variable);
@@ -1931,12 +1934,8 @@ pub(crate) fn impl_self_ty_recover(
 }
 
 pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
-    let impl_loc = impl_id.lookup(db.upcast());
     let impl_data = db.impl_data(impl_id);
     let resolver = impl_id.resolver(db.upcast());
-    let _cx = stdx::panic_context::enter(format!(
-        "impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
-    ));
     let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
         .with_type_param_mode(ParamLoweringMode::Variable);
     let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 431d09c5650..ceb170f6cf7 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -751,19 +751,9 @@ impl Evaluator<'_> {
                         Variants::Single { .. } => &layout,
                         Variants::Multiple { variants, .. } => {
                             &variants[match f.parent {
-                                hir_def::VariantId::EnumVariantId(it) => RustcEnumVariantIdx({
-                                    let lookup = it.lookup(self.db.upcast());
-                                    let rustc_enum_variant_idx =
-                                        lookup.id.value.index().into_raw().into_u32()
-                                            - lookup.id.item_tree(self.db.upcast())
-                                                [lookup.parent.lookup(self.db.upcast()).id.value]
-                                                .variants
-                                                .start
-                                                .index()
-                                                .into_raw()
-                                                .into_u32();
-                                    rustc_enum_variant_idx as usize
-                                }),
+                                hir_def::VariantId::EnumVariantId(it) => {
+                                    RustcEnumVariantIdx(it.lookup(self.db.upcast()).index as usize)
+                                }
                                 _ => {
                                     return Err(MirEvalError::TypeError(
                                         "Multivariant layout only happens for enums",
@@ -1604,15 +1594,7 @@ impl Evaluator<'_> {
                 };
                 let mut discriminant = self.const_eval_discriminant(enum_variant_id)?;
                 let lookup = enum_variant_id.lookup(self.db.upcast());
-                let rustc_enum_variant_idx = lookup.id.value.index().into_raw().into_u32()
-                    - lookup.id.item_tree(self.db.upcast())
-                        [lookup.parent.lookup(self.db.upcast()).id.value]
-                        .variants
-                        .start
-                        .index()
-                        .into_raw()
-                        .into_u32();
-                let rustc_enum_variant_idx = RustcEnumVariantIdx(rustc_enum_variant_idx as usize);
+                let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize);
                 let variant_layout = variants[rustc_enum_variant_idx].clone();
                 let have_tag = match tag_encoding {
                     TagEncoding::Direct => true,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 246fc231b47..91f60653543 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -44,7 +44,7 @@ use hir_def::{
     data::adt::VariantData,
     generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
     hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
-    item_tree::ItemTreeNode,
+    item_tree::ItemTreeModItemNode,
     lang_item::LangItemTarget,
     layout::{self, ReprOptions, TargetDataLayout},
     nameres::{self, diagnostics::DefDiagnostic},
@@ -1294,7 +1294,7 @@ pub struct Variant {
 
 impl Variant {
     pub fn module(self, db: &dyn HirDatabase) -> Module {
-        Module { id: self.id.lookup(db.upcast()).container }
+        Module { id: self.id.module(db.upcast()) }
     }
 
     pub fn parent_enum(self, db: &dyn HirDatabase) -> Enum {
@@ -1340,17 +1340,7 @@ impl Variant {
             layout::Variants::Multiple { variants, .. } => Layout(
                 {
                     let lookup = self.id.lookup(db.upcast());
-                    let rustc_enum_variant_idx = lookup.id.value.index().into_raw().into_u32()
-                        - lookup.id.item_tree(db.upcast())
-                            [lookup.parent.lookup(db.upcast()).id.value]
-                            .variants
-                            .start
-                            .index()
-                            .into_raw()
-                            .into_u32();
-                    let rustc_enum_variant_idx =
-                        RustcEnumVariantIdx(rustc_enum_variant_idx as usize);
-
+                    let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize);
                     Arc::new(variants[rustc_enum_variant_idx].clone())
                 },
                 db.target_data_layout(parent_enum.krate(db).into()).unwrap(),
@@ -2838,7 +2828,7 @@ where
     ID: Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<AST>>,
     DEF: From<ID>,
     CTOR: FnOnce(DEF) -> AssocItem,
-    AST: ItemTreeNode,
+    AST: ItemTreeModItemNode,
 {
     match id.lookup(db.upcast()).container {
         ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 1c6157de559..19c2d3be16b 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -440,6 +440,12 @@ impl ast::Struct {
     }
 }
 
+impl ast::Union {
+    pub fn kind(&self) -> StructKind {
+        StructKind::from_node(self)
+    }
+}
+
 impl ast::RecordExprField {
     pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> {
         let candidate = Self::for_name_ref(field_name)?;