about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-01-15 10:58:05 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-01-15 10:58:05 +0100
commit2d72ec71ec454fed5812a749683a3114ee4c0af5 (patch)
treef19ed3aebb3a7fed115e734beccd1e7ff82ac991
parentd80d2fcae0fb66901d88980d74520992fd5882ff (diff)
downloadrust-2d72ec71ec454fed5812a749683a3114ee4c0af5.tar.gz
rust-2d72ec71ec454fed5812a749683a3114ee4c0af5.zip
Deduplicate
-rw-r--r--crates/hir-def/src/body/pretty.rs30
-rw-r--r--crates/hir-def/src/child_by_source.rs7
-rw-r--r--crates/hir-def/src/data/adt.rs10
-rw-r--r--crates/hir-def/src/db.rs2
-rw-r--r--crates/hir-def/src/dyn_map/keys.rs2
-rw-r--r--crates/hir-def/src/item_scope.rs7
-rw-r--r--crates/hir-def/src/item_tree.rs7
-rw-r--r--crates/hir-def/src/lang_item.rs2
-rw-r--r--crates/hir-def/src/nameres.rs8
-rw-r--r--crates/hir-def/src/nameres/collector.rs40
-rw-r--r--crates/hir-def/src/nameres/path_resolution.rs53
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/hir/src/semantics/source_to_def.rs2
13 files changed, 82 insertions, 95 deletions
diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs
index 601878e8e79..a389a283b59 100644
--- a/crates/hir-def/src/body/pretty.rs
+++ b/crates/hir-def/src/body/pretty.rs
@@ -18,27 +18,21 @@ use super::*;
 pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String {
     let header = match owner {
         DefWithBodyId::FunctionId(it) => {
-            let item_tree_id = it.lookup(db).id;
-            format!(
-                "fn {}",
-                item_tree_id.item_tree(db)[item_tree_id.value].name.display(db.upcast())
-            )
+            it.lookup(db).id.resolved(db, |it| format!("fn {} = ", it.name.display(db.upcast())))
         }
-        DefWithBodyId::StaticId(it) => {
-            let item_tree_id = it.lookup(db).id;
+        DefWithBodyId::StaticId(it) => it
+            .lookup(db)
+            .id
+            .resolved(db, |it| format!("static {} = ", it.name.display(db.upcast()))),
+        DefWithBodyId::ConstId(it) => it.lookup(db).id.resolved(db, |it| {
             format!(
-                "static {} = ",
-                item_tree_id.item_tree(db)[item_tree_id.value].name.display(db.upcast())
+                "const {} = ",
+                match &it.name {
+                    Some(name) => name.display(db.upcast()).to_string(),
+                    None => "_".to_string(),
+                }
             )
-        }
-        DefWithBodyId::ConstId(it) => {
-            let item_tree_id = it.lookup(db).id;
-            let name = match &item_tree_id.item_tree(db)[item_tree_id.value].name {
-                Some(name) => name.display(db.upcast()).to_string(),
-                None => "_".to_string(),
-            };
-            format!("const {name} = ")
-        }
+        }),
         DefWithBodyId::InTypeConstId(_) => format!("In type const = "),
         DefWithBodyId::VariantId(it) => {
             let loc = it.lookup(db);
diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs
index e8a771141ef..b3bb3355f12 100644
--- a/crates/hir-def/src/child_by_source.rs
+++ b/crates/hir-def/src/child_by_source.rs
@@ -204,15 +204,18 @@ impl ChildBySource for VariantId {
 }
 
 impl ChildBySource for EnumId {
-    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, _: HirFileId) {
+    fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
         let loc = &self.lookup(db);
+        if file_id != loc.id.file_id() {
+            return;
+        }
 
         let tree = loc.id.item_tree(db);
         let ast_id_map = db.ast_id_map(loc.id.file_id());
         let root = db.parse_or_expand(loc.id.file_id());
 
         db.enum_data(*self).variants.iter().for_each(|&(variant, _)| {
-            res[keys::VARIANT].insert(
+            res[keys::ENUM_VARIANT].insert(
                 ast_id_map.get(tree[variant.lookup(db).id.value].ast_id).to_node(&root),
                 variant,
             );
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs
index 93a64dc6ec6..942fafe329e 100644
--- a/crates/hir-def/src/data/adt.rs
+++ b/crates/hir-def/src/data/adt.rs
@@ -298,7 +298,7 @@ impl EnumData {
 
         Arc::new(EnumData {
             name: enum_.name.clone(),
-            variants: loc.container.def_map(db)[loc.container.local_id].scope.enums[&e]
+            variants: loc.container.def_map(db).enum_definitions[&e]
                 .iter()
                 .map(|&id| (id, item_tree[id.lookup(db).id.value].name.clone()))
                 .collect(),
@@ -332,7 +332,7 @@ impl EnumVariantData {
     pub(crate) fn enum_variant_data_with_diagnostics_query(
         db: &dyn DefDatabase,
         e: EnumVariantId,
-    ) -> (Arc<EnumVariantData>, Arc<[DefDiagnostic]>) {
+    ) -> (Arc<EnumVariantData>, Option<Arc<Box<[DefDiagnostic]>>>) {
         let loc = e.lookup(db);
         let krate = loc.container.krate;
         let item_tree = loc.id.item_tree(db);
@@ -355,7 +355,11 @@ impl EnumVariantData {
                 name: variant.name.clone(),
                 variant_data: Arc::new(var_data),
             }),
-            field_diagnostics.into(),
+            if field_diagnostics.is_empty() {
+                None
+            } else {
+                Some(Arc::new(field_diagnostics.into_boxed_slice()))
+            },
         )
     }
 }
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 4201b1dd174..2b1d0bca283 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -140,7 +140,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
     fn enum_variant_data_with_diagnostics(
         &self,
         id: EnumVariantId,
-    ) -> (Arc<EnumVariantData>, Arc<[DefDiagnostic]>);
+    ) -> (Arc<EnumVariantData>, Option<Arc<Box<[DefDiagnostic]>>>);
 
     #[salsa::invoke(ImplData::impl_data_query)]
     fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
diff --git a/crates/hir-def/src/dyn_map/keys.rs b/crates/hir-def/src/dyn_map/keys.rs
index d0f2bfab432..60832f59eb9 100644
--- a/crates/hir-def/src/dyn_map/keys.rs
+++ b/crates/hir-def/src/dyn_map/keys.rs
@@ -28,7 +28,7 @@ pub const ENUM: Key<ast::Enum, EnumId> = Key::new();
 pub const EXTERN_CRATE: Key<ast::ExternCrate, ExternCrateId> = Key::new();
 pub const USE: Key<ast::Use, UseId> = Key::new();
 
-pub const VARIANT: Key<ast::Variant, EnumVariantId> = Key::new();
+pub const ENUM_VARIANT: Key<ast::Variant, EnumVariantId> = Key::new();
 pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new();
 pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new();
 pub const TYPE_PARAM: Key<ast::TypeParam, TypeOrConstParamId> = Key::new();
diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs
index 436bc0c98c2..168ee4acffb 100644
--- a/crates/hir-def/src/item_scope.rs
+++ b/crates/hir-def/src/item_scope.rs
@@ -18,8 +18,8 @@ use crate::{
     db::DefDatabase,
     per_ns::PerNs,
     visibility::{Visibility, VisibilityExplicity},
-    AdtId, BuiltinType, ConstId, EnumId, EnumVariantId, ExternCrateId, HasModule, ImplId,
-    LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId,
+    AdtId, BuiltinType, ConstId, ExternCrateId, HasModule, ImplId, LocalModuleId, Lookup, MacroId,
+    ModuleDefId, ModuleId, TraitId, UseId,
 };
 
 #[derive(Debug, Default)]
@@ -79,7 +79,6 @@ pub struct ItemScope {
     /// declared.
     declarations: Vec<ModuleDefId>,
 
-    pub enums: FxHashMap<EnumId, Box<[EnumVariantId]>>,
     impls: Vec<ImplId>,
     unnamed_consts: Vec<ConstId>,
     /// Traits imported via `use Trait as _;`.
@@ -719,7 +718,6 @@ impl ItemScope {
             use_imports_types,
             use_imports_macros,
             macro_invocations,
-            enums,
         } = self;
         types.shrink_to_fit();
         values.shrink_to_fit();
@@ -738,7 +736,6 @@ impl ItemScope {
         extern_crate_decls.shrink_to_fit();
         use_decls.shrink_to_fit();
         macro_invocations.shrink_to_fit();
-        enums.shrink_to_fit();
     }
 }
 
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 0f81bef5006..173aa817b0d 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -445,6 +445,13 @@ impl<N> ItemTreeId<N> {
     pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
         self.tree.item_tree(db)
     }
+
+    pub fn resolved<R>(self, db: &dyn DefDatabase, cb: impl FnOnce(&N) -> R) -> R
+    where
+        ItemTree: Index<FileItemTreeId<N>, Output = N>,
+    {
+        cb(&self.tree.item_tree(db)[self.value])
+    }
 }
 
 impl<N> Copy for ItemTreeId<N> {}
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index fc2edce93da..bd2d804e4b3 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -125,7 +125,7 @@ impl LangItems {
                     }
                     ModuleDefId::AdtId(AdtId::EnumId(e)) => {
                         lang_items.collect_lang_item(db, e, LangItemTarget::EnumId);
-                        module_data.scope.enums[&e].iter().for_each(|&id| {
+                        crate_def_map.enum_definitions[&e].iter().for_each(|&id| {
                             lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant);
                         });
                     }
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index 53644f58efc..7eb2f3adddb 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -80,8 +80,8 @@ use crate::{
     path::ModPath,
     per_ns::PerNs,
     visibility::{Visibility, VisibilityExplicity},
-    AstId, BlockId, BlockLoc, CrateRootModuleId, ExternCrateId, FunctionId, LocalModuleId, Lookup,
-    MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
+    AstId, BlockId, BlockLoc, CrateRootModuleId, EnumId, EnumVariantId, ExternCrateId, FunctionId,
+    LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
 };
 
 /// Contains the results of (early) name resolution.
@@ -113,6 +113,7 @@ pub struct DefMap {
     /// this contains all kinds of macro, not just `macro_rules!` macro.
     /// ExternCrateId being None implies it being imported from the general prelude import.
     macro_use_prelude: FxHashMap<Name, (MacroId, Option<ExternCrateId>)>,
+    pub(crate) enum_definitions: FxHashMap<EnumId, Box<[EnumVariantId]>>,
 
     /// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
     /// attributes.
@@ -370,6 +371,7 @@ impl DefMap {
             macro_use_prelude: FxHashMap::default(),
             derive_helpers_in_scope: FxHashMap::default(),
             diagnostics: Vec::new(),
+            enum_definitions: FxHashMap::default(),
             data: Arc::new(DefMapCrateData {
                 extern_prelude: FxHashMap::default(),
                 exported_derives: FxHashMap::default(),
@@ -612,12 +614,14 @@ impl DefMap {
             krate: _,
             prelude: _,
             data: _,
+            enum_definitions,
         } = self;
 
         macro_use_prelude.shrink_to_fit();
         diagnostics.shrink_to_fit();
         modules.shrink_to_fit();
         derive_helpers_in_scope.shrink_to_fit();
+        enum_definitions.shrink_to_fit();
         for (_, module) in modules.iter_mut() {
             module.children.shrink_to_fit();
             module.scope.shrink_to_fit();
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index fc15a77e8c3..760f811ede6 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -980,35 +980,26 @@ impl DefCollector<'_> {
                         cov_mark::hit!(glob_enum);
                         // glob import from enum => just import all the variants
 
-                        // We need to check if the def map the enum is from is us, then we can't
+                        // We need to check if the def map the enum is from is us, if it is we can't
                         // call the def-map query since we are currently constructing it!
                         let loc = e.lookup(self.db);
                         let tree = loc.id.item_tree(self.db);
                         let current_def_map = self.def_map.krate == loc.container.krate
                             && self.def_map.block_id() == loc.container.block;
+                        let def_map;
                         let resolutions = if current_def_map {
-                            self.def_map.modules[loc.container.local_id].scope.enums[&e]
-                                .iter()
-                                .map(|&variant| {
-                                    let name = tree[variant.lookup(self.db).id.value].name.clone();
-                                    let res =
-                                        PerNs::both(variant.into(), variant.into(), vis, None);
-                                    (Some(name), res)
-                                })
-                                .collect::<Vec<_>>()
+                            &self.def_map.enum_definitions[&e]
                         } else {
-                            loc.container.def_map(self.db).modules[loc.container.local_id]
-                                .scope
-                                .enums[&e]
-                                .iter()
-                                .map(|&variant| {
-                                    let name = tree[variant.lookup(self.db).id.value].name.clone();
-                                    let res =
-                                        PerNs::both(variant.into(), variant.into(), vis, None);
-                                    (Some(name), res)
-                                })
-                                .collect::<Vec<_>>()
-                        };
+                            def_map = loc.container.def_map(self.db);
+                            &def_map.enum_definitions[&e]
+                        }
+                        .iter()
+                        .map(|&variant| {
+                            let name = tree[variant.lookup(self.db).id.value].name.clone();
+                            let res = PerNs::both(variant.into(), variant.into(), vis, None);
+                            (Some(name), res)
+                        })
+                        .collect::<Vec<_>>();
                         self.update(module_id, &resolutions, vis, Some(ImportType::Glob(id)));
                     }
                     Some(d) => {
@@ -1749,10 +1740,7 @@ impl ModCollector<'_, '_> {
                             )
                         })
                         .collect();
-                    self.def_collector.def_map.modules[module_id]
-                        .scope
-                        .enums
-                        .insert(enum_, variants);
+                    self.def_collector.def_map.enum_definitions.insert(enum_, variants);
                 }
                 ModItem::Const(id) => {
                     let it = &self.item_tree[id];
diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs
index 372d1480218..7300a0628f5 100644
--- a/crates/hir-def/src/nameres/path_resolution.rs
+++ b/crates/hir-def/src/nameres/path_resolution.rs
@@ -360,41 +360,28 @@ impl DefMap {
                     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.modules[loc.container.local_id].scope.enums[&e].iter().find_map(
-                            |&variant| {
-                                let variant_data = &tree[variant.lookup(db).id.value];
-                                (variant_data.name == *segment).then(|| match variant_data.fields {
-                                    Fields::Record(_) => {
-                                        PerNs::types(variant.into(), Visibility::Public, None)
-                                    }
-                                    Fields::Tuple(_) | Fields::Unit => PerNs::both(
-                                        variant.into(),
-                                        variant.into(),
-                                        Visibility::Public,
-                                        None,
-                                    ),
-                                })
-                            },
-                        )
+                        &self.enum_definitions[&e]
                     } else {
-                        loc.container.def_map(db).modules[loc.container.local_id].scope.enums[&e]
-                            .iter()
-                            .find_map(|&variant| {
-                                let variant_data = &tree[variant.lookup(db).id.value];
-                                (variant_data.name == *segment).then(|| match variant_data.fields {
-                                    Fields::Record(_) => {
-                                        PerNs::types(variant.into(), Visibility::Public, None)
-                                    }
-                                    Fields::Tuple(_) | Fields::Unit => PerNs::both(
-                                        variant.into(),
-                                        variant.into(),
-                                        Visibility::Public,
-                                        None,
-                                    ),
-                                })
-                            })
-                    };
+                        def_map = loc.container.def_map(db);
+                        &def_map.enum_definitions[&e]
+                    }
+                    .iter()
+                    .find_map(|&variant| {
+                        let variant_data = &tree[variant.lookup(db).id.value];
+                        (variant_data.name == *segment).then(|| match variant_data.fields {
+                            Fields::Record(_) => {
+                                PerNs::types(variant.into(), Visibility::Public, None)
+                            }
+                            Fields::Tuple(_) | Fields::Unit => PerNs::both(
+                                variant.into(),
+                                variant.into(),
+                                Visibility::Public,
+                                None,
+                            ),
+                        })
+                    });
                     match res {
                         Some(res) => res,
                         None => {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 246fc231b47..5e133bf5c75 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -584,8 +584,11 @@ impl Module {
                         Adt::Enum(e) => {
                             for v in e.variants(db) {
                                 acc.extend(ModuleDef::Variant(v).diagnostics(db));
-                                for diag in db.enum_variant_data_with_diagnostics(v.id).1.iter() {
-                                    emit_def_diagnostic(db, acc, diag);
+                                if let Some(diags) = &db.enum_variant_data_with_diagnostics(v.id).1
+                                {
+                                    for diag in &***diags {
+                                        emit_def_diagnostic(db, acc, diag);
+                                    }
                                 }
                             }
                         }
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index df8c1e904fe..cb04f98911e 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -201,7 +201,7 @@ impl SourceToDefCtx<'_, '_> {
         &mut self,
         src: InFile<ast::Variant>,
     ) -> Option<EnumVariantId> {
-        self.to_def(src, keys::VARIANT)
+        self.to_def(src, keys::ENUM_VARIANT)
     }
     pub(super) fn extern_crate_to_def(
         &mut self,