Unnamed repository; edit this file 'description' to name the repository.
Deduplicate
Lukas Wirth 2024-01-15
parent d80d2fc · commit 2d72ec7
-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 601878e8e7..a389a283b5 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 e8a771141e..b3bb3355f1 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 93a64dc6ec..942fafe329 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 4201b1dd17..2b1d0bca28 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 d0f2bfab43..60832f59eb 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 436bc0c98c..168ee4acff 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 0f81bef500..173aa817b0 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 fc2edce93d..bd2d804e4b 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 53644f58ef..7eb2f3addd 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 fc15a77e8c..760f811ede 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 372d148021..7300a0628f 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 246fc231b4..5e133bf5c7 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 df8c1e904f..cb04f98911 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,