From 13f30e9ef5f3d78fdaef450e935782a2edd9f88e Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 18 Mar 2021 19:39:40 +0800 Subject: Handle inner recursive macro rules cases --- crates/hir_def/src/item_tree.rs | 4 ++++ crates/hir_def/src/item_tree/lower.rs | 8 ++++++++ crates/hir_ty/src/tests/macros.rs | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) (limited to 'crates') diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 7bb22c4c4..4477bdd36 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -115,6 +115,10 @@ impl ItemTree { // still need to collect inner items. ctx.lower_inner_items(stmt.syntax()) }, + ast::Item(item) => { + // Macros can expand to stmt and other item, and we add it as top level item + ctx.lower_single_item(item) + }, _ => { panic!("cannot create item tree from {:?} {}", syntax, syntax); }, diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 7e91b991d..d684b89d0 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 { self.tree } + pub(super) fn lower_single_item(mut self, item: ast::Item) -> ItemTree { + self.tree.top_level = self + .lower_mod_item(&item, false) + .map(|item| item.0) + .unwrap_or_else(|| Default::default()); + self.tree + } + pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree { self.collect_inner_items(within); 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 @@ -231,6 +231,28 @@ fn expr_macro_expanded_in_stmts() { ); } +#[test] +fn recursive_inner_item_macro_rules() { + check_infer( + r#" + macro_rules! mac { + () => { mac!($)}; + ($x:tt) => { macro_rules! blub { () => { 1 }; } }; + } + fn foo() { + mac!(); + let a = blub!(); + } + "#, + expect![[r#" + !0..1 '1': i32 + !0..7 'mac!($)': {unknown} + 107..143 '{ ...!(); }': () + 129..130 'a': i32 + "#]], + ); +} + #[test] fn infer_type_value_macro_having_same_name() { check_infer( -- cgit v1.2.3