aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres.rs')
-rw-r--r--crates/hir_def/src/nameres.rs73
1 files changed, 26 insertions, 47 deletions
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 4fbbecb38..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(),
@@ -266,7 +273,8 @@ impl DefMap {
266 } 273 }
267 274
268 pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId { 275 pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId {
269 ModuleId { krate: self.krate, local_id } 276 let block = self.block.as_ref().map(|b| b.block);
277 ModuleId { krate: self.krate, local_id, block }
270 } 278 }
271 279
272 pub(crate) fn resolve_path( 280 pub(crate) fn resolve_path(
@@ -286,9 +294,9 @@ impl DefMap {
286 pub fn dump(&self) -> String { 294 pub fn dump(&self) -> String {
287 let mut buf = String::new(); 295 let mut buf = String::new();
288 let mut current_map = self; 296 let mut current_map = self;
289 while let Some(parent) = &current_map.parent { 297 while let Some(block) = &current_map.block {
290 go(&mut buf, current_map, "block scope", current_map.root); 298 go(&mut buf, current_map, "block scope", current_map.root);
291 current_map = &**parent; 299 current_map = &*block.parent;
292 } 300 }
293 go(&mut buf, current_map, "crate", current_map.root); 301 go(&mut buf, current_map, "crate", current_map.root);
294 return buf; 302 return buf;
@@ -342,35 +350,6 @@ impl ModuleData {
342 } 350 }
343} 351}
344 352
345fn parent_def_map(
346 db: &dyn DefDatabase,
347 krate: CrateId,
348 block: AstId<ast::BlockExpr>,
349) -> Arc<DefMap> {
350 // FIXME: store this info in the item tree instead of reparsing here
351 let ast_id_map = db.ast_id_map(block.file_id);
352 let block_ptr = ast_id_map.get(block.value);
353 let root = match db.parse_or_expand(block.file_id) {
354 Some(it) => it,
355 None => {
356 return Arc::new(DefMap::empty(krate, Edition::Edition2018));
357 }
358 };
359 let ast = block_ptr.to_node(&root);
360
361 for ancestor in ast.syntax().ancestors().skip(1) {
362 if let Some(block_expr) = ast::BlockExpr::cast(ancestor) {
363 let ancestor_id = ast_id_map.ast_id(&block_expr);
364 let ast_id = InFile::new(block.file_id, ancestor_id);
365 let parent_map = db.block_def_map(krate, ast_id);
366 return parent_map;
367 }
368 }
369
370 // No enclosing block scope, so the parent is the crate-level DefMap.
371 db.crate_def_map(krate)
372}
373
374#[derive(Debug, Clone, PartialEq, Eq)] 353#[derive(Debug, Clone, PartialEq, Eq)]
375pub enum ModuleSource { 354pub enum ModuleSource {
376 SourceFile(ast::SourceFile), 355 SourceFile(ast::SourceFile),