Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15053 - Veykril:crate-root-module-id, r=Veykril
internal: Add a CrateRootModuleId that encodes a module id that is always a crate root
bors 2023-06-14
parent 51939db · parent cf178cb · commit 9c967d3
-rw-r--r--crates/hir-def/src/find_path.rs4
-rw-r--r--crates/hir-def/src/item_tree.rs6
-rw-r--r--crates/hir-def/src/lib.rs45
-rw-r--r--crates/hir-def/src/nameres.rs23
-rw-r--r--crates/hir-def/src/nameres/collector.rs58
-rw-r--r--crates/hir-def/src/resolver.rs19
-rw-r--r--crates/hir-expand/src/ast_id_map.rs6
-rw-r--r--crates/hir/src/lib.rs4
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
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 e8cc2eab46..8c49ae1c4a 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 590ed64af5..e74b71888c 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<AttrOwner, RawAttrs>,
- // FIXME: Remove this indirection, an item tree is almost always non-empty?
data: Option<Box<ItemTreeData>>,
}
@@ -718,7 +717,6 @@ pub struct Mod {
pub enum ModKind {
/// `mod m { ... }`
Inline { items: Box<[ModItem]> },
-
/// `mod m;`
Outline,
}
@@ -892,10 +890,6 @@ impl ModItem {
}
}
- pub fn downcast<N: ItemTreeNode>(self) -> Option<FileItemTreeId<N>> {
- N::id_from_mod_item(self)
- }
-
pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
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 4d76484394..9d8b57a0da 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -93,6 +93,46 @@ use crate::{
},
};
+/// 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<DefMap> {
+ db.crate_def_map(self.krate)
+ }
+
+ pub fn krate(self) -> CrateId {
+ self.krate
+ }
+}
+
+impl From<CrateRootModuleId> for ModuleId {
+ fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
+ ModuleId { krate, block: None, local_id: DefMap::ROOT }
+ }
+}
+
+impl From<CrateRootModuleId> for ModuleDefId {
+ fn from(value: CrateRootModuleId) -> Self {
+ ModuleDefId::ModuleId(value.into())
+ }
+}
+
+impl TryFrom<ModuleId> for CrateRootModuleId {
+ type Error = ();
+
+ fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
+ 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,
@@ -314,8 +354,7 @@ impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macr
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<Function>,
pub expander: ProcMacroExpander,
pub kind: ProcMacroKind,
@@ -903,7 +942,7 @@ impl HasModule for MacroId {
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 9b520bc303..0ab1bd8490 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -77,8 +77,8 @@ use crate::{
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 @@ use crate::{
#[derive(Debug, PartialEq, Eq)]
pub struct DefMap {
_c: Count<Self>,
+ /// 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<BlockInfo>,
+ /// The modules and their data declared in this crate.
modules: Arena<ModuleData>,
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<AstId<ast::Item>, Vec<(Name, MacroId, MacroCallId)>>,
+ /// The diagnostics that need to be emitted for this crate.
diagnostics: Vec<DefDiagnostic>,
+ /// The crate data that is shared between a crate's def map and all its block def maps.
data: Arc<DefMapCrateData>,
}
/// 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<Name, ModuleId>,
+ /// The extern prelude which contains all root modules of external crates that are in scope.
+ extern_prelude: FxHashMap<Name, CrateRootModuleId>,
/// Side table for resolving derive helpers.
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
@@ -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<DefMap> {
@@ -419,11 +426,11 @@ impl DefMap {
}
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
- 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<Item = (&Name, MacroId)> + '_ {
- 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 @@ impl DefMap {
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 @@ impl DefMap {
///
/// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns
/// `None`, iteration continues.
- pub fn with_ancestor_maps<T>(
+ pub(crate) fn with_ancestor_maps<T>(
&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 06542b4b1e..97481ea7df 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -51,11 +51,11 @@ use crate::{
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 @@ 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 = 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 @@ impl DefCollector<'_> {
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 @@ impl DefCollector<'_> {
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 @@ impl DefCollector<'_> {
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 @@ impl DefCollector<'_> {
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 @@ impl DefCollector<'_> {
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 @@ impl DefCollector<'_> {
};
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 @@ impl DefCollector<'_> {
}
}
- fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
+ fn resolve_extern_crate(&self, name: &Name) -> Option<CrateRootModuleId> {
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 @@ impl DefCollector<'_> {
{
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 @@ impl ModCollector<'_, '_> {
let target_crate =
match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
- Some(m) => {
- 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 c497c09aff..0d6f55411c 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -21,11 +21,11 @@ use crate::{
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 @@ impl HasResolver for ModuleId {
}
}
+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 02efaace43..c2b0d5985e 100644
--- a/crates/hir-expand/src/ast_id_map.rs
+++ b/crates/hir-expand/src/ast_id_map.rs
@@ -20,7 +20,7 @@ use syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
/// `AstId` points to an AST node in a specific file.
pub struct FileAstId<N: AstNode> {
raw: ErasedFileAstId,
- _ty: PhantomData<fn() -> N>,
+ covariant: PhantomData<fn() -> N>,
}
impl<N: AstNode> Clone for FileAstId<N> {
@@ -54,7 +54,7 @@ impl<N: AstNode> FileAstId<N> {
where
N: Into<M>,
{
- FileAstId { raw: self.raw, _ty: PhantomData }
+ FileAstId { raw: self.raw, covariant: PhantomData }
}
}
@@ -122,7 +122,7 @@ impl AstIdMap {
pub fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> {
let raw = self.erased_ast_id(item.syntax());
- FileAstId { raw, _ty: PhantomData }
+ FileAstId { raw, covariant: PhantomData }
}
pub fn get<N: AstNode>(&self, id: FileAstId<N>) -> AstPtr<N> {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 17c491e436..9876503d03 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -203,7 +203,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(DefMap::ROOT) }
+ Module { id: def_map.crate_root().into() }
}
pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> {
@@ -476,7 +476,7 @@ 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(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 40ab658eea..c70f60513b 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -554,7 +554,6 @@ impl GlobalState {
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 {
@@ -570,7 +569,6 @@ impl GlobalState {
Some(Progress::fraction(n_done, n_total)),
None,
);
- // }
}
}
}