diff options
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 9 | ||||
-rw-r--r-- | crates/hir_def/src/body/tests.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/db.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 9 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 13 |
5 files changed, 26 insertions, 11 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index bc61730a7..540c6c9ad 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -700,10 +700,13 @@ impl ExprCollector<'_> { | |||
700 | let ast_id = self.expander.ast_id(&block); | 700 | let ast_id = self.expander.ast_id(&block); |
701 | let block_loc = BlockLoc { ast_id, module: self.expander.module }; | 701 | let block_loc = BlockLoc { ast_id, module: self.expander.module }; |
702 | let block_id = self.db.intern_block(block_loc); | 702 | let block_id = self.db.intern_block(block_loc); |
703 | let def_map = self.db.block_def_map(block_id); | 703 | let opt_def_map = self.db.block_def_map(block_id); |
704 | let root = def_map.module_id(def_map.root()); | 704 | let has_def_map = opt_def_map.is_some(); |
705 | let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone()); | ||
706 | let module = | ||
707 | if has_def_map { def_map.module_id(def_map.root()) } else { self.expander.module }; | ||
705 | let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); | 708 | let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); |
706 | let prev_module = mem::replace(&mut self.expander.module, root); | 709 | let prev_module = mem::replace(&mut self.expander.module, module); |
707 | 710 | ||
708 | self.collect_stmts_items(block.statements()); | 711 | self.collect_stmts_items(block.statements()); |
709 | let statements = | 712 | let statements = |
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs index da60072ce..404603360 100644 --- a/crates/hir_def/src/body/tests.rs +++ b/crates/hir_def/src/body/tests.rs | |||
@@ -43,7 +43,7 @@ fn block_def_map_at(ra_fixture: &str) -> Arc<DefMap> { | |||
43 | let mut block = | 43 | let mut block = |
44 | block_at_pos(&db, &def_map, position).expect("couldn't find enclosing function or block"); | 44 | block_at_pos(&db, &def_map, position).expect("couldn't find enclosing function or block"); |
45 | loop { | 45 | loop { |
46 | let def_map = db.block_def_map(block); | 46 | let def_map = db.block_def_map(block).unwrap_or_else(|| def_map.clone()); |
47 | let new_block = block_at_pos(&db, &def_map, position); | 47 | let new_block = block_at_pos(&db, &def_map, position); |
48 | match new_block { | 48 | match new_block { |
49 | Some(new_block) => { | 49 | Some(new_block) => { |
@@ -58,6 +58,7 @@ fn block_def_map_at(ra_fixture: &str) -> Arc<DefMap> { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | fn block_at_pos(db: &dyn DefDatabase, def_map: &DefMap, position: FilePosition) -> Option<BlockId> { | 60 | fn block_at_pos(db: &dyn DefDatabase, def_map: &DefMap, position: FilePosition) -> Option<BlockId> { |
61 | // Find the smallest (innermost) function containing the cursor. | ||
61 | let mut size = None; | 62 | let mut size = None; |
62 | let mut fn_def = None; | 63 | let mut fn_def = None; |
63 | for (_, module) in def_map.modules() { | 64 | for (_, module) in def_map.modules() { |
@@ -73,7 +74,6 @@ fn block_at_pos(db: &dyn DefDatabase, def_map: &DefMap, position: FilePosition) | |||
73 | let ast = ast_map.get(item_tree[it.lookup(db).id.value].ast_id).to_node(&root); | 74 | let ast = ast_map.get(item_tree[it.lookup(db).id.value].ast_id).to_node(&root); |
74 | let range = ast.syntax().text_range(); | 75 | let range = ast.syntax().text_range(); |
75 | 76 | ||
76 | // Find the smallest (innermost) function containing the cursor. | ||
77 | if !range.contains(position.offset) { | 77 | if !range.contains(position.offset) { |
78 | continue; | 78 | continue; |
79 | } | 79 | } |
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index aef7e1f6c..7fe6f6346 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs | |||
@@ -59,7 +59,7 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { | |||
59 | fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>; | 59 | fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>; |
60 | 60 | ||
61 | #[salsa::invoke(DefMap::block_def_map_query)] | 61 | #[salsa::invoke(DefMap::block_def_map_query)] |
62 | fn block_def_map(&self, block: BlockId) -> Arc<DefMap>; | 62 | fn block_def_map(&self, block: BlockId) -> Option<Arc<DefMap>>; |
63 | 63 | ||
64 | #[salsa::invoke(StructData::struct_data_query)] | 64 | #[salsa::invoke(StructData::struct_data_query)] |
65 | fn struct_data(&self, id: StructId) -> Arc<StructData>; | 65 | fn struct_data(&self, id: StructId) -> Arc<StructData>; |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 42b50b5b7..5dd3705b0 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -81,7 +81,13 @@ pub struct ModuleId { | |||
81 | impl ModuleId { | 81 | impl ModuleId { |
82 | pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> { | 82 | pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> { |
83 | match self.block { | 83 | match self.block { |
84 | Some(block) => db.block_def_map(block), | 84 | Some(block) => { |
85 | db.block_def_map(block).unwrap_or_else(|| { | ||
86 | // NOTE: This should be unreachable - all `ModuleId`s come from their `DefMap`s, | ||
87 | // so the `DefMap` here must exist. | ||
88 | panic!("no `block_def_map` for `ModuleId` {:?}", self); | ||
89 | }) | ||
90 | } | ||
85 | None => db.crate_def_map(self.krate), | 91 | None => db.crate_def_map(self.krate), |
86 | } | 92 | } |
87 | } | 93 | } |
@@ -239,6 +245,7 @@ pub struct BlockId(salsa::InternId); | |||
239 | #[derive(Debug, Hash, PartialEq, Eq, Clone)] | 245 | #[derive(Debug, Hash, PartialEq, Eq, Clone)] |
240 | pub struct BlockLoc { | 246 | pub struct BlockLoc { |
241 | ast_id: AstId<ast::BlockExpr>, | 247 | ast_id: AstId<ast::BlockExpr>, |
248 | /// The containing module. | ||
242 | module: ModuleId, | 249 | module: ModuleId, |
243 | } | 250 | } |
244 | impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); | 251 | impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); |
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 0a15fc470..ece5958f4 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs | |||
@@ -197,12 +197,17 @@ impl DefMap { | |||
197 | Arc::new(def_map) | 197 | Arc::new(def_map) |
198 | } | 198 | } |
199 | 199 | ||
200 | pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> { | 200 | pub(crate) fn block_def_map_query( |
201 | db: &dyn DefDatabase, | ||
202 | block_id: BlockId, | ||
203 | ) -> Option<Arc<DefMap>> { | ||
201 | let block: BlockLoc = db.lookup_intern_block(block_id); | 204 | let block: BlockLoc = db.lookup_intern_block(block_id); |
202 | let parent = block.module.def_map(db); | 205 | let parent = block.module.def_map(db); |
203 | 206 | ||
204 | // FIXME: It would be good to just return the parent map when the block has no items, but | 207 | let item_tree = db.item_tree(block.ast_id.file_id); |
205 | // we rely on `def_map.block` in a few places, which is `Some` for the inner `DefMap`. | 208 | if item_tree.inner_items_of_block(block.ast_id.value).is_empty() { |
209 | return None; | ||
210 | } | ||
206 | 211 | ||
207 | let block_info = | 212 | let block_info = |
208 | BlockInfo { block: block_id, parent, parent_module: block.module.local_id }; | 213 | BlockInfo { block: block_id, parent, parent_module: block.module.local_id }; |
@@ -211,7 +216,7 @@ impl DefMap { | |||
211 | def_map.block = Some(block_info); | 216 | def_map.block = Some(block_info); |
212 | 217 | ||
213 | let def_map = collector::collect_defs(db, def_map, Some(block.ast_id)); | 218 | let def_map = collector::collect_defs(db, def_map, Some(block.ast_id)); |
214 | Arc::new(def_map) | 219 | Some(Arc::new(def_map)) |
215 | } | 220 | } |
216 | 221 | ||
217 | fn empty(krate: CrateId, edition: Edition) -> DefMap { | 222 | fn empty(krate: CrateId, edition: Edition) -> DefMap { |