aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_def/src/item_tree.rs10
-rw-r--r--crates/hir_def/src/item_tree/lower.rs26
2 files changed, 32 insertions, 4 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 1e5c94660..42d9f0947 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -98,15 +98,17 @@ impl ItemTree {
98 ctx.lower_module_items(&items) 98 ctx.lower_module_items(&items)
99 }, 99 },
100 ast::MacroStmts(stmts) => { 100 ast::MacroStmts(stmts) => {
101 ctx.lower_inner_items(stmts.syntax()) 101 // The produced statements can include items, which should be added as top-level
102 // items.
103 ctx.lower_macro_stmts(stmts)
102 }, 104 },
103 // Macros can expand to expressions. We return an empty item tree in this case, but
104 // still need to collect inner items.
105 ast::Expr(e) => { 105 ast::Expr(e) => {
106 // Macros can expand to expressions. We return an empty item tree in this case, but
107 // still need to collect inner items.
106 ctx.lower_inner_items(e.syntax()) 108 ctx.lower_inner_items(e.syntax())
107 }, 109 },
108 _ => { 110 _ => {
109 panic!("cannot create item tree from {:?}", syntax); 111 panic!("cannot create item tree from {:?} {}", syntax, syntax);
110 }, 112 },
111 } 113 }
112 }; 114 };
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 8a71376b9..acc001add 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -61,6 +61,32 @@ impl Ctx {
61 self.tree 61 self.tree
62 } 62 }
63 63
64 pub(super) fn lower_macro_stmts(mut self, stmts: ast::MacroStmts) -> ItemTree {
65 self.tree.top_level = stmts
66 .statements()
67 .filter_map(|stmt| match stmt {
68 ast::Stmt::Item(item) => Some(item),
69 _ => None,
70 })
71 .flat_map(|item| self.lower_mod_item(&item, false))
72 .flat_map(|items| items.0)
73 .collect();
74
75 // Non-items need to have their inner items collected.
76 for stmt in stmts.statements() {
77 match stmt {
78 ast::Stmt::ExprStmt(_) | ast::Stmt::LetStmt(_) => {
79 self.collect_inner_items(stmt.syntax())
80 }
81 _ => {}
82 }
83 }
84 if let Some(expr) = stmts.expr() {
85 self.collect_inner_items(expr.syntax());
86 }
87 self.tree
88 }
89
64 pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree { 90 pub(super) fn lower_inner_items(mut self, within: &SyntaxNode) -> ItemTree {
65 self.collect_inner_items(within); 91 self.collect_inner_items(within);
66 self.tree 92 self.tree