aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/hir_def/src/body.rs2
-rw-r--r--crates/hir_def/src/child_by_source.rs2
-rw-r--r--crates/hir_def/src/db.rs15
-rw-r--r--crates/hir_def/src/find_path.rs37
-rw-r--r--crates/hir_def/src/import_map.rs4
-rw-r--r--crates/hir_def/src/item_tree.rs13
-rw-r--r--crates/hir_def/src/item_tree/lower.rs2
-rw-r--r--crates/hir_def/src/lib.rs31
-rw-r--r--crates/hir_def/src/nameres.rs75
-rw-r--r--crates/hir_def/src/nameres/collector.rs29
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs67
-rw-r--r--crates/hir_def/src/nameres/tests.rs62
-rw-r--r--crates/hir_def/src/nameres/tests/block.rs26
-rw-r--r--crates/hir_def/src/nameres/tests/diagnostics.rs16
-rw-r--r--crates/hir_def/src/path.rs1
-rw-r--r--crates/hir_def/src/resolver.rs8
-rw-r--r--crates/hir_def/src/test_db.rs6
-rw-r--r--crates/hir_def/src/visibility.rs2
19 files changed, 244 insertions, 156 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index c72649c41..6513daec8 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -196,7 +196,7 @@ impl Attrs {
196 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { 196 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
197 let raw_attrs = match def { 197 let raw_attrs = match def {
198 AttrDefId::ModuleId(module) => { 198 AttrDefId::ModuleId(module) => {
199 let def_map = db.crate_def_map(module.krate); 199 let def_map = module.def_map(db);
200 let mod_data = &def_map[module.local_id]; 200 let mod_data = &def_map[module.local_id];
201 match mod_data.declaration_source(db) { 201 match mod_data.declaration_source(db) {
202 Some(it) => { 202 Some(it) => {
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 2c2c999dd..d0c84ab0b 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -86,7 +86,7 @@ impl Expander {
86 module: ModuleId, 86 module: ModuleId,
87 ) -> Expander { 87 ) -> Expander {
88 let cfg_expander = CfgExpander::new(db, current_file_id, module.krate); 88 let cfg_expander = CfgExpander::new(db, current_file_id, module.krate);
89 let crate_def_map = db.crate_def_map(module.krate); 89 let crate_def_map = module.def_map(db);
90 let ast_id_map = db.ast_id_map(current_file_id); 90 let ast_id_map = db.ast_id_map(current_file_id);
91 Expander { 91 Expander {
92 cfg_expander, 92 cfg_expander,
diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs
index dcb00a1d9..65d85c86a 100644
--- a/crates/hir_def/src/child_by_source.rs
+++ b/crates/hir_def/src/child_by_source.rs
@@ -74,7 +74,7 @@ impl ChildBySource for ImplId {
74 74
75impl ChildBySource for ModuleId { 75impl ChildBySource for ModuleId {
76 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 76 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
77 let crate_def_map = db.crate_def_map(self.krate); 77 let crate_def_map = self.def_map(db);
78 let module_data = &crate_def_map[self.local_id]; 78 let module_data = &crate_def_map[self.local_id];
79 module_data.scope.child_by_source(db) 79 module_data.scope.child_by_source(db)
80 } 80 }
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index a87c80b8a..aef7e1f6c 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -2,9 +2,9 @@
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use base_db::{salsa, CrateId, SourceDatabase, Upcast}; 4use base_db::{salsa, CrateId, SourceDatabase, Upcast};
5use hir_expand::{db::AstDatabase, AstId, HirFileId}; 5use hir_expand::{db::AstDatabase, HirFileId};
6use la_arena::ArenaMap; 6use la_arena::ArenaMap;
7use syntax::{ast, SmolStr}; 7use syntax::SmolStr;
8 8
9use crate::{ 9use crate::{
10 adt::{EnumData, StructData}, 10 adt::{EnumData, StructData},
@@ -16,9 +16,10 @@ use crate::{
16 item_tree::ItemTree, 16 item_tree::ItemTree,
17 lang_item::{LangItemTarget, LangItems}, 17 lang_item::{LangItemTarget, LangItems},
18 nameres::DefMap, 18 nameres::DefMap,
19 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 19 AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId,
20 GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, StaticLoc, StructId, 20 FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId,
21 StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId, 21 StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId,
22 UnionLoc, VariantId,
22}; 23};
23 24
24#[salsa::query_group(InternDatabaseStorage)] 25#[salsa::query_group(InternDatabaseStorage)]
@@ -41,6 +42,8 @@ pub trait InternDatabase: SourceDatabase {
41 fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; 42 fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId;
42 #[salsa::interned] 43 #[salsa::interned]
43 fn intern_impl(&self, loc: ImplLoc) -> ImplId; 44 fn intern_impl(&self, loc: ImplLoc) -> ImplId;
45 #[salsa::interned]
46 fn intern_block(&self, loc: BlockLoc) -> BlockId;
44} 47}
45 48
46#[salsa::query_group(DefDatabaseStorage)] 49#[salsa::query_group(DefDatabaseStorage)]
@@ -56,7 +59,7 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
56 fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>; 59 fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>;
57 60
58 #[salsa::invoke(DefMap::block_def_map_query)] 61 #[salsa::invoke(DefMap::block_def_map_query)]
59 fn block_def_map(&self, krate: CrateId, block: AstId<ast::BlockExpr>) -> Arc<DefMap>; 62 fn block_def_map(&self, block: BlockId) -> Arc<DefMap>;
60 63
61 #[salsa::invoke(StructData::struct_data_query)] 64 #[salsa::invoke(StructData::struct_data_query)]
62 fn struct_data(&self, id: StructId) -> Arc<StructData>; 65 fn struct_data(&self, id: StructId) -> Arc<StructData>;
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index db2d125ae..94a1d567d 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -53,12 +53,8 @@ fn check_self_super(def_map: &DefMap, item: ItemInNs, from: ModuleId) -> Option<
53 Some(ModPath::from_segments(PathKind::Super(0), Vec::new())) 53 Some(ModPath::from_segments(PathKind::Super(0), Vec::new()))
54 } else if let Some(parent_id) = def_map[from.local_id].parent { 54 } else if let Some(parent_id) = def_map[from.local_id].parent {
55 // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) 55 // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly)
56 if item 56 let parent_id = def_map.module_id(parent_id);
57 == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId { 57 if item == ItemInNs::Types(ModuleDefId::ModuleId(parent_id)) {
58 krate: from.krate,
59 local_id: parent_id,
60 }))
61 {
62 Some(ModPath::from_segments(PathKind::Super(1), Vec::new())) 58 Some(ModPath::from_segments(PathKind::Super(1), Vec::new()))
63 } else { 59 } else {
64 None 60 None
@@ -110,7 +106,7 @@ fn find_path_inner(
110 // Base cases: 106 // Base cases:
111 107
112 // - if the item is already in scope, return the name under which it is 108 // - if the item is already in scope, return the name under which it is
113 let def_map = db.crate_def_map(from.krate); 109 let def_map = from.def_map(db);
114 let from_scope: &crate::item_scope::ItemScope = &def_map[from.local_id].scope; 110 let from_scope: &crate::item_scope::ItemScope = &def_map[from.local_id].scope;
115 let scope_name = 111 let scope_name =
116 if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None }; 112 if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None };
@@ -120,12 +116,8 @@ fn find_path_inner(
120 } 116 }
121 117
122 // - if the item is the crate root, return `crate` 118 // - if the item is the crate root, return `crate`
123 if item 119 let root = def_map.module_id(def_map.root());
124 == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId { 120 if item == ItemInNs::Types(ModuleDefId::ModuleId(root)) {
125 krate: from.krate,
126 local_id: def_map.root(),
127 }))
128 {
129 return Some(ModPath::from_segments(PathKind::Crate, Vec::new())); 121 return Some(ModPath::from_segments(PathKind::Crate, Vec::new()));
130 } 122 }
131 123
@@ -145,7 +137,7 @@ fn find_path_inner(
145 137
146 // - if the item is in the prelude, return the name from there 138 // - if the item is in the prelude, return the name from there
147 if let Some(prelude_module) = def_map.prelude() { 139 if let Some(prelude_module) = def_map.prelude() {
148 let prelude_def_map = db.crate_def_map(prelude_module.krate); 140 let prelude_def_map = prelude_module.def_map(db);
149 let prelude_scope: &crate::item_scope::ItemScope = 141 let prelude_scope: &crate::item_scope::ItemScope =
150 &prelude_def_map[prelude_module.local_id].scope; 142 &prelude_def_map[prelude_module.local_id].scope;
151 if let Some((name, vis)) = prelude_scope.name_of(item) { 143 if let Some((name, vis)) = prelude_scope.name_of(item) {
@@ -175,7 +167,7 @@ fn find_path_inner(
175 167
176 // - otherwise, look for modules containing (reexporting) it and import it from one of those 168 // - otherwise, look for modules containing (reexporting) it and import it from one of those
177 169
178 let crate_root = ModuleId { local_id: def_map.root(), krate: from.krate }; 170 let crate_root = def_map.module_id(def_map.root());
179 let crate_attrs = db.attrs(crate_root.into()); 171 let crate_attrs = db.attrs(crate_root.into());
180 let prefer_no_std = crate_attrs.by_key("no_std").exists(); 172 let prefer_no_std = crate_attrs.by_key("no_std").exists();
181 let mut best_path = None; 173 let mut best_path = None;
@@ -283,19 +275,16 @@ fn find_local_import_locations(
283 // above `from` with any visibility. That means we do not need to descend into private siblings 275 // above `from` with any visibility. That means we do not need to descend into private siblings
284 // of `from` (and similar). 276 // of `from` (and similar).
285 277
286 let def_map = db.crate_def_map(from.krate); 278 let def_map = from.def_map(db);
287 279
288 // Compute the initial worklist. We start with all direct child modules of `from` as well as all 280 // Compute the initial worklist. We start with all direct child modules of `from` as well as all
289 // of its (recursive) parent modules. 281 // of its (recursive) parent modules.
290 let data = &def_map[from.local_id]; 282 let data = &def_map[from.local_id];
291 let mut worklist = data 283 let mut worklist =
292 .children 284 data.children.values().map(|child| def_map.module_id(*child)).collect::<Vec<_>>();
293 .values()
294 .map(|child| ModuleId { krate: from.krate, local_id: *child })
295 .collect::<Vec<_>>();
296 let mut parent = data.parent; 285 let mut parent = data.parent;
297 while let Some(p) = parent { 286 while let Some(p) = parent {
298 worklist.push(ModuleId { krate: from.krate, local_id: p }); 287 worklist.push(def_map.module_id(p));
299 parent = def_map[p].parent; 288 parent = def_map[p].parent;
300 } 289 }
301 290
@@ -312,7 +301,7 @@ fn find_local_import_locations(
312 &def_map[module.local_id] 301 &def_map[module.local_id]
313 } else { 302 } else {
314 // The crate might reexport a module defined in another crate. 303 // The crate might reexport a module defined in another crate.
315 ext_def_map = db.crate_def_map(module.krate); 304 ext_def_map = module.def_map(db);
316 &ext_def_map[module.local_id] 305 &ext_def_map[module.local_id]
317 }; 306 };
318 307
@@ -375,7 +364,7 @@ mod tests {
375 parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap(); 364 parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap();
376 let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap(); 365 let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap();
377 366
378 let crate_def_map = db.crate_def_map(module.krate); 367 let crate_def_map = module.def_map(&db);
379 let resolved = crate_def_map 368 let resolved = crate_def_map
380 .resolve_path( 369 .resolve_path(
381 &db, 370 &db,
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index 0251d016b..0a3dc7956 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -75,7 +75,7 @@ impl ImportMap {
75 75
76 // We look only into modules that are public(ly reexported), starting with the crate root. 76 // We look only into modules that are public(ly reexported), starting with the crate root.
77 let empty = ImportPath { segments: vec![] }; 77 let empty = ImportPath { segments: vec![] };
78 let root = ModuleId { krate, local_id: def_map.root() }; 78 let root = def_map.module_id(def_map.root());
79 let mut worklist = vec![(root, empty)]; 79 let mut worklist = vec![(root, empty)];
80 while let Some((module, mod_path)) = worklist.pop() { 80 while let Some((module, mod_path)) = worklist.pop() {
81 let ext_def_map; 81 let ext_def_map;
@@ -83,7 +83,7 @@ impl ImportMap {
83 &def_map[module.local_id] 83 &def_map[module.local_id]
84 } else { 84 } else {
85 // The crate might reexport a module defined in another crate. 85 // The crate might reexport a module defined in another crate.
86 ext_def_map = db.crate_def_map(module.krate); 86 ext_def_map = module.def_map(db);
87 &ext_def_map[module.local_id] 87 &ext_def_map[module.local_id]
88 }; 88 };
89 89
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index b8d7608e7..1e5c94660 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -66,7 +66,7 @@ impl GenericParamsId {
66} 66}
67 67
68/// The item tree of a source file. 68/// The item tree of a source file.
69#[derive(Debug, Eq, PartialEq)] 69#[derive(Debug, Default, Eq, PartialEq)]
70pub struct ItemTree { 70pub struct ItemTree {
71 _c: Count<Self>, 71 _c: Count<Self>,
72 72
@@ -82,7 +82,7 @@ impl ItemTree {
82 let syntax = if let Some(node) = db.parse_or_expand(file_id) { 82 let syntax = if let Some(node) = db.parse_or_expand(file_id) {
83 node 83 node
84 } else { 84 } else {
85 return Arc::new(Self::empty()); 85 return Default::default();
86 }; 86 };
87 87
88 let hygiene = Hygiene::new(db.upcast(), file_id); 88 let hygiene = Hygiene::new(db.upcast(), file_id);
@@ -118,15 +118,6 @@ impl ItemTree {
118 Arc::new(item_tree) 118 Arc::new(item_tree)
119 } 119 }
120 120
121 fn empty() -> Self {
122 Self {
123 _c: Count::new(),
124 top_level: Default::default(),
125 attrs: Default::default(),
126 data: Default::default(),
127 }
128 }
129
130 fn shrink_to_fit(&mut self) { 121 fn shrink_to_fit(&mut self) {
131 if let Some(data) = &mut self.data { 122 if let Some(data) = &mut self.data {
132 let ItemTreeData { 123 let ItemTreeData {
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index ce470fc3b..8a71376b9 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -43,7 +43,7 @@ pub(super) struct Ctx {
43impl Ctx { 43impl Ctx {
44 pub(super) fn new(db: &dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self { 44 pub(super) fn new(db: &dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Self {
45 Self { 45 Self {
46 tree: ItemTree::empty(), 46 tree: ItemTree::default(),
47 hygiene, 47 hygiene,
48 file, 48 file,
49 source_ast_id_map: db.ast_id_map(file), 49 source_ast_id_map: db.ast_id_map(file),
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 08ed920c6..42b50b5b7 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -50,7 +50,10 @@ pub mod import_map;
50#[cfg(test)] 50#[cfg(test)]
51mod test_db; 51mod test_db;
52 52
53use std::hash::{Hash, Hasher}; 53use std::{
54 hash::{Hash, Hasher},
55 sync::Arc,
56};
54 57
55use base_db::{impl_intern_key, salsa, CrateId}; 58use base_db::{impl_intern_key, salsa, CrateId};
56use hir_expand::{ 59use hir_expand::{
@@ -58,6 +61,7 @@ use hir_expand::{
58 MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 61 MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
59}; 62};
60use la_arena::Idx; 63use la_arena::Idx;
64use nameres::DefMap;
61use syntax::ast; 65use syntax::ast;
62 66
63use crate::builtin_type::BuiltinType; 67use crate::builtin_type::BuiltinType;
@@ -69,10 +73,24 @@ use stdx::impl_from;
69 73
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
71pub struct ModuleId { 75pub struct ModuleId {
72 pub krate: CrateId, 76 krate: CrateId,
77 block: Option<BlockId>,
73 pub local_id: LocalModuleId, 78 pub local_id: LocalModuleId,
74} 79}
75 80
81impl ModuleId {
82 pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
83 match self.block {
84 Some(block) => db.block_def_map(block),
85 None => db.crate_def_map(self.krate),
86 }
87 }
88
89 pub fn krate(&self) -> CrateId {
90 self.krate
91 }
92}
93
76/// An ID of a module, **local** to a specific crate 94/// An ID of a module, **local** to a specific crate
77pub type LocalModuleId = Idx<nameres::ModuleData>; 95pub type LocalModuleId = Idx<nameres::ModuleData>;
78 96
@@ -216,6 +234,15 @@ pub struct ImplId(salsa::InternId);
216type ImplLoc = ItemLoc<Impl>; 234type ImplLoc = ItemLoc<Impl>;
217impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); 235impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
218 236
237#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
238pub struct BlockId(salsa::InternId);
239#[derive(Debug, Hash, PartialEq, Eq, Clone)]
240pub struct BlockLoc {
241 ast_id: AstId<ast::BlockExpr>,
242 module: ModuleId,
243}
244impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
245
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 246#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
220pub struct TypeParamId { 247pub struct TypeParamId {
221 pub parent: GenericDefId, 248 pub parent: GenericDefId,
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index bd3ea9b8b..199771e9a 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -62,7 +62,7 @@ use la_arena::Arena;
62use profile::Count; 62use profile::Count;
63use rustc_hash::FxHashMap; 63use rustc_hash::FxHashMap;
64use stdx::format_to; 64use stdx::format_to;
65use syntax::{ast, AstNode}; 65use syntax::ast;
66 66
67use crate::{ 67use crate::{
68 db::DefDatabase, 68 db::DefDatabase,
@@ -70,14 +70,14 @@ use crate::{
70 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 70 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
71 path::ModPath, 71 path::ModPath,
72 per_ns::PerNs, 72 per_ns::PerNs,
73 AstId, LocalModuleId, ModuleDefId, ModuleId, 73 AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId,
74}; 74};
75 75
76/// Contains all top-level defs from a macro-expanded crate 76/// Contains all top-level defs from a macro-expanded crate
77#[derive(Debug, PartialEq, Eq)] 77#[derive(Debug, PartialEq, Eq)]
78pub struct DefMap { 78pub struct DefMap {
79 _c: Count<Self>, 79 _c: Count<Self>,
80 parent: Option<Arc<DefMap>>, 80 block: Option<BlockInfo>,
81 root: LocalModuleId, 81 root: LocalModuleId,
82 modules: Arena<ModuleData>, 82 modules: Arena<ModuleData>,
83 krate: CrateId, 83 krate: CrateId,
@@ -91,6 +91,13 @@ pub struct DefMap {
91 diagnostics: Vec<DefDiagnostic>, 91 diagnostics: Vec<DefDiagnostic>,
92} 92}
93 93
94#[derive(Debug, PartialEq, Eq)]
95struct BlockInfo {
96 block: BlockId,
97 parent: Arc<DefMap>,
98 parent_module: LocalModuleId,
99}
100
94impl std::ops::Index<LocalModuleId> for DefMap { 101impl std::ops::Index<LocalModuleId> for DefMap {
95 type Output = ModuleData; 102 type Output = ModuleData;
96 fn index(&self, id: LocalModuleId) -> &ModuleData { 103 fn index(&self, id: LocalModuleId) -> &ModuleData {
@@ -190,15 +197,12 @@ impl DefMap {
190 Arc::new(def_map) 197 Arc::new(def_map)
191 } 198 }
192 199
193 pub(crate) fn block_def_map_query( 200 pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
194 db: &dyn DefDatabase, 201 let block: BlockLoc = db.lookup_intern_block(block_id);
195 krate: CrateId, 202 let item_tree = db.item_tree(block.ast_id.file_id);
196 block: AstId<ast::BlockExpr>, 203 let block_items = item_tree.inner_items_of_block(block.ast_id.value);
197 ) -> Arc<DefMap> {
198 let item_tree = db.item_tree(block.file_id);
199 let block_items = item_tree.inner_items_of_block(block.value);
200 204
201 let parent = parent_def_map(db, krate, block); 205 let parent = block.module.def_map(db);
202 206
203 if block_items.is_empty() { 207 if block_items.is_empty() {
204 // If there are no inner items, nothing new is brought into scope, so we can just return 208 // If there are no inner items, nothing new is brought into scope, so we can just return
@@ -206,10 +210,13 @@ impl DefMap {
206 return parent; 210 return parent;
207 } 211 }
208 212
209 let mut def_map = DefMap::empty(krate, parent.edition); 213 let block_info =
210 def_map.parent = Some(parent); 214 BlockInfo { block: block_id, parent, parent_module: block.module.local_id };
215
216 let mut def_map = DefMap::empty(block.module.krate, block_info.parent.edition);
217 def_map.block = Some(block_info);
211 218
212 let def_map = collector::collect_defs(db, def_map, Some(block.value)); 219 let def_map = collector::collect_defs(db, def_map, Some(block.ast_id.value));
213 Arc::new(def_map) 220 Arc::new(def_map)
214 } 221 }
215 222
@@ -218,7 +225,7 @@ impl DefMap {
218 let root = modules.alloc(ModuleData::default()); 225 let root = modules.alloc(ModuleData::default());
219 DefMap { 226 DefMap {
220 _c: Count::new(), 227 _c: Count::new(),
221 parent: None, 228 block: None,
222 krate, 229 krate,
223 edition, 230 edition,
224 extern_prelude: FxHashMap::default(), 231 extern_prelude: FxHashMap::default(),
@@ -265,6 +272,11 @@ impl DefMap {
265 self.extern_prelude.iter() 272 self.extern_prelude.iter()
266 } 273 }
267 274
275 pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId {
276 let block = self.block.as_ref().map(|b| b.block);
277 ModuleId { krate: self.krate, local_id, block }
278 }
279
268 pub(crate) fn resolve_path( 280 pub(crate) fn resolve_path(
269 &self, 281 &self,
270 db: &dyn DefDatabase, 282 db: &dyn DefDatabase,
@@ -282,9 +294,9 @@ impl DefMap {
282 pub fn dump(&self) -> String { 294 pub fn dump(&self) -> String {
283 let mut buf = String::new(); 295 let mut buf = String::new();
284 let mut current_map = self; 296 let mut current_map = self;
285 while let Some(parent) = &current_map.parent { 297 while let Some(block) = &current_map.block {
286 go(&mut buf, current_map, "block scope", current_map.root); 298 go(&mut buf, current_map, "block scope", current_map.root);
287 current_map = &**parent; 299 current_map = &*block.parent;
288 } 300 }
289 go(&mut buf, current_map, "crate", current_map.root); 301 go(&mut buf, current_map, "crate", current_map.root);
290 return buf; 302 return buf;
@@ -338,35 +350,6 @@ impl ModuleData {
338 } 350 }
339} 351}
340 352
341fn parent_def_map(
342 db: &dyn DefDatabase,
343 krate: CrateId,
344 block: AstId<ast::BlockExpr>,
345) -> Arc<DefMap> {
346 // FIXME: store this info in the item tree instead of reparsing here
347 let ast_id_map = db.ast_id_map(block.file_id);
348 let block_ptr = ast_id_map.get(block.value);
349 let root = match db.parse_or_expand(block.file_id) {
350 Some(it) => it,
351 None => {
352 return Arc::new(DefMap::empty(krate, Edition::Edition2018));
353 }
354 };
355 let ast = block_ptr.to_node(&root);
356
357 for ancestor in ast.syntax().ancestors().skip(1) {
358 if let Some(block_expr) = ast::BlockExpr::cast(ancestor) {
359 let ancestor_id = ast_id_map.ast_id(&block_expr);
360 let ast_id = InFile::new(block.file_id, ancestor_id);
361 let parent_map = db.block_def_map(krate, ast_id);
362 return parent_map;
363 }
364 }
365
366 // No enclosing block scope, so the parent is the crate-level DefMap.
367 db.crate_def_map(krate)
368}
369
370#[derive(Debug, Clone, PartialEq, Eq)] 353#[derive(Debug, Clone, PartialEq, Eq)]
371pub enum ModuleSource { 354pub enum ModuleSource {
372 SourceFile(ast::SourceFile), 355 SourceFile(ast::SourceFile),
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index cd68efbe6..393170b32 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -37,8 +37,8 @@ use crate::{
37 per_ns::PerNs, 37 per_ns::PerNs,
38 visibility::{RawVisibility, Visibility}, 38 visibility::{RawVisibility, Visibility},
39 AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, 39 AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId,
40 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, 40 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc,
41 TraitLoc, TypeAliasLoc, UnionLoc, 41 TypeAliasLoc, UnionLoc,
42}; 42};
43 43
44const GLOB_RECURSION_LIMIT: usize = 100; 44const GLOB_RECURSION_LIMIT: usize = 100;
@@ -56,10 +56,9 @@ pub(super) fn collect_defs(
56 for dep in &crate_graph[def_map.krate].dependencies { 56 for dep in &crate_graph[def_map.krate].dependencies {
57 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); 57 log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
58 let dep_def_map = db.crate_def_map(dep.crate_id); 58 let dep_def_map = db.crate_def_map(dep.crate_id);
59 def_map.extern_prelude.insert( 59 def_map
60 dep.as_name(), 60 .extern_prelude
61 ModuleId { krate: dep.crate_id, local_id: dep_def_map.root }.into(), 61 .insert(dep.as_name(), dep_def_map.module_id(dep_def_map.root).into());
62 );
63 62
64 // look for the prelude 63 // look for the prelude
65 // If the dependency defines a prelude, we overwrite an already defined 64 // If the dependency defines a prelude, we overwrite an already defined
@@ -332,11 +331,9 @@ impl DefCollector<'_> {
332 // exported in type/value namespace. This function reduces the visibility of all items 331 // exported in type/value namespace. This function reduces the visibility of all items
333 // in the crate root that aren't proc macros. 332 // in the crate root that aren't proc macros.
334 let root = self.def_map.root; 333 let root = self.def_map.root;
334 let module_id = self.def_map.module_id(root);
335 let root = &mut self.def_map.modules[root]; 335 let root = &mut self.def_map.modules[root];
336 root.scope.censor_non_proc_macros(ModuleId { 336 root.scope.censor_non_proc_macros(module_id);
337 krate: self.def_map.krate,
338 local_id: self.def_map.root,
339 });
340 } 337 }
341 } 338 }
342 339
@@ -578,7 +575,7 @@ impl DefCollector<'_> {
578 } else if m.krate != self.def_map.krate { 575 } else if m.krate != self.def_map.krate {
579 mark::hit!(glob_across_crates); 576 mark::hit!(glob_across_crates);
580 // glob import from other crate => we can just import everything once 577 // glob import from other crate => we can just import everything once
581 let item_map = self.db.crate_def_map(m.krate); 578 let item_map = m.def_map(self.db);
582 let scope = &item_map[m.local_id].scope; 579 let scope = &item_map[m.local_id].scope;
583 580
584 // Module scoped macros is included 581 // Module scoped macros is included
@@ -1029,8 +1026,7 @@ impl ModCollector<'_, '_> {
1029 continue; 1026 continue;
1030 } 1027 }
1031 } 1028 }
1032 let module = 1029 let module = self.def_collector.def_map.module_id(self.module_id);
1033 ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id };
1034 let container = ContainerId::ModuleId(module); 1030 let container = ContainerId::ModuleId(module);
1035 1031
1036 let mut def = None; 1032 let mut def = None;
@@ -1097,10 +1093,7 @@ impl ModCollector<'_, '_> {
1097 } 1093 }
1098 } 1094 }
1099 ModItem::Impl(imp) => { 1095 ModItem::Impl(imp) => {
1100 let module = ModuleId { 1096 let module = self.def_collector.def_map.module_id(self.module_id);
1101 krate: self.def_collector.def_map.krate,
1102 local_id: self.module_id,
1103 };
1104 let container = ContainerId::ModuleId(module); 1097 let container = ContainerId::ModuleId(module);
1105 let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) } 1098 let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) }
1106 .intern(self.def_collector.db); 1099 .intern(self.def_collector.db);
@@ -1343,7 +1336,7 @@ impl ModCollector<'_, '_> {
1343 modules[res].scope.define_legacy_macro(name, mac) 1336 modules[res].scope.define_legacy_macro(name, mac)
1344 } 1337 }
1345 modules[self.module_id].children.insert(name.clone(), res); 1338 modules[self.module_id].children.insert(name.clone(), res);
1346 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; 1339 let module = self.def_collector.def_map.module_id(res);
1347 let def: ModuleDefId = module.into(); 1340 let def: ModuleDefId = module.into();
1348 self.def_collector.def_map.modules[self.module_id].scope.define_def(def); 1341 self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
1349 self.def_collector.update( 1342 self.def_collector.update(
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index ec90f4e65..419e465ed 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -10,9 +10,8 @@
10//! 10//!
11//! `ReachedFixedPoint` signals about this. 11//! `ReachedFixedPoint` signals about this.
12 12
13use std::iter::successors;
14
15use base_db::Edition; 13use base_db::Edition;
14use hir_expand::name;
16use hir_expand::name::Name; 15use hir_expand::name::Name;
17use test_utils::mark; 16use test_utils::mark;
18 17
@@ -23,7 +22,7 @@ use crate::{
23 path::{ModPath, PathKind}, 22 path::{ModPath, PathKind},
24 per_ns::PerNs, 23 per_ns::PerNs,
25 visibility::{RawVisibility, Visibility}, 24 visibility::{RawVisibility, Visibility},
26 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 25 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId,
27}; 26};
28 27
29#[derive(Debug, Clone, Copy, PartialEq, Eq)] 28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -63,6 +62,10 @@ impl ResolvePathResult {
63 62
64impl DefMap { 63impl DefMap {
65 pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { 64 pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs {
65 if name == &name!(self) {
66 mark::hit!(extern_crate_self_as);
67 return PerNs::types(self.module_id(self.root).into(), Visibility::Public);
68 }
66 self.extern_prelude 69 self.extern_prelude
67 .get(name) 70 .get(name)
68 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) 71 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
@@ -126,8 +129,8 @@ impl DefMap {
126 result.krate = result.krate.or(new.krate); 129 result.krate = result.krate.or(new.krate);
127 result.segment_index = result.segment_index.min(new.segment_index); 130 result.segment_index = result.segment_index.min(new.segment_index);
128 131
129 match &current_map.parent { 132 match &current_map.block {
130 Some(map) => current_map = map, 133 Some(block) => current_map = &block.parent,
131 None => return result, 134 None => return result,
132 } 135 }
133 } 136 }
@@ -146,21 +149,15 @@ impl DefMap {
146 PathKind::DollarCrate(krate) => { 149 PathKind::DollarCrate(krate) => {
147 if krate == self.krate { 150 if krate == self.krate {
148 mark::hit!(macro_dollar_crate_self); 151 mark::hit!(macro_dollar_crate_self);
149 PerNs::types( 152 PerNs::types(self.module_id(self.root).into(), Visibility::Public)
150 ModuleId { krate: self.krate, local_id: self.root }.into(),
151 Visibility::Public,
152 )
153 } else { 153 } else {
154 let def_map = db.crate_def_map(krate); 154 let def_map = db.crate_def_map(krate);
155 let module = ModuleId { krate, local_id: def_map.root }; 155 let module = def_map.module_id(def_map.root);
156 mark::hit!(macro_dollar_crate_other); 156 mark::hit!(macro_dollar_crate_other);
157 PerNs::types(module.into(), Visibility::Public) 157 PerNs::types(module.into(), Visibility::Public)
158 } 158 }
159 } 159 }
160 PathKind::Crate => PerNs::types( 160 PathKind::Crate => PerNs::types(self.module_id(self.root).into(), Visibility::Public),
161 ModuleId { krate: self.krate, local_id: self.root }.into(),
162 Visibility::Public,
163 ),
164 // plain import or absolute path in 2015: crate-relative with 161 // plain import or absolute path in 2015: crate-relative with
165 // fallback to extern prelude (with the simplification in 162 // fallback to extern prelude (with the simplification in
166 // rust-lang/rust#57745) 163 // rust-lang/rust#57745)
@@ -194,17 +191,35 @@ impl DefMap {
194 self.resolve_name_in_module(db, original_module, &segment, prefer_module) 191 self.resolve_name_in_module(db, original_module, &segment, prefer_module)
195 } 192 }
196 PathKind::Super(lvl) => { 193 PathKind::Super(lvl) => {
197 let m = successors(Some(original_module), |m| self.modules[*m].parent) 194 let mut module = original_module;
198 .nth(lvl as usize); 195 for i in 0..lvl {
199 if let Some(local_id) = m { 196 match self.modules[module].parent {
200 PerNs::types( 197 Some(it) => module = it,
201 ModuleId { krate: self.krate, local_id }.into(), 198 None => match &self.block {
202 Visibility::Public, 199 Some(block) => {
203 ) 200 // Look up remaining path in parent `DefMap`
204 } else { 201 let new_path = ModPath {
205 log::debug!("super path in root module"); 202 kind: PathKind::Super(lvl - i),
206 return ResolvePathResult::empty(ReachedFixedPoint::Yes); 203 segments: path.segments.clone(),
204 };
205 log::debug!("`super` path: {} -> {} in parent map", path, new_path);
206 return block.parent.resolve_path_fp_with_macro(
207 db,
208 mode,
209 block.parent_module,
210 &new_path,
211 shadow,
212 );
213 }
214 None => {
215 log::debug!("super path in root module");
216 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
217 }
218 },
219 }
207 } 220 }
221
222 PerNs::types(self.module_id(module).into(), Visibility::Public)
208 } 223 }
209 PathKind::Abs => { 224 PathKind::Abs => {
210 // 2018-style absolute path -- only extern prelude 225 // 2018-style absolute path -- only extern prelude
@@ -243,7 +258,7 @@ impl DefMap {
243 kind: PathKind::Super(0), 258 kind: PathKind::Super(0),
244 }; 259 };
245 log::debug!("resolving {:?} in other crate", path); 260 log::debug!("resolving {:?} in other crate", path);
246 let defp_map = db.crate_def_map(module.krate); 261 let defp_map = module.def_map(db);
247 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); 262 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
248 return ResolvePathResult::with( 263 return ResolvePathResult::with(
249 def, 264 def,
@@ -356,7 +371,7 @@ impl DefMap {
356 self 371 self
357 } else { 372 } else {
358 // Extend lifetime 373 // Extend lifetime
359 keep = db.crate_def_map(prelude.krate); 374 keep = prelude.def_map(db);
360 &keep 375 &keep
361 }; 376 };
362 def_map[prelude.local_id].scope.get(name) 377 def_map[prelude.local_id].scope.get(name)
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs
index 73e3a4702..b36d0b59b 100644
--- a/crates/hir_def/src/nameres/tests.rs
+++ b/crates/hir_def/src/nameres/tests.rs
@@ -8,12 +8,12 @@ mod block;
8 8
9use std::sync::Arc; 9use std::sync::Arc;
10 10
11use base_db::{fixture::WithFixture, SourceDatabase}; 11use base_db::{fixture::WithFixture, FilePosition, SourceDatabase};
12use expect_test::{expect, Expect}; 12use expect_test::{expect, Expect};
13use hir_expand::db::AstDatabase; 13use syntax::AstNode;
14use test_utils::mark; 14use test_utils::mark;
15 15
16use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; 16use crate::{db::DefDatabase, nameres::*, test_db::TestDB, Lookup};
17 17
18fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> { 18fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> {
19 let db = TestDB::with_files(ra_fixture); 19 let db = TestDB::with_files(ra_fixture);
@@ -23,14 +23,58 @@ fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> {
23 23
24fn compute_block_def_map(ra_fixture: &str) -> Arc<DefMap> { 24fn compute_block_def_map(ra_fixture: &str) -> Arc<DefMap> {
25 let (db, position) = TestDB::with_position(ra_fixture); 25 let (db, position) = TestDB::with_position(ra_fixture);
26
27 // FIXME: perhaps we should make this use body lowering tests instead?
28
26 let module = db.module_for_file(position.file_id); 29 let module = db.module_for_file(position.file_id);
27 let ast_map = db.ast_id_map(position.file_id.into()); 30 let mut def_map = db.crate_def_map(module.krate);
28 let ast = db.parse(position.file_id); 31 while let Some(new_def_map) = descend_def_map_at_position(&db, position, def_map.clone()) {
29 let block: ast::BlockExpr = 32 def_map = new_def_map;
30 syntax::algo::find_node_at_offset(&ast.syntax_node(), position.offset).unwrap(); 33 }
31 let block_id = ast_map.ast_id(&block); 34
35 // FIXME: select the right module, not the root
36
37 def_map
38}
39
40fn descend_def_map_at_position(
41 db: &dyn DefDatabase,
42 position: FilePosition,
43 def_map: Arc<DefMap>,
44) -> Option<Arc<DefMap>> {
45 for (local_id, module_data) in def_map.modules() {
46 let mod_def = module_data.origin.definition_source(db);
47 let ast_map = db.ast_id_map(mod_def.file_id);
48 let item_tree = db.item_tree(mod_def.file_id);
49 let root = db.parse_or_expand(mod_def.file_id).unwrap();
50 for item in module_data.scope.declarations() {
51 match item {
52 ModuleDefId::FunctionId(it) => {
53 // Technically blocks can be inside any type (due to arrays and const generics),
54 // and also in const/static initializers. For tests we only really care about
55 // functions though.
56
57 let ast = ast_map.get(item_tree[it.lookup(db).id.value].ast_id).to_node(&root);
58
59 if ast.syntax().text_range().contains(position.offset) {
60 // Cursor inside function, descend into its body's DefMap.
61 // Note that we don't handle block *expressions* inside function bodies.
62 let ast_map = db.ast_id_map(position.file_id.into());
63 let ast_id = ast_map.ast_id(&ast.body().unwrap());
64 let block = BlockLoc {
65 ast_id: InFile::new(position.file_id.into(), ast_id),
66 module: def_map.module_id(local_id),
67 };
68 let block_id = db.intern_block(block);
69 return Some(db.block_def_map(block_id));
70 }
71 }
72 _ => continue,
73 }
74 }
75 }
32 76
33 db.block_def_map(module.krate, InFile::new(position.file_id.into(), block_id)) 77 None
34} 78}
35 79
36fn check(ra_fixture: &str, expect: Expect) { 80fn check(ra_fixture: &str, expect: Expect) {
diff --git a/crates/hir_def/src/nameres/tests/block.rs b/crates/hir_def/src/nameres/tests/block.rs
index 01d6326a7..470ca593e 100644
--- a/crates/hir_def/src/nameres/tests/block.rs
+++ b/crates/hir_def/src/nameres/tests/block.rs
@@ -95,3 +95,29 @@ fn outer() {
95 "#]], 95 "#]],
96 ); 96 );
97} 97}
98
99#[test]
100fn super_imports() {
101 check_at(
102 r#"
103mod module {
104 fn f() {
105 use super::Struct;
106 $0
107 }
108}
109
110struct Struct {}
111"#,
112 expect![[r#"
113 block scope
114 Struct: t
115 crate
116 Struct: t
117 module: t
118
119 crate::module
120 f: v
121 "#]],
122 );
123}
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs
index 58d69d3c6..e8e72e5ef 100644
--- a/crates/hir_def/src/nameres/tests/diagnostics.rs
+++ b/crates/hir_def/src/nameres/tests/diagnostics.rs
@@ -62,6 +62,22 @@ fn unresolved_extern_crate() {
62} 62}
63 63
64#[test] 64#[test]
65fn extern_crate_self_as() {
66 mark::check!(extern_crate_self_as);
67 check_diagnostics(
68 r"
69 //- /lib.rs
70 extern crate doesnotexist;
71 //^^^^^^^^^^^^^^^^^^^^^^^^^^ unresolved extern crate
72 // Should not error.
73 extern crate self as foo;
74 struct Foo;
75 use foo::Foo as Bar;
76 ",
77 );
78}
79
80#[test]
65fn dedup_unresolved_import_from_unresolved_crate() { 81fn dedup_unresolved_import_from_unresolved_crate() {
66 check_diagnostics( 82 check_diagnostics(
67 r" 83 r"
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index e34cd7f2f..84ea09b53 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -304,6 +304,7 @@ pub use hir_expand::name as __name;
304#[macro_export] 304#[macro_export]
305macro_rules! __known_path { 305macro_rules! __known_path {
306 (core::iter::IntoIterator) => {}; 306 (core::iter::IntoIterator) => {};
307 (core::iter::Iterator) => {};
307 (core::result::Result) => {}; 308 (core::result::Result) => {};
308 (core::option::Option) => {}; 309 (core::option::Option) => {};
309 (core::ops::Range) => {}; 310 (core::ops::Range) => {};
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index b2f577649..9021ea712 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -430,7 +430,7 @@ impl Resolver {
430 for scope in &self.scopes { 430 for scope in &self.scopes {
431 if let Scope::ModuleScope(m) = scope { 431 if let Scope::ModuleScope(m) = scope {
432 if let Some(prelude) = m.crate_def_map.prelude() { 432 if let Some(prelude) = m.crate_def_map.prelude() {
433 let prelude_def_map = db.crate_def_map(prelude.krate); 433 let prelude_def_map = prelude.def_map(db);
434 traits.extend(prelude_def_map[prelude.local_id].scope.traits()); 434 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
435 } 435 }
436 traits.extend(m.crate_def_map[m.module_id].scope.traits()); 436 traits.extend(m.crate_def_map[m.module_id].scope.traits());
@@ -459,7 +459,7 @@ impl Resolver {
459 459
460 pub fn module(&self) -> Option<ModuleId> { 460 pub fn module(&self) -> Option<ModuleId> {
461 let (def_map, local_id) = self.module_scope()?; 461 let (def_map, local_id) = self.module_scope()?;
462 Some(ModuleId { krate: def_map.krate(), local_id }) 462 Some(def_map.module_id(local_id))
463 } 463 }
464 464
465 pub fn krate(&self) -> Option<CrateId> { 465 pub fn krate(&self) -> Option<CrateId> {
@@ -529,7 +529,7 @@ impl Scope {
529 f(name.clone(), ScopeDef::PerNs(def)); 529 f(name.clone(), ScopeDef::PerNs(def));
530 }); 530 });
531 if let Some(prelude) = m.crate_def_map.prelude() { 531 if let Some(prelude) = m.crate_def_map.prelude() {
532 let prelude_def_map = db.crate_def_map(prelude.krate); 532 let prelude_def_map = prelude.def_map(db);
533 prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { 533 prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| {
534 let seen_tuple = (name.clone(), def); 534 let seen_tuple = (name.clone(), def);
535 if !seen.contains(&seen_tuple) { 535 if !seen.contains(&seen_tuple) {
@@ -633,7 +633,7 @@ pub trait HasResolver: Copy {
633 633
634impl HasResolver for ModuleId { 634impl HasResolver for ModuleId {
635 fn resolver(self, db: &dyn DefDatabase) -> Resolver { 635 fn resolver(self, db: &dyn DefDatabase) -> Resolver {
636 let def_map = db.crate_def_map(self.krate); 636 let def_map = self.def_map(db);
637 Resolver::default().push_module_scope(def_map, self.local_id) 637 Resolver::default().push_module_scope(def_map, self.local_id)
638 } 638 }
639} 639}
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
index 4ff219fb7..c4e36eda5 100644
--- a/crates/hir_def/src/test_db.rs
+++ b/crates/hir_def/src/test_db.rs
@@ -15,7 +15,7 @@ use rustc_hash::FxHashSet;
15use syntax::{TextRange, TextSize}; 15use syntax::{TextRange, TextSize};
16use test_utils::extract_annotations; 16use test_utils::extract_annotations;
17 17
18use crate::{db::DefDatabase, ModuleDefId}; 18use crate::{db::DefDatabase, ModuleDefId, ModuleId};
19 19
20#[salsa::database( 20#[salsa::database(
21 base_db::SourceDatabaseExtStorage, 21 base_db::SourceDatabaseExtStorage,
@@ -72,12 +72,12 @@ impl FileLoader for TestDB {
72} 72}
73 73
74impl TestDB { 74impl TestDB {
75 pub(crate) fn module_for_file(&self, file_id: FileId) -> crate::ModuleId { 75 pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
76 for &krate in self.relevant_crates(file_id).iter() { 76 for &krate in self.relevant_crates(file_id).iter() {
77 let crate_def_map = self.crate_def_map(krate); 77 let crate_def_map = self.crate_def_map(krate);
78 for (local_id, data) in crate_def_map.modules() { 78 for (local_id, data) in crate_def_map.modules() {
79 if data.origin.file_id() == Some(file_id) { 79 if data.origin.file_id() == Some(file_id) {
80 return crate::ModuleId { krate, local_id }; 80 return crate_def_map.module_id(local_id);
81 } 81 }
82 } 82 }
83 } 83 }
diff --git a/crates/hir_def/src/visibility.rs b/crates/hir_def/src/visibility.rs
index 3134fa43d..e79a91102 100644
--- a/crates/hir_def/src/visibility.rs
+++ b/crates/hir_def/src/visibility.rs
@@ -103,7 +103,7 @@ impl Visibility {
103 if from_module.krate != to_module.krate { 103 if from_module.krate != to_module.krate {
104 return false; 104 return false;
105 } 105 }
106 let def_map = db.crate_def_map(from_module.krate); 106 let def_map = from_module.def_map(db);
107 self.is_visible_from_def_map(&def_map, from_module.local_id) 107 self.is_visible_from_def_map(&def_map, from_module.local_id)
108 } 108 }
109 109