aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-02-01 12:32:43 +0000
committerJonas Schievink <[email protected]>2021-02-03 14:33:25 +0000
commitda57f5dc17303cfd5ba318d1735c7f325f6b7130 (patch)
treee3df694209537a03437b6b041e4c3cb24c481563 /crates/hir_def
parent7eff6705cc1c1d4399a7c9da360d344a96df59b6 (diff)
Shortcut `block_def_map` if there's no inner items
This previously didn't work, but apparently only because of the wonky test setup
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/body/lower.rs9
-rw-r--r--crates/hir_def/src/body/tests.rs4
-rw-r--r--crates/hir_def/src/db.rs2
-rw-r--r--crates/hir_def/src/lib.rs9
-rw-r--r--crates/hir_def/src/nameres.rs13
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
60fn block_at_pos(db: &dyn DefDatabase, def_map: &DefMap, position: FilePosition) -> Option<BlockId> { 60fn 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 {
81impl ModuleId { 81impl 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)]
240pub struct BlockLoc { 246pub 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}
244impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); 251impl_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 {