Skip to content

Commit 9c967d3

Browse files
committed
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
2 parents 51939db + cf178cb commit 9c967d3

File tree

9 files changed

+102
-65
lines changed

9 files changed

+102
-65
lines changed

crates/hir-def/src/find_path.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ fn find_path_inner(
8181
}
8282

8383
let def_map = from.def_map(db);
84-
let crate_root = def_map.crate_root();
84+
let crate_root = def_map.crate_root().into();
8585
// - if the item is a module, jump straight to module search
8686
if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
8787
let mut visited_modules = FxHashSet::default();
@@ -374,7 +374,7 @@ fn calculate_best_path(
374374
}
375375
}
376376
if let Some(module) = item.module(db) {
377-
if module.def_map(db).block_id().is_some() && prefixed.is_some() {
377+
if module.containing_block().is_some() && prefixed.is_some() {
378378
cov_mark::hit!(prefixed_in_block_expression);
379379
prefixed = Some(PrefixKind::Plain);
380380
}

crates/hir-def/src/item_tree.rs

-6
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ pub struct ItemTree {
101101
top_level: SmallVec<[ModItem; 1]>,
102102
attrs: FxHashMap<AttrOwner, RawAttrs>,
103103

104-
// FIXME: Remove this indirection, an item tree is almost always non-empty?
105104
data: Option<Box<ItemTreeData>>,
106105
}
107106

@@ -718,7 +717,6 @@ pub struct Mod {
718717
pub enum ModKind {
719718
/// `mod m { ... }`
720719
Inline { items: Box<[ModItem]> },
721-
722720
/// `mod m;`
723721
Outline,
724722
}
@@ -892,10 +890,6 @@ impl ModItem {
892890
}
893891
}
894892

895-
pub fn downcast<N: ItemTreeNode>(self) -> Option<FileItemTreeId<N>> {
896-
N::id_from_mod_item(self)
897-
}
898-
899893
pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
900894
match self {
901895
ModItem::Import(it) => tree[it.index].ast_id().upcast(),

crates/hir-def/src/lib.rs

+42-3
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,46 @@ use crate::{
9393
},
9494
};
9595

96+
/// A `ModuleId` that is always a crate's root module.
97+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
98+
pub struct CrateRootModuleId {
99+
krate: CrateId,
100+
}
101+
102+
impl CrateRootModuleId {
103+
pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
104+
db.crate_def_map(self.krate)
105+
}
106+
107+
pub fn krate(self) -> CrateId {
108+
self.krate
109+
}
110+
}
111+
112+
impl From<CrateRootModuleId> for ModuleId {
113+
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
114+
ModuleId { krate, block: None, local_id: DefMap::ROOT }
115+
}
116+
}
117+
118+
impl From<CrateRootModuleId> for ModuleDefId {
119+
fn from(value: CrateRootModuleId) -> Self {
120+
ModuleDefId::ModuleId(value.into())
121+
}
122+
}
123+
124+
impl TryFrom<ModuleId> for CrateRootModuleId {
125+
type Error = ();
126+
127+
fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
128+
if block.is_none() && local_id == DefMap::ROOT {
129+
Ok(CrateRootModuleId { krate })
130+
} else {
131+
Err(())
132+
}
133+
}
134+
}
135+
96136
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97137
pub struct ModuleId {
98138
krate: CrateId,
@@ -314,8 +354,7 @@ impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macr
314354
pub struct ProcMacroId(salsa::InternId);
315355
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
316356
pub struct ProcMacroLoc {
317-
// FIXME: this should be a crate? or just a crate-root module
318-
pub container: ModuleId,
357+
pub container: CrateRootModuleId,
319358
pub id: ItemTreeId<Function>,
320359
pub expander: ProcMacroExpander,
321360
pub kind: ProcMacroKind,
@@ -903,7 +942,7 @@ impl HasModule for MacroId {
903942
match self {
904943
MacroId::MacroRulesId(it) => it.lookup(db).container,
905944
MacroId::Macro2Id(it) => it.lookup(db).container,
906-
MacroId::ProcMacroId(it) => it.lookup(db).container,
945+
MacroId::ProcMacroId(it) => it.lookup(db).container.into(),
907946
}
908947
}
909948
}

crates/hir-def/src/nameres.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ use crate::{
7777
path::ModPath,
7878
per_ns::PerNs,
7979
visibility::Visibility,
80-
AstId, BlockId, BlockLoc, FunctionId, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId,
81-
ProcMacroId,
80+
AstId, BlockId, BlockLoc, CrateRootModuleId, FunctionId, LocalModuleId, Lookup, MacroExpander,
81+
MacroId, ModuleId, ProcMacroId,
8282
};
8383

8484
/// Contains the results of (early) name resolution.
@@ -93,7 +93,10 @@ use crate::{
9393
#[derive(Debug, PartialEq, Eq)]
9494
pub struct DefMap {
9595
_c: Count<Self>,
96+
/// When this is a block def map, this will hold the block id of the the block and module that
97+
/// contains this block.
9698
block: Option<BlockInfo>,
99+
/// The modules and their data declared in this crate.
97100
modules: Arena<ModuleData>,
98101
krate: CrateId,
99102
/// The prelude module for this crate. This either comes from an import
@@ -111,15 +114,18 @@ pub struct DefMap {
111114
/// attributes.
112115
derive_helpers_in_scope: FxHashMap<AstId<ast::Item>, Vec<(Name, MacroId, MacroCallId)>>,
113116

117+
/// The diagnostics that need to be emitted for this crate.
114118
diagnostics: Vec<DefDiagnostic>,
115119

120+
/// The crate data that is shared between a crate's def map and all its block def maps.
116121
data: Arc<DefMapCrateData>,
117122
}
118123

119124
/// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
120125
#[derive(Clone, Debug, PartialEq, Eq)]
121126
struct DefMapCrateData {
122-
extern_prelude: FxHashMap<Name, ModuleId>,
127+
/// The extern prelude which contains all root modules of external crates that are in scope.
128+
extern_prelude: FxHashMap<Name, CrateRootModuleId>,
123129

124130
/// Side table for resolving derive helpers.
125131
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
@@ -279,6 +285,7 @@ pub struct ModuleData {
279285
}
280286

281287
impl DefMap {
288+
/// The module id of a crate or block root.
282289
pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0));
283290

284291
pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
@@ -419,20 +426,20 @@ impl DefMap {
419426
}
420427

421428
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
422-
self.data.extern_prelude.iter().map(|(name, def)| (name, *def))
429+
self.data.extern_prelude.iter().map(|(name, &def)| (name, def.into()))
423430
}
424431

425432
pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
426-
self.macro_use_prelude.iter().map(|(name, def)| (name, *def))
433+
self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
427434
}
428435

429436
pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId {
430437
let block = self.block.map(|b| b.block);
431438
ModuleId { krate: self.krate, local_id, block }
432439
}
433440

434-
pub(crate) fn crate_root(&self) -> ModuleId {
435-
ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
441+
pub fn crate_root(&self) -> CrateRootModuleId {
442+
CrateRootModuleId { krate: self.krate }
436443
}
437444

438445
pub(crate) fn resolve_path(
@@ -476,7 +483,7 @@ impl DefMap {
476483
///
477484
/// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns
478485
/// `None`, iteration continues.
479-
pub fn with_ancestor_maps<T>(
486+
pub(crate) fn with_ancestor_maps<T>(
480487
&self,
481488
db: &dyn DefDatabase,
482489
local_mod: LocalModuleId,

crates/hir-def/src/nameres/collector.rs

+24-34
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ use crate::{
5151
per_ns::PerNs,
5252
tt,
5353
visibility::{RawVisibility, Visibility},
54-
AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionId,
55-
FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc,
56-
MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId,
57-
ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc,
58-
UnresolvedMacro,
54+
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
55+
ExternBlockLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId,
56+
Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId,
57+
ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc,
58+
TypeAliasLoc, UnionLoc, UnresolvedMacro,
5959
};
6060

6161
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
@@ -274,8 +274,6 @@ impl DefCollector<'_> {
274274

275275
let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
276276
let item_tree = self.db.file_item_tree(file_id.into());
277-
let module_id = DefMap::ROOT;
278-
279277
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
280278
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
281279

@@ -285,10 +283,9 @@ impl DefCollector<'_> {
285283

286284
for (name, dep) in &self.deps {
287285
if dep.is_prelude() {
288-
crate_data.extern_prelude.insert(
289-
name.clone(),
290-
ModuleId { krate: dep.crate_id, block: None, local_id: DefMap::ROOT },
291-
);
286+
crate_data
287+
.extern_prelude
288+
.insert(name.clone(), CrateRootModuleId { krate: dep.crate_id });
292289
}
293290
}
294291

@@ -374,7 +371,7 @@ impl DefCollector<'_> {
374371
ModCollector {
375372
def_collector: self,
376373
macro_depth: 0,
377-
module_id,
374+
module_id: DefMap::ROOT,
378375
tree_id: TreeId::new(file_id.into(), None),
379376
item_tree: &item_tree,
380377
mod_dir: ModDir::root(),
@@ -384,8 +381,6 @@ impl DefCollector<'_> {
384381

385382
fn seed_with_inner(&mut self, tree_id: TreeId) {
386383
let item_tree = tree_id.item_tree(self.db);
387-
let module_id = DefMap::ROOT;
388-
389384
let is_cfg_enabled = item_tree
390385
.top_level_attrs(self.db, self.def_map.krate)
391386
.cfg()
@@ -394,7 +389,7 @@ impl DefCollector<'_> {
394389
ModCollector {
395390
def_collector: self,
396391
macro_depth: 0,
397-
module_id,
392+
module_id: DefMap::ROOT,
398393
tree_id,
399394
item_tree: &item_tree,
400395
mod_dir: ModDir::root(),
@@ -604,8 +599,6 @@ impl DefCollector<'_> {
604599
if self.def_map.block.is_some() {
605600
return;
606601
}
607-
let crate_root = self.def_map.module_id(DefMap::ROOT);
608-
609602
let kind = def.kind.to_basedb_kind();
610603
let (expander, kind) =
611604
match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) {
@@ -614,7 +607,8 @@ impl DefCollector<'_> {
614607
};
615608

616609
let proc_macro_id =
617-
ProcMacroLoc { container: crate_root, id, expander, kind }.intern(self.db);
610+
ProcMacroLoc { container: self.def_map.crate_root(), id, expander, kind }
611+
.intern(self.db);
618612
self.define_proc_macro(def.name.clone(), proc_macro_id);
619613
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
620614
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
@@ -831,16 +825,12 @@ impl DefCollector<'_> {
831825
}
832826
}
833827

834-
fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
828+
fn resolve_extern_crate(&self, name: &Name) -> Option<CrateRootModuleId> {
835829
if *name == name!(self) {
836830
cov_mark::hit!(extern_crate_self_as);
837831
Some(self.def_map.crate_root())
838832
} else {
839-
self.deps.get(name).map(|dep| ModuleId {
840-
krate: dep.crate_id,
841-
block: None,
842-
local_id: DefMap::ROOT,
843-
})
833+
self.deps.get(name).map(|dep| CrateRootModuleId { krate: dep.crate_id })
844834
}
845835
}
846836

@@ -883,10 +873,12 @@ impl DefCollector<'_> {
883873
{
884874
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
885875
{
886-
Arc::get_mut(&mut self.def_map.data)
887-
.unwrap()
888-
.extern_prelude
889-
.insert(name.clone(), def);
876+
if let Ok(def) = def.try_into() {
877+
Arc::get_mut(&mut self.def_map.data)
878+
.unwrap()
879+
.extern_prelude
880+
.insert(name.clone(), def);
881+
}
890882
}
891883
}
892884

@@ -1791,13 +1783,11 @@ impl ModCollector<'_, '_> {
17911783

17921784
let target_crate =
17931785
match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
1794-
Some(m) => {
1795-
if m == self.def_collector.def_map.module_id(self.module_id) {
1796-
cov_mark::hit!(ignore_macro_use_extern_crate_self);
1797-
return;
1798-
}
1799-
m.krate
1786+
Some(m) if m.krate == self.def_collector.def_map.krate => {
1787+
cov_mark::hit!(ignore_macro_use_extern_crate_self);
1788+
return;
18001789
}
1790+
Some(m) => m.krate,
18011791
None => return,
18021792
};
18031793

crates/hir-def/src/resolver.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ use crate::{
2121
path::{ModPath, Path, PathKind},
2222
per_ns::PerNs,
2323
visibility::{RawVisibility, Visibility},
24-
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
25-
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
26-
LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId,
27-
StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
28-
TypeParamId, VariantId,
24+
AdtId, AssocItemId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId,
25+
EnumVariantId, ExternBlockId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
26+
ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
27+
ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
28+
TypeOrConstParamId, TypeOwnerId, TypeParamId, VariantId,
2929
};
3030

3131
#[derive(Debug, Clone)]
@@ -946,6 +946,15 @@ impl HasResolver for ModuleId {
946946
}
947947
}
948948

949+
impl HasResolver for CrateRootModuleId {
950+
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
951+
Resolver {
952+
scopes: vec![],
953+
module_scope: ModuleItemMap { def_map: self.def_map(db), module_id: DefMap::ROOT },
954+
}
955+
}
956+
}
957+
949958
impl HasResolver for TraitId {
950959
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
951960
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())

crates/hir-expand/src/ast_id_map.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
2020
/// `AstId` points to an AST node in a specific file.
2121
pub struct FileAstId<N: AstNode> {
2222
raw: ErasedFileAstId,
23-
_ty: PhantomData<fn() -> N>,
23+
covariant: PhantomData<fn() -> N>,
2424
}
2525

2626
impl<N: AstNode> Clone for FileAstId<N> {
@@ -54,7 +54,7 @@ impl<N: AstNode> FileAstId<N> {
5454
where
5555
N: Into<M>,
5656
{
57-
FileAstId { raw: self.raw, _ty: PhantomData }
57+
FileAstId { raw: self.raw, covariant: PhantomData }
5858
}
5959
}
6060

@@ -122,7 +122,7 @@ impl AstIdMap {
122122

123123
pub fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> {
124124
let raw = self.erased_ast_id(item.syntax());
125-
FileAstId { raw, _ty: PhantomData }
125+
FileAstId { raw, covariant: PhantomData }
126126
}
127127

128128
pub fn get<N: AstNode>(&self, id: FileAstId<N>) -> AstPtr<N> {

0 commit comments

Comments
 (0)