aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-04-10 22:12:02 +0100
committerJonas Schievink <[email protected]>2021-04-11 00:25:50 +0100
commite2c1da36f59cd99d4da4c1d5f8f323626d3dbe61 (patch)
treee06290db93699c71d1e4c752de6563ff787bd5fa /crates/hir_def/src
parentbd675c8a8bdd3fda239bee3d3f31acd8679655b9 (diff)
Support macros in pattern position
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r--crates/hir_def/src/body/lower.rs34
-rw-r--r--crates/hir_def/src/item_tree.rs5
-rw-r--r--crates/hir_def/src/item_tree/lower.rs2
3 files changed, 33 insertions, 8 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index bfb75a8a5..ed07d6928 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -531,8 +531,9 @@ impl ExprCollector<'_> {
531 } 531 }
532 } 532 }
533 ast::Expr::MacroCall(e) => { 533 ast::Expr::MacroCall(e) => {
534 let macro_ptr = AstPtr::new(&e);
534 let mut ids = vec![]; 535 let mut ids = vec![];
535 self.collect_macro_call(e, syntax_ptr.clone(), true, |this, expansion| { 536 self.collect_macro_call(e, macro_ptr, true, |this, expansion| {
536 ids.push(match expansion { 537 ids.push(match expansion {
537 Some(it) => this.collect_expr(it), 538 Some(it) => this.collect_expr(it),
538 None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), 539 None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
@@ -555,7 +556,7 @@ impl ExprCollector<'_> {
555 fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>( 556 fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>(
556 &mut self, 557 &mut self,
557 e: ast::MacroCall, 558 e: ast::MacroCall,
558 syntax_ptr: AstPtr<ast::Expr>, 559 syntax_ptr: AstPtr<ast::MacroCall>,
559 is_error_recoverable: bool, 560 is_error_recoverable: bool,
560 mut collector: F, 561 mut collector: F,
561 ) { 562 ) {
@@ -643,10 +644,14 @@ impl ExprCollector<'_> {
643 644
644 // Note that macro could be expended to multiple statements 645 // Note that macro could be expended to multiple statements
645 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { 646 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() {
647 let macro_ptr = AstPtr::new(&m);
646 let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); 648 let syntax_ptr = AstPtr::new(&stmt.expr().unwrap());
647 649
648 self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| { 650 self.collect_macro_call(
649 match expansion { 651 m,
652 macro_ptr,
653 false,
654 |this, expansion| match expansion {
650 Some(expansion) => { 655 Some(expansion) => {
651 let statements: ast::MacroStmts = expansion; 656 let statements: ast::MacroStmts = expansion;
652 657
@@ -660,8 +665,8 @@ impl ExprCollector<'_> {
660 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); 665 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
661 this.statements_in_scope.push(Statement::Expr(expr)); 666 this.statements_in_scope.push(Statement::Expr(expr));
662 } 667 }
663 } 668 },
664 }); 669 );
665 } else { 670 } else {
666 let expr = self.collect_expr_opt(stmt.expr()); 671 let expr = self.collect_expr_opt(stmt.expr());
667 self.statements_in_scope.push(Statement::Expr(expr)); 672 self.statements_in_scope.push(Statement::Expr(expr));
@@ -848,8 +853,23 @@ impl ExprCollector<'_> {
848 Pat::Missing 853 Pat::Missing
849 } 854 }
850 } 855 }
856 ast::Pat::MacroPat(mac) => match mac.macro_call() {
857 Some(call) => {
858 let macro_ptr = AstPtr::new(&call);
859 let mut pat = None;
860 self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
861 pat = Some(this.collect_pat_opt(expanded_pat));
862 });
863
864 match pat {
865 Some(pat) => return pat,
866 None => Pat::Missing,
867 }
868 }
869 None => Pat::Missing,
870 },
851 // FIXME: implement 871 // FIXME: implement
852 ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, 872 ast::Pat::RangePat(_) => Pat::Missing,
853 }; 873 };
854 let ptr = AstPtr::new(&pat); 874 let ptr = AstPtr::new(&pat);
855 self.alloc_pat(pattern, Either::Left(ptr)) 875 self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 240662486..94e08f835 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -99,6 +99,11 @@ impl ItemTree {
99 // items. 99 // items.
100 ctx.lower_macro_stmts(stmts) 100 ctx.lower_macro_stmts(stmts)
101 }, 101 },
102 ast::Pat(_pat) => {
103 // FIXME: This occurs because macros in pattern position are treated as inner
104 // items and expanded during block DefMap computation
105 return Default::default();
106 },
102 ast::Expr(e) => { 107 ast::Expr(e) => {
103 // Macros can expand to expressions. We return an empty item tree in this case, but 108 // Macros can expand to expressions. We return an empty item tree in this case, but
104 // still need to collect inner items. 109 // still need to collect inner items.
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index c5629af24..45b099cf3 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -189,7 +189,7 @@ impl Ctx {
189 block_stack.push(self.source_ast_id_map.ast_id(&block)); 189 block_stack.push(self.source_ast_id_map.ast_id(&block));
190 }, 190 },
191 ast::Item(item) => { 191 ast::Item(item) => {
192 // FIXME: This triggers for macro calls in expression position 192 // FIXME: This triggers for macro calls in expression/pattern/type position
193 let mod_items = self.lower_mod_item(&item, true); 193 let mod_items = self.lower_mod_item(&item, true);
194 let current_block = block_stack.last(); 194 let current_block = block_stack.last();
195 if let (Some(mod_items), Some(block)) = (mod_items, current_block) { 195 if let (Some(mod_items), Some(block)) = (mod_items, current_block) {