diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index ebe05afca6..7055e3ca9e 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -1073,7 +1073,7 @@ impl ExprCollector<'_> { match block_id.map(|block_id| (self.db.block_def_map(block_id), block_id)) { Some((def_map, block_id)) => { self.body.block_scopes.push(block_id); - (def_map.module_id(def_map.root()), def_map) + (def_map.module_id(DefMap::ROOT), def_map) } None => (self.expander.module, self.def_map.clone()), }; diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs index 21180fcbda..bb79e28f26 100644 --- a/crates/hir-def/src/child_by_source.rs +++ b/crates/hir-def/src/child_by_source.rs @@ -12,6 +12,7 @@ use crate::{ db::DefDatabase, dyn_map::{keys, DynMap}, item_scope::ItemScope, + nameres::DefMap, src::{HasChildSource, HasSource}, AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, VariantId, @@ -205,7 +206,7 @@ impl ChildBySource for DefWithBodyId { for (_, def_map) in body.blocks(db) { // All block expressions are merged into the same map, because they logically all add // inner items to the containing `DefWithBodyId`. - def_map[def_map.root()].scope.child_by_source_to(db, res, file_id); + def_map[DefMap::ROOT].scope.child_by_source_to(db, res, file_id); } } } diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index c3721a94f6..6d18e3f56c 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -198,15 +198,14 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Arc; - #[salsa::invoke(LangItems::lang_item_query)] fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option; #[salsa::invoke(ImportMap::import_map_query)] fn import_map(&self, krate: CrateId) -> Arc; + // region:visibilities + #[salsa::invoke(visibility::field_visibilities_query)] fn field_visibilities(&self, var: VariantId) -> Arc>; @@ -217,8 +216,14 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Visibility; + // endregion:visibilities + + #[salsa::invoke(LangItems::crate_lang_items_query)] + fn crate_lang_items(&self, krate: CrateId) -> Arc; + #[salsa::transparent] fn crate_limits(&self, crate_id: CrateId) -> CrateLimits; + #[salsa::transparent] fn recursion_limit(&self, crate_id: CrateId) -> u32; diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index 6ef2949ef5..ec150dc068 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -11,8 +11,8 @@ use rustc_hash::{FxHashSet, FxHasher}; use triomphe::Arc; use crate::{ - db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId, - ModuleId, TraitId, + db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, visibility::Visibility, AssocItemId, + ModuleDefId, ModuleId, TraitId, }; type FxIndexMap = IndexMap>; @@ -183,7 +183,7 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMap { // We look only into modules that are public(ly reexported), starting with the crate root. let empty = ImportPath { segments: vec![] }; - let root = def_map.module_id(def_map.root()); + let root = def_map.module_id(DefMap::ROOT); let mut worklist = vec![(root, empty)]; while let Some((module, mod_path)) = worklist.pop() { let ext_def_map; diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs index 40849d4a66..4a62696df0 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -35,7 +35,7 @@ use tt::token_id::{Subtree, TokenId}; use crate::{ db::DefDatabase, macro_id_to_def_id, - nameres::{MacroSubNs, ModuleSource}, + nameres::{DefMap, MacroSubNs, ModuleSource}, resolver::HasResolver, src::HasSource, test_db::TestDB, @@ -61,7 +61,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros); let krate = db.crate_graph().iter().next().unwrap(); let def_map = db.crate_def_map(krate); - let local_id = def_map.root(); + let local_id = DefMap::ROOT; let module = def_map.module_id(local_id); let resolver = module.resolver(&db); let source = def_map[local_id].definition_source(&db); diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index ccb9bed5c5..053ab5890e 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -94,7 +94,6 @@ use crate::{ pub struct DefMap { _c: Count, block: Option, - root: LocalModuleId, modules: Arena, krate: CrateId, /// The prelude module for this crate. This either comes from an import @@ -141,7 +140,19 @@ struct BlockInfo { /// The `BlockId` this `DefMap` was created from. block: BlockId, /// The containing module. - parent: ModuleId, + parent: BlockRelativeModuleId, +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +struct BlockRelativeModuleId { + block: Option, + local_id: LocalModuleId, +} + +impl BlockRelativeModuleId { + fn def_map(self, db: &dyn DefDatabase, krate: CrateId) -> Arc { + ModuleId { krate, block: self.block, local_id: self.local_id }.def_map(db) + } } impl std::ops::Index for DefMap { @@ -231,6 +242,8 @@ pub struct ModuleData { } impl DefMap { + pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0)); + pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc { let _p = profile::span("crate_def_map_query").detail(|| { db.crate_graph()[krate].display_name.as_deref().unwrap_or_default().to_string() @@ -266,7 +279,13 @@ impl DefMap { ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility); let mut def_map = DefMap::empty(krate, parent_map.edition, module_data); - def_map.block = Some(BlockInfo { block: block_id, parent: block.module }); + def_map.block = Some(BlockInfo { + block: block_id, + parent: BlockRelativeModuleId { + block: block.module.block, + local_id: block.module.local_id, + }, + }); let def_map = collector::collect_defs(db, def_map, tree_id); Arc::new(def_map) @@ -275,6 +294,7 @@ impl DefMap { fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap { let mut modules: Arena = Arena::default(); let root = modules.alloc(module_data); + assert_eq!(root, Self::ROOT); DefMap { _c: Count::new(), @@ -289,7 +309,6 @@ impl DefMap { proc_macro_loading_error: None, derive_helpers_in_scope: FxHashMap::default(), prelude: None, - root, modules, registered_attrs: Vec::new(), registered_tools: Vec::new(), @@ -339,10 +358,6 @@ impl DefMap { self.no_std || self.no_core } - pub fn root(&self) -> LocalModuleId { - self.root - } - pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option { self.fn_proc_macro_mapping.get(&id).copied() } @@ -377,9 +392,9 @@ impl DefMap { } pub(crate) fn crate_root(&self, db: &dyn DefDatabase) -> ModuleId { - self.with_ancestor_maps(db, self.root, &mut |def_map, _module| { + self.with_ancestor_maps(db, Self::ROOT, &mut |def_map, _module| { if def_map.block.is_none() { - Some(def_map.module_id(def_map.root)) + Some(def_map.module_id(Self::ROOT)) } else { None } @@ -439,7 +454,7 @@ impl DefMap { } let mut block = self.block; while let Some(block_info) = block { - let parent = block_info.parent.def_map(db); + let parent = block_info.parent.def_map(db, self.krate); if let Some(it) = f(&parent, block_info.parent.local_id) { return Some(it); } @@ -452,7 +467,8 @@ impl DefMap { /// If this `DefMap` is for a block expression, returns the module containing the block (which /// might again be a block, or a module inside a block). pub fn parent(&self) -> Option { - Some(self.block?.parent) + let BlockRelativeModuleId { block, local_id } = self.block?.parent; + Some(ModuleId { krate: self.krate, block, local_id }) } /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing @@ -460,7 +476,13 @@ impl DefMap { pub fn containing_module(&self, local_mod: LocalModuleId) -> Option { match self[local_mod].parent { Some(parent) => Some(self.module_id(parent)), - None => self.block.map(|block| block.parent), + None => { + self.block.map( + |BlockInfo { parent: BlockRelativeModuleId { block, local_id }, .. }| { + ModuleId { krate: self.krate, block, local_id } + }, + ) + } } } @@ -471,12 +493,12 @@ impl DefMap { let mut arc; let mut current_map = self; while let Some(block) = current_map.block { - go(&mut buf, db, current_map, "block scope", current_map.root); + go(&mut buf, db, current_map, "block scope", Self::ROOT); buf.push('\n'); - arc = block.parent.def_map(db); + arc = block.parent.def_map(db, self.krate); current_map = &arc; } - go(&mut buf, db, current_map, "crate", current_map.root); + go(&mut buf, db, current_map, "crate", Self::ROOT); return buf; fn go( @@ -506,7 +528,7 @@ impl DefMap { let mut current_map = self; while let Some(block) = current_map.block { format_to!(buf, "{:?} in {:?}\n", block.block, block.parent); - arc = block.parent.def_map(db); + arc = block.parent.def_map(db, self.krate); current_map = &arc; } @@ -534,7 +556,6 @@ impl DefMap { recursion_limit: _, krate: _, prelude: _, - root: _, rustc_coherence_is_core: _, no_core: _, no_std: _, diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 64caf26299..b431b6f647 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -71,7 +71,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T for dep in &krate.dependencies { tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); let dep_def_map = db.crate_def_map(dep.crate_id); - let dep_root = dep_def_map.module_id(dep_def_map.root); + let dep_root = dep_def_map.module_id(DefMap::ROOT); deps.insert(dep.as_name(), dep_root); @@ -287,7 +287,7 @@ impl DefCollector<'_> { let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; let item_tree = self.db.file_item_tree(file_id.into()); - let module_id = self.def_map.root; + let module_id = DefMap::ROOT; let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); @@ -382,7 +382,7 @@ impl DefCollector<'_> { fn seed_with_inner(&mut self, tree_id: TreeId) { let item_tree = tree_id.item_tree(self.db); - let module_id = self.def_map.root; + let module_id = DefMap::ROOT; let is_cfg_enabled = item_tree .top_level_attrs(self.db, self.def_map.krate) @@ -464,7 +464,7 @@ impl DefCollector<'_> { // Additionally, while the proc macro entry points must be `pub`, they are not publicly // exported in type/value namespace. This function reduces the visibility of all items // in the crate root that aren't proc macros. - let root = self.def_map.root; + let root = DefMap::ROOT; let module_id = self.def_map.module_id(root); let root = &mut self.def_map.modules[root]; root.scope.censor_non_proc_macros(module_id); @@ -560,13 +560,8 @@ impl DefCollector<'_> { }; let path = ModPath::from_segments(path_kind, [krate, name![prelude], edition]); - let (per_ns, _) = self.def_map.resolve_path( - self.db, - self.def_map.root, - &path, - BuiltinShadowMode::Other, - None, - ); + let (per_ns, _) = + self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None); match per_ns.types { Some((ModuleDefId::ModuleId(m), _)) => { @@ -661,7 +656,7 @@ impl DefCollector<'_> { // In Rust, `#[macro_export]` macros are unconditionally visible at the // crate root, even if the parent modules is **not** visible. if export { - let module_id = self.def_map.root; + let module_id = DefMap::ROOT; self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, @@ -712,7 +707,7 @@ impl DefCollector<'_> { /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped. /// And unconditionally exported. fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) { - let module_id = self.def_map.root; + let module_id = DefMap::ROOT; self.def_map.modules[module_id].scope.declare(macro_.into()); self.update( module_id, @@ -732,7 +727,7 @@ impl DefCollector<'_> { let def_map = self.db.crate_def_map(krate); // `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!` // macros. - let root_scope = &def_map[def_map.root].scope; + let root_scope = &def_map[DefMap::ROOT].scope; if let Some(names) = names { for name in names { // FIXME: Report diagnostic on 404. @@ -834,9 +829,9 @@ impl DefCollector<'_> { let root = match self.def_map.block { Some(_) => { let def_map = self.def_map.crate_root(self.db).def_map(self.db); - def_map.module_id(def_map.root()) + def_map.module_id(DefMap::ROOT) } - None => self.def_map.module_id(self.def_map.root()), + None => self.def_map.module_id(DefMap::ROOT), }; Some(root) } else { @@ -879,7 +874,7 @@ impl DefCollector<'_> { // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 if import.is_extern_crate && self.def_map.block.is_none() - && module_id == self.def_map.root + && module_id == DefMap::ROOT { if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name) { @@ -1525,7 +1520,7 @@ impl ModCollector<'_, '_> { fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { let krate = self.def_collector.def_map.krate; - let is_crate_root = self.module_id == self.def_collector.def_map.root; + let is_crate_root = self.module_id == DefMap::ROOT; // Note: don't assert that inserted value is fresh: it's simply not true // for macros. @@ -1641,9 +1636,9 @@ impl ModCollector<'_, '_> { FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db); let vis = resolve_vis(def_map, &self.item_tree[it.visibility]); - if self.def_collector.is_proc_macro && self.module_id == def_map.root { + if self.def_collector.is_proc_macro && self.module_id == DefMap::ROOT { if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) { - let crate_root = def_map.module_id(def_map.root); + let crate_root = def_map.module_id(DefMap::ROOT); self.def_collector.export_proc_macro( proc_macro, ItemTreeId::new(self.tree_id, id), diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 24dc4e243b..751536db38 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -121,7 +121,7 @@ impl DefMap { // ...unless we're resolving visibility for an associated item in an impl. if self.block_id() != m.block && !within_impl { cov_mark::hit!(adjust_vis_in_block_def_map); - vis = Visibility::Module(self.module_id(self.root())); + vis = Visibility::Module(self.module_id(Self::ROOT)); tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis); } } @@ -173,7 +173,7 @@ impl DefMap { match ¤t_map.block { Some(block) => { original_module = block.parent.local_id; - arc = block.parent.def_map(db); + arc = block.parent.def_map(db, current_map.krate); current_map = &*arc; } None => return result, @@ -207,7 +207,7 @@ impl DefMap { PerNs::types(self.crate_root(db).into(), Visibility::Public) } else { let def_map = db.crate_def_map(krate); - let module = def_map.module_id(def_map.root); + let module = def_map.module_id(Self::ROOT); cov_mark::hit!(macro_dollar_crate_other); PerNs::types(module.into(), Visibility::Public) } @@ -268,14 +268,17 @@ impl DefMap { path.display(db.upcast()), new_path.display(db.upcast()) ); - return block.parent.def_map(db).resolve_path_fp_with_macro( - db, - mode, - block.parent.local_id, - &new_path, - shadow, - expected_macro_subns, - ); + return block + .parent + .def_map(db, self.krate) + .resolve_path_fp_with_macro( + db, + mode, + block.parent.local_id, + &new_path, + shadow, + expected_macro_subns, + ); } None => { tracing::debug!("super path in root module"); @@ -476,9 +479,9 @@ impl DefMap { let from_crate_root = match self.block { Some(_) => { let def_map = self.crate_root(db).def_map(db); - def_map[def_map.root].scope.get(name) + def_map[Self::ROOT].scope.get(name) } - None => self[self.root].scope.get(name), + None => self[Self::ROOT].scope.get(name), }; let from_extern_prelude = || { self.resolve_name_in_extern_prelude(db, name) diff --git a/crates/hir-def/src/nameres/tests/macros.rs b/crates/hir-def/src/nameres/tests/macros.rs index 57f0233607..ae509de056 100644 --- a/crates/hir-def/src/nameres/tests/macros.rs +++ b/crates/hir-def/src/nameres/tests/macros.rs @@ -750,7 +750,7 @@ macro_rules! foo { pub use core::clone::Clone; "#, ); - assert_eq!(map.modules[map.root].scope.impls().len(), 1); + assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1); } #[test] @@ -772,7 +772,7 @@ pub macro Copy {} pub macro Clone {} "#, ); - assert_eq!(map.modules[map.root].scope.impls().len(), 2); + assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 2); } #[test] @@ -815,7 +815,7 @@ pub macro derive($item:item) {} pub macro Clone {} "#, ); - assert_eq!(map.modules[map.root].scope.impls().len(), 1); + assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1); } #[test] @@ -1286,7 +1286,7 @@ fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } let krate = db.crate_graph().iter().next().unwrap(); let def_map = db.crate_def_map(krate); - let root_module = &def_map[def_map.root()].scope; + let root_module = &def_map[DefMap::ROOT].scope; assert!( root_module.legacy_macros().count() == 0, "`#[macro_use]` shouldn't bring macros into textual macro scope", @@ -1392,7 +1392,7 @@ macro_rules! derive { () => {} } struct S; "#, ); - assert_eq!(map.modules[map.root].scope.impls().len(), 1); + assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1); } #[test] diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 3eaff61b15..06f5b2526a 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -586,8 +586,9 @@ impl Resolver { })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = db.block_def_map(block); - let root = def_map.root(); - resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, module_id: root })); + resolver + .scopes + .push(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT })); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the // innermost module scope instead? @@ -753,8 +754,7 @@ fn resolver_for_scope_( for scope in scope_chain.into_iter().rev() { if let Some(block) = scopes.block(scope) { let def_map = db.block_def_map(block); - let root = def_map.root(); - r = r.push_block_scope(def_map, root); + r = r.push_block_scope(def_map, DefMap::ROOT); // FIXME: This adds as many module scopes as there are blocks, but resolving in each // already traverses all parents, so this is O(n²). I think we could only store the // innermost module scope instead? diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs index d4b4031364..a6befc8a81 100644 --- a/crates/hir-def/src/test_db.rs +++ b/crates/hir-def/src/test_db.rs @@ -110,7 +110,7 @@ impl TestDB { } _ => { // FIXME: handle `mod` inside block expression - return def_map.module_id(def_map.root()); + return def_map.module_id(DefMap::ROOT); } } } @@ -119,7 +119,7 @@ impl TestDB { /// Finds the smallest/innermost module in `def_map` containing `position`. fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId { let mut size = None; - let mut res = def_map.root(); + let mut res = DefMap::ROOT; for (module, data) in def_map.modules() { let src = data.definition_source(self); if src.file_id != position.file_id.into() { diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 058d5059b1..32f50cb051 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -13,6 +13,7 @@ use hir_def::{ generics::{TypeOrConstParamData, TypeParamProvenance}, item_scope::ItemInNs, lang_item::{LangItem, LangItemTarget}, + nameres::DefMap, path::{Path, PathKind}, type_ref::{TraitBoundModifier, TypeBound, TypeRef}, visibility::Visibility, @@ -1488,7 +1489,7 @@ pub fn write_visibility( Visibility::Public => write!(f, "pub "), Visibility::Module(vis_id) => { let def_map = module_id.def_map(f.db.upcast()); - let root_module_id = def_map.module_id(def_map.root()); + let root_module_id = def_map.module_id(DefMap::ROOT); if vis_id == module_id { // pub(self) or omitted Ok(()) diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 0c8793c6df..9a2090ab79 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -548,7 +548,7 @@ impl HirDisplay for Module { // FIXME: Module doesn't have visibility saved in data. match self.name(f.db) { Some(name) => write!(f, "mod {}", name.display(f.db.upcast())), - None if self.is_crate_root(f.db) => match self.krate(f.db).display_name(f.db) { + None if self.is_crate_root() => match self.krate(f.db).display_name(f.db) { Some(name) => write!(f, "extern crate {name}"), None => f.write_str("extern crate {unknown}"), }, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 7c432197a6..19709bb44a 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -118,7 +118,7 @@ pub use { find_path::PrefixKind, import_map, lang_item::LangItem, - nameres::ModuleSource, + nameres::{DefMap, ModuleSource}, path::{ModPath, PathKind}, type_ref::{Mutability, TypeRef}, visibility::Visibility, @@ -202,7 +202,7 @@ impl Crate { pub fn root_module(self, db: &dyn HirDatabase) -> Module { let def_map = db.crate_def_map(self.id); - Module { id: def_map.module_id(def_map.root()) } + Module { id: def_map.module_id(DefMap::ROOT) } } pub fn modules(self, db: &dyn HirDatabase) -> Vec { @@ -475,12 +475,11 @@ impl Module { /// in the module tree of any target in `Cargo.toml`. pub fn crate_root(self, db: &dyn HirDatabase) -> Module { let def_map = db.crate_def_map(self.id.krate()); - Module { id: def_map.module_id(def_map.root()) } + Module { id: def_map.module_id(DefMap::ROOT) } } - pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool { - let def_map = db.crate_def_map(self.id.krate()); - def_map.root() == self.id.local_id + pub fn is_crate_root(self) -> bool { + DefMap::ROOT == self.id.local_id } /// Iterates over all child modules. diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index d53e9e2fa9..480cb77b4f 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -158,7 +158,7 @@ impl Completions { path_ctx: &PathCompletionCtx, ) { ctx.process_all_names(&mut |name, res, doc_aliases| match res { - ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => { + ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => { self.add_module(ctx, path_ctx, m, name, doc_aliases); } _ => (), diff --git a/crates/ide-db/src/helpers.rs b/crates/ide-db/src/helpers.rs index 8e3b1eef15..eba9d8afc4 100644 --- a/crates/ide-db/src/helpers.rs +++ b/crates/ide-db/src/helpers.rs @@ -77,7 +77,7 @@ pub fn visit_file_defs( } module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into())); - let is_root = module.is_crate_root(db); + let is_root = module.is_crate_root(); module .legacy_macros(db) .into_iter() diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs index 5b2558ea8f..52a23b4b8f 100644 --- a/crates/ide-db/src/rename.rs +++ b/crates/ide-db/src/rename.rs @@ -178,7 +178,7 @@ fn rename_mod( let mut source_change = SourceChange::default(); - if module.is_crate_root(sema.db) { + if module.is_crate_root() { return Ok(source_change); } diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index 9d00c71709..73cd5dcaf2 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -225,7 +225,7 @@ impl Definition { // def is crate root // FIXME: We don't do searches for crates currently, as a crate does not actually have a single name if let &Definition::Module(module) = self { - if module.is_crate_root(db) { + if module.is_crate_root() { return SearchScope::reverse_dependencies(db, module.krate()); } } @@ -392,7 +392,7 @@ impl<'a> FindUsages<'a> { let name = match self.def { // special case crate modules as these do not have a proper name - Definition::Module(module) if module.is_crate_root(self.sema.db) => { + Definition::Module(module) if module.is_crate_root() => { // FIXME: This assumes the crate name is always equal to its display name when it really isn't module .krate() @@ -500,7 +500,7 @@ impl<'a> FindUsages<'a> { let scope = search_scope.intersection(&SearchScope::module_and_children(self.sema.db, module)); - let is_crate_root = module.is_crate_root(self.sema.db).then(|| Finder::new("crate")); + let is_crate_root = module.is_crate_root().then(|| Finder::new("crate")); let finder = &Finder::new("super"); for (text, file_id, search_range) in scope_files(sema, &scope) { diff --git a/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/crates/ide-diagnostics/src/handlers/unlinked_file.rs index b9c5384ea1..271e7ce73b 100644 --- a/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -2,7 +2,7 @@ use std::iter; -use hir::{db::DefDatabase, InFile, ModuleSource}; +use hir::{db::DefDatabase, DefMap, InFile, ModuleSource}; use ide_db::{ base_db::{FileId, FileLoader, SourceDatabase, SourceDatabaseExt}, source_change::SourceChange, @@ -74,7 +74,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option> { 'crates: for &krate in &*ctx.sema.db.relevant_crates(file_id) { let crate_def_map = ctx.sema.db.crate_def_map(krate); - let root_module = &crate_def_map[crate_def_map.root()]; + let root_module = &crate_def_map[DefMap::ROOT]; let Some(root_file_id) = root_module.origin.file_id() else { continue }; let Some(crate_root_path) = source_root.path_for_file(&root_file_id) else { continue }; let Some(rel) = parent.strip_prefix(&crate_root_path.parent()?) else { continue }; diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs index 70bff41121..d2c77e2dc7 100644 --- a/crates/ide/src/status.rs +++ b/crates/ide/src/status.rs @@ -1,7 +1,7 @@ use std::{fmt, marker::PhantomData}; use hir::{ - db::{AstIdMapQuery, AttrsQuery, ParseMacroExpansionQuery}, + db::{AstIdMapQuery, AttrsQuery, BlockDefMapQuery, ParseMacroExpansionQuery}, Attr, Attrs, ExpandResult, MacroFile, Module, }; use ide_db::{ @@ -51,6 +51,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option) -> String { format_to!(buf, "\nDebug info:\n"); format_to!(buf, "{}\n", collect_query(AttrsQuery.in_db(db))); format_to!(buf, "{} ast id maps\n", collect_query_count(AstIdMapQuery.in_db(db))); + format_to!(buf, "{} block def maps\n", collect_query_count(BlockDefMapQuery.in_db(db))); if let Some(file_id) = file_id { format_to!(buf, "\nFile info:\n"); diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 925057ffaa..3c40246a69 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -340,7 +340,7 @@ fn highlight_def( Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)), Definition::Module(module) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); - if module.is_crate_root(db) { + if module.is_crate_root() { h |= HlMod::CrateRoot; } h diff --git a/lib/la-arena/src/lib.rs b/lib/la-arena/src/lib.rs index 1f8ef01a5b..5107f29439 100644 --- a/lib/la-arena/src/lib.rs +++ b/lib/la-arena/src/lib.rs @@ -18,6 +18,18 @@ pub use map::{ArenaMap, Entry, OccupiedEntry, VacantEntry}; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RawIdx(u32); +impl RawIdx { + /// Constructs a [`RawIdx`] from a u32. + pub const fn from_u32(u32: u32) -> Self { + RawIdx(u32) + } + + /// Deconstructs a [`RawIdx`] into the underlying u32. + pub const fn into_u32(self) -> u32 { + self.0 + } +} + impl From for u32 { #[inline] fn from(raw: RawIdx) -> u32 { @@ -94,12 +106,12 @@ impl fmt::Debug for Idx { impl Idx { /// Creates a new index from a [`RawIdx`]. - pub fn from_raw(raw: RawIdx) -> Self { + pub const fn from_raw(raw: RawIdx) -> Self { Idx { raw, _ty: PhantomData } } /// Converts this index into the underlying [`RawIdx`]. - pub fn into_raw(self) -> RawIdx { + pub const fn into_raw(self) -> RawIdx { self.raw } }