From cf178cba8f362013aaecf758be891da34f949717 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 13 Jun 2023 12:59:52 +0200 Subject: [PATCH] internal: Add a CrateRootModuleId that encodes a module id that is always a crate root --- crates/hir-def/src/find_path.rs | 4 +- crates/hir-def/src/item_tree.rs | 6 --- crates/hir-def/src/lib.rs | 45 +++++++++++++++++-- crates/hir-def/src/nameres.rs | 23 ++++++---- crates/hir-def/src/nameres/collector.rs | 58 ++++++++++--------------- crates/hir-def/src/resolver.rs | 19 +++++--- crates/hir-expand/src/ast_id_map.rs | 6 +-- crates/hir/src/lib.rs | 4 +- crates/rust-analyzer/src/main_loop.rs | 2 - 9 files changed, 102 insertions(+), 65 deletions(-) diff --git a/crates/hir-def/src/find_path.rs b/crates/hir-def/src/find_path.rs index e8cc2eab461..8c49ae1c4af 100644 --- a/crates/hir-def/src/find_path.rs +++ b/crates/hir-def/src/find_path.rs @@ -81,7 +81,7 @@ fn find_path_inner( } let def_map = from.def_map(db); - let crate_root = def_map.crate_root(); + let crate_root = def_map.crate_root().into(); // - if the item is a module, jump straight to module search if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item { let mut visited_modules = FxHashSet::default(); @@ -374,7 +374,7 @@ fn calculate_best_path( } } if let Some(module) = item.module(db) { - if module.def_map(db).block_id().is_some() && prefixed.is_some() { + if module.containing_block().is_some() && prefixed.is_some() { cov_mark::hit!(prefixed_in_block_expression); prefixed = Some(PrefixKind::Plain); } diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 590ed64af5d..e74b71888c2 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -101,7 +101,6 @@ pub struct ItemTree { top_level: SmallVec<[ModItem; 1]>, attrs: FxHashMap, - // FIXME: Remove this indirection, an item tree is almost always non-empty? data: Option>, } @@ -718,7 +717,6 @@ pub struct Mod { pub enum ModKind { /// `mod m { ... }` Inline { items: Box<[ModItem]> }, - /// `mod m;` Outline, } @@ -892,10 +890,6 @@ pub fn as_assoc_item(&self) -> Option { } } - pub fn downcast(self) -> Option> { - N::id_from_mod_item(self) - } - pub fn ast_id(&self, tree: &ItemTree) -> FileAstId { match self { ModItem::Import(it) => tree[it.index].ast_id().upcast(), diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 4f68093bcbe..b0ab9727c9d 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -97,6 +97,46 @@ macro_rules! eprintln { }, }; +/// A `ModuleId` that is always a crate's root module. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct CrateRootModuleId { + krate: CrateId, +} + +impl CrateRootModuleId { + pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc { + db.crate_def_map(self.krate) + } + + pub fn krate(self) -> CrateId { + self.krate + } +} + +impl From for ModuleId { + fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self { + ModuleId { krate, block: None, local_id: DefMap::ROOT } + } +} + +impl From for ModuleDefId { + fn from(value: CrateRootModuleId) -> Self { + ModuleDefId::ModuleId(value.into()) + } +} + +impl TryFrom for CrateRootModuleId { + type Error = (); + + fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result { + if block.is_none() && local_id == DefMap::ROOT { + Ok(CrateRootModuleId { krate }) + } else { + Err(()) + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ModuleId { krate: CrateId, @@ -318,8 +358,7 @@ pub struct MacroRulesLoc { pub struct ProcMacroId(salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ProcMacroLoc { - // FIXME: this should be a crate? or just a crate-root module - pub container: ModuleId, + pub container: CrateRootModuleId, pub id: ItemTreeId, pub expander: ProcMacroExpander, pub kind: ProcMacroKind, @@ -891,7 +930,7 @@ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match self { MacroId::MacroRulesId(it) => it.lookup(db).container, MacroId::Macro2Id(it) => it.lookup(db).container, - MacroId::ProcMacroId(it) => it.lookup(db).container, + MacroId::ProcMacroId(it) => it.lookup(db).container.into(), } } } diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 9b520bc3030..0ab1bd8490c 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -77,8 +77,8 @@ path::ModPath, per_ns::PerNs, visibility::Visibility, - AstId, BlockId, BlockLoc, FunctionId, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, - ProcMacroId, + AstId, BlockId, BlockLoc, CrateRootModuleId, FunctionId, LocalModuleId, Lookup, MacroExpander, + MacroId, ModuleId, ProcMacroId, }; /// Contains the results of (early) name resolution. @@ -93,7 +93,10 @@ #[derive(Debug, PartialEq, Eq)] pub struct DefMap { _c: Count, + /// When this is a block def map, this will hold the block id of the the block and module that + /// contains this block. block: Option, + /// The modules and their data declared in this crate. modules: Arena, krate: CrateId, /// The prelude module for this crate. This either comes from an import @@ -111,15 +114,18 @@ pub struct DefMap { /// attributes. derive_helpers_in_scope: FxHashMap, Vec<(Name, MacroId, MacroCallId)>>, + /// The diagnostics that need to be emitted for this crate. diagnostics: Vec, + /// The crate data that is shared between a crate's def map and all its block def maps. data: Arc, } /// Data that belongs to a crate which is shared between a crate's def map and all its block def maps. #[derive(Clone, Debug, PartialEq, Eq)] struct DefMapCrateData { - extern_prelude: FxHashMap, + /// The extern prelude which contains all root modules of external crates that are in scope. + extern_prelude: FxHashMap, /// Side table for resolving derive helpers. exported_derives: FxHashMap>, @@ -279,6 +285,7 @@ pub struct ModuleData { } impl DefMap { + /// The module id of a crate or block root. 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 { @@ -419,11 +426,11 @@ pub(crate) fn prelude(&self) -> Option { } pub(crate) fn extern_prelude(&self) -> impl Iterator + '_ { - self.data.extern_prelude.iter().map(|(name, def)| (name, *def)) + self.data.extern_prelude.iter().map(|(name, &def)| (name, def.into())) } pub(crate) fn macro_use_prelude(&self) -> impl Iterator + '_ { - self.macro_use_prelude.iter().map(|(name, def)| (name, *def)) + self.macro_use_prelude.iter().map(|(name, &def)| (name, def)) } pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { @@ -431,8 +438,8 @@ pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { ModuleId { krate: self.krate, local_id, block } } - pub(crate) fn crate_root(&self) -> ModuleId { - ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT } + pub fn crate_root(&self) -> CrateRootModuleId { + CrateRootModuleId { krate: self.krate } } pub(crate) fn resolve_path( @@ -476,7 +483,7 @@ pub(crate) fn resolve_path_locally( /// /// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns /// `None`, iteration continues. - pub fn with_ancestor_maps( + pub(crate) fn with_ancestor_maps( &self, db: &dyn DefDatabase, local_mod: LocalModuleId, diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 06542b4b1e9..97481ea7df7 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -51,11 +51,11 @@ per_ns::PerNs, tt, visibility::{RawVisibility, Visibility}, - AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionId, - FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc, - MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, - ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, - UnresolvedMacro, + AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId, + ExternBlockLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, + Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId, + ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, + TypeAliasLoc, UnionLoc, UnresolvedMacro, }; static GLOB_RECURSION_LIMIT: Limit = Limit::new(100); @@ -274,8 +274,6 @@ fn seed_with_top_level(&mut self) { 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 = DefMap::ROOT; - let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); @@ -285,10 +283,9 @@ fn seed_with_top_level(&mut self) { for (name, dep) in &self.deps { if dep.is_prelude() { - crate_data.extern_prelude.insert( - name.clone(), - ModuleId { krate: dep.crate_id, block: None, local_id: DefMap::ROOT }, - ); + crate_data + .extern_prelude + .insert(name.clone(), CrateRootModuleId { krate: dep.crate_id }); } } @@ -374,7 +371,7 @@ fn seed_with_top_level(&mut self) { ModCollector { def_collector: self, macro_depth: 0, - module_id, + module_id: DefMap::ROOT, tree_id: TreeId::new(file_id.into(), None), item_tree: &item_tree, mod_dir: ModDir::root(), @@ -384,8 +381,6 @@ fn seed_with_top_level(&mut self) { fn seed_with_inner(&mut self, tree_id: TreeId) { let item_tree = tree_id.item_tree(self.db); - let module_id = DefMap::ROOT; - let is_cfg_enabled = item_tree .top_level_attrs(self.db, self.def_map.krate) .cfg() @@ -394,7 +389,7 @@ fn seed_with_inner(&mut self, tree_id: TreeId) { ModCollector { def_collector: self, macro_depth: 0, - module_id, + module_id: DefMap::ROOT, tree_id, item_tree: &item_tree, mod_dir: ModDir::root(), @@ -604,8 +599,6 @@ fn export_proc_macro( if self.def_map.block.is_some() { return; } - let crate_root = self.def_map.module_id(DefMap::ROOT); - let kind = def.kind.to_basedb_kind(); let (expander, kind) = match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) { @@ -614,7 +607,8 @@ fn export_proc_macro( }; let proc_macro_id = - ProcMacroLoc { container: crate_root, id, expander, kind }.intern(self.db); + ProcMacroLoc { container: self.def_map.crate_root(), id, expander, kind } + .intern(self.db); self.define_proc_macro(def.name.clone(), proc_macro_id); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); if let ProcMacroKind::CustomDerive { helpers } = def.kind { @@ -831,16 +825,12 @@ fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialRe } } - fn resolve_extern_crate(&self, name: &Name) -> Option { + fn resolve_extern_crate(&self, name: &Name) -> Option { if *name == name!(self) { cov_mark::hit!(extern_crate_self_as); Some(self.def_map.crate_root()) } else { - self.deps.get(name).map(|dep| ModuleId { - krate: dep.crate_id, - block: None, - local_id: DefMap::ROOT, - }) + self.deps.get(name).map(|dep| CrateRootModuleId { krate: dep.crate_id }) } } @@ -883,10 +873,12 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) { { if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name) { - Arc::get_mut(&mut self.def_map.data) - .unwrap() - .extern_prelude - .insert(name.clone(), def); + if let Ok(def) = def.try_into() { + Arc::get_mut(&mut self.def_map.data) + .unwrap() + .extern_prelude + .insert(name.clone(), def); + } } } @@ -1791,13 +1783,11 @@ fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId { - if m == self.def_collector.def_map.module_id(self.module_id) { - cov_mark::hit!(ignore_macro_use_extern_crate_self); - return; - } - m.krate + Some(m) if m.krate == self.def_collector.def_map.krate => { + cov_mark::hit!(ignore_macro_use_extern_crate_self); + return; } + Some(m) => m.krate, None => return, }; diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 880a76f2b85..edfa905e34c 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -21,11 +21,11 @@ path::{ModPath, Path, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, - AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, - FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, - LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, - StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, - TypeParamId, VariantId, + AdtId, AssocItemId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, + EnumVariantId, ExternBlockId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, + ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, + ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, + TypeOrConstParamId, TypeOwnerId, TypeParamId, VariantId, }; #[derive(Debug, Clone)] @@ -946,6 +946,15 @@ fn resolver(self, db: &dyn DefDatabase) -> Resolver { } } +impl HasResolver for CrateRootModuleId { + fn resolver(self, db: &dyn DefDatabase) -> Resolver { + Resolver { + scopes: vec![], + module_scope: ModuleItemMap { def_map: self.def_map(db), module_id: DefMap::ROOT }, + } + } +} + impl HasResolver for TraitId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) diff --git a/crates/hir-expand/src/ast_id_map.rs b/crates/hir-expand/src/ast_id_map.rs index 02efaace437..c2b0d5985e3 100644 --- a/crates/hir-expand/src/ast_id_map.rs +++ b/crates/hir-expand/src/ast_id_map.rs @@ -20,7 +20,7 @@ /// `AstId` points to an AST node in a specific file. pub struct FileAstId { raw: ErasedFileAstId, - _ty: PhantomData N>, + covariant: PhantomData N>, } impl Clone for FileAstId { @@ -54,7 +54,7 @@ pub fn upcast(self) -> FileAstId where N: Into, { - FileAstId { raw: self.raw, _ty: PhantomData } + FileAstId { raw: self.raw, covariant: PhantomData } } } @@ -122,7 +122,7 @@ pub(crate) fn from_source(node: &SyntaxNode) -> AstIdMap { pub fn ast_id(&self, item: &N) -> FileAstId { let raw = self.erased_ast_id(item.syntax()); - FileAstId { raw, _ty: PhantomData } + FileAstId { raw, covariant: PhantomData } } pub fn get(&self, id: FileAstId) -> AstPtr { diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index cf7d7f6c4f8..12b3c0a69b1 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -203,7 +203,7 @@ pub fn transitive_reverse_dependencies( pub fn root_module(self, db: &dyn HirDatabase) -> Module { let def_map = db.crate_def_map(self.id); - Module { id: def_map.module_id(DefMap::ROOT) } + Module { id: def_map.crate_root().into() } } pub fn modules(self, db: &dyn HirDatabase) -> Vec { @@ -476,7 +476,7 @@ pub fn krate(self) -> Crate { /// 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(DefMap::ROOT) } + Module { id: def_map.crate_root().into() } } pub fn is_crate_root(self) -> bool { diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index eb5d7f495f7..be89def2a74 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -549,7 +549,6 @@ fn handle_vfs_msg(&mut self, message: vfs::loader::Message) { self.vfs_progress_n_total = n_total; self.vfs_progress_n_done = n_done; - // if n_total != 0 { let state = if n_done == 0 { Progress::Begin } else if n_done < n_total { @@ -565,7 +564,6 @@ fn handle_vfs_msg(&mut self, message: vfs::loader::Message) { Some(Progress::fraction(n_done, n_total)), None, ); - // } } } }