diff options
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/macros.rs | 22 |
3 files changed, 34 insertions, 0 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 5f5b7151a..ae2475b4e 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -115,6 +115,10 @@ impl ItemTree { | |||
115 | // still need to collect inner items. | 115 | // still need to collect inner items. |
116 | ctx.lower_inner_items(stmt.syntax()) | 116 | ctx.lower_inner_items(stmt.syntax()) |
117 | }, | 117 | }, |
118 | ast::Item(item) => { | ||
119 | // Macros can expand to stmt and other item, and we add it as top level item | ||
120 | ctx.lower_single_item(item) | ||
121 | }, | ||
118 | _ => { | 122 | _ => { |
119 | panic!("cannot create item tree from {:?} {}", syntax, syntax); | 123 | panic!("cannot create item tree from {:?} {}", syntax, syntax); |
120 | }, | 124 | }, |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 3f558edd8..d3fe1ce1e 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -87,6 +87,14 @@ impl Ctx { | |||
87 | self.tree | 87 | self.tree |
88 | } | 88 | } |
89 | 89 | ||
90 | pub(super) fn lower_single_item(mut self, item: ast::Item) -> ItemTree { | ||
91 | self.tree.top_level = self | ||
92 | .lower_mod_item(&item, false) | ||
93 | .map(|item| item.0) | ||
94 | .unwrap_or_else(|| Default::default()); | ||
95 | self.tree | ||
96 | } | ||
97 | |||
90 | pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree { | 98 | pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree { |
91 | self.collect_inner_items(within); | 99 | self.collect_inner_items(within); |
92 | self.tree | 100 | self.tree |
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index af4f8bb11..c1e605740 100644 --- a/crates/hir_ty/src/tests/macros.rs +++ b/crates/hir_ty/src/tests/macros.rs | |||
@@ -232,6 +232,28 @@ fn expr_macro_expanded_in_stmts() { | |||
232 | } | 232 | } |
233 | 233 | ||
234 | #[test] | 234 | #[test] |
235 | fn recursive_inner_item_macro_rules() { | ||
236 | check_infer( | ||
237 | r#" | ||
238 | macro_rules! mac { | ||
239 | () => { mac!($)}; | ||
240 | ($x:tt) => { macro_rules! blub { () => { 1 }; } }; | ||
241 | } | ||
242 | fn foo() { | ||
243 | mac!(); | ||
244 | let a = blub!(); | ||
245 | } | ||
246 | "#, | ||
247 | expect![[r#" | ||
248 | !0..1 '1': i32 | ||
249 | !0..7 'mac!($)': {unknown} | ||
250 | 107..143 '{ ...!(); }': () | ||
251 | 129..130 'a': i32 | ||
252 | "#]], | ||
253 | ); | ||
254 | } | ||
255 | |||
256 | #[test] | ||
235 | fn infer_type_value_macro_having_same_name() { | 257 | fn infer_type_value_macro_having_same_name() { |
236 | check_infer( | 258 | check_infer( |
237 | r#" | 259 | r#" |