aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_def/src/nameres.rs12
-rw-r--r--crates/hir_def/src/nameres/collector.rs13
-rw-r--r--crates/hir_def/src/nameres/tests/block.rs63
3 files changed, 72 insertions, 16 deletions
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 005b36e02..6169b3bbc 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -199,16 +199,10 @@ impl DefMap {
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(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
201 let block: BlockLoc = db.lookup_intern_block(block_id); 201 let block: BlockLoc = db.lookup_intern_block(block_id);
202 let item_tree = db.item_tree(block.ast_id.file_id);
203 let block_items = item_tree.inner_items_of_block(block.ast_id.value);
204
205 let parent = block.module.def_map(db); 202 let parent = block.module.def_map(db);
206 203
207 if block_items.is_empty() { 204 // FIXME: It would be good to just return the parent map when the block has no items, but
208 // If there are no inner items, nothing new is brought into scope, so we can just return 205 // we rely on `def_map.block` in a few places, which is `Some` for the inner `DefMap`.
209 // the parent DefMap. This keeps DefMap parent chains short.
210 return parent;
211 }
212 206
213 let block_info = 207 let block_info =
214 BlockInfo { block: block_id, parent, parent_module: block.module.local_id }; 208 BlockInfo { block: block_id, parent, parent_module: block.module.local_id };
@@ -216,7 +210,7 @@ impl DefMap {
216 let mut def_map = DefMap::empty(block.module.krate, block_info.parent.edition); 210 let mut def_map = DefMap::empty(block.module.krate, block_info.parent.edition);
217 def_map.block = Some(block_info); 211 def_map.block = Some(block_info);
218 212
219 let def_map = collector::collect_defs(db, def_map, Some(block.ast_id.value)); 213 let def_map = collector::collect_defs(db, def_map, Some(block.ast_id));
220 Arc::new(def_map) 214 Arc::new(def_map)
221 } 215 }
222 216
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 761b29c86..ae98fadac 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -48,7 +48,7 @@ const FIXED_POINT_LIMIT: usize = 8192;
48pub(super) fn collect_defs( 48pub(super) fn collect_defs(
49 db: &dyn DefDatabase, 49 db: &dyn DefDatabase,
50 mut def_map: DefMap, 50 mut def_map: DefMap,
51 block: Option<FileAstId<ast::BlockExpr>>, 51 block: Option<AstId<ast::BlockExpr>>,
52) -> DefMap { 52) -> DefMap {
53 let crate_graph = db.crate_graph(); 53 let crate_graph = db.crate_graph();
54 54
@@ -261,11 +261,10 @@ impl DefCollector<'_> {
261 } 261 }
262 } 262 }
263 263
264 fn seed_with_inner(&mut self, block: FileAstId<ast::BlockExpr>) { 264 fn seed_with_inner(&mut self, block: AstId<ast::BlockExpr>) {
265 let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; 265 let item_tree = self.db.item_tree(block.file_id);
266 let item_tree = self.db.item_tree(file_id.into());
267 let module_id = self.def_map.root; 266 let module_id = self.def_map.root;
268 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; 267 self.def_map.modules[module_id].origin = ModuleOrigin::BlockExpr { block };
269 if item_tree 268 if item_tree
270 .top_level_attrs(self.db, self.def_map.krate) 269 .top_level_attrs(self.db, self.def_map.krate)
271 .cfg() 270 .cfg()
@@ -275,11 +274,11 @@ impl DefCollector<'_> {
275 def_collector: &mut *self, 274 def_collector: &mut *self,
276 macro_depth: 0, 275 macro_depth: 0,
277 module_id, 276 module_id,
278 file_id: file_id.into(), 277 file_id: block.file_id,
279 item_tree: &item_tree, 278 item_tree: &item_tree,
280 mod_dir: ModDir::root(), 279 mod_dir: ModDir::root(),
281 } 280 }
282 .collect(item_tree.inner_items_of_block(block)); 281 .collect(item_tree.inner_items_of_block(block.value));
283 } 282 }
284 } 283 }
285 284
diff --git a/crates/hir_def/src/nameres/tests/block.rs b/crates/hir_def/src/nameres/tests/block.rs
index 470ca593e..6cc659513 100644
--- a/crates/hir_def/src/nameres/tests/block.rs
+++ b/crates/hir_def/src/nameres/tests/block.rs
@@ -121,3 +121,66 @@ struct Struct {}
121 "#]], 121 "#]],
122 ); 122 );
123} 123}
124
125#[test]
126fn legacy_macro_items() {
127 // Checks that legacy-scoped `macro_rules!` from parent namespaces are resolved and expanded
128 // correctly.
129 check_at(
130 r#"
131macro_rules! hit {
132 () => {
133 struct Hit {}
134 }
135}
136
137fn f() {
138 hit!();
139 $0
140}
141"#,
142 expect![[r#"
143 block scope
144 Hit: t
145 crate
146 f: v
147 "#]],
148 );
149}
150
151#[test]
152fn macro_resolve() {
153 check_at(
154 r#"
155//- /lib.rs crate:lib deps:core
156use core::mark;
157
158fn f() {
159 fn nested() {
160 mark::hit!(Hit);
161 $0
162 }
163}
164//- /core.rs crate:core
165pub mod mark {
166 #[macro_export]
167 macro_rules! _hit {
168 ($name:ident) => {
169 struct $name {}
170 }
171 }
172
173 pub use crate::_hit as hit;
174}
175"#,
176 expect![[r#"
177 block scope
178 Hit: t
179 block scope
180 nested: v
181 crate
182 f: v
183 mark: t
184 "#]],
185 );
186}