From e2c1da36f59cd99d4da4c1d5f8f323626d3dbe61 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 10 Apr 2021 23:12:02 +0200 Subject: Support macros in pattern position --- crates/hir_def/src/body/lower.rs | 34 +++++++++++++++++++++++++++------- crates/hir_def/src/item_tree.rs | 5 +++++ crates/hir_def/src/item_tree/lower.rs | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-) (limited to 'crates/hir_def') 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<'_> { } } ast::Expr::MacroCall(e) => { + let macro_ptr = AstPtr::new(&e); let mut ids = vec![]; - self.collect_macro_call(e, syntax_ptr.clone(), true, |this, expansion| { + self.collect_macro_call(e, macro_ptr, true, |this, expansion| { ids.push(match expansion { Some(it) => this.collect_expr(it), None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), @@ -555,7 +556,7 @@ impl ExprCollector<'_> { fn collect_macro_call), T: ast::AstNode>( &mut self, e: ast::MacroCall, - syntax_ptr: AstPtr, + syntax_ptr: AstPtr, is_error_recoverable: bool, mut collector: F, ) { @@ -643,10 +644,14 @@ impl ExprCollector<'_> { // Note that macro could be expended to multiple statements if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { + let macro_ptr = AstPtr::new(&m); let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); - self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| { - match expansion { + self.collect_macro_call( + m, + macro_ptr, + false, + |this, expansion| match expansion { Some(expansion) => { let statements: ast::MacroStmts = expansion; @@ -660,8 +665,8 @@ impl ExprCollector<'_> { let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); this.statements_in_scope.push(Statement::Expr(expr)); } - } - }); + }, + ); } else { let expr = self.collect_expr_opt(stmt.expr()); self.statements_in_scope.push(Statement::Expr(expr)); @@ -848,8 +853,23 @@ impl ExprCollector<'_> { Pat::Missing } } + ast::Pat::MacroPat(mac) => match mac.macro_call() { + Some(call) => { + let macro_ptr = AstPtr::new(&call); + let mut pat = None; + self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { + pat = Some(this.collect_pat_opt(expanded_pat)); + }); + + match pat { + Some(pat) => return pat, + None => Pat::Missing, + } + } + None => Pat::Missing, + }, // FIXME: implement - ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, + ast::Pat::RangePat(_) => Pat::Missing, }; let ptr = AstPtr::new(&pat); 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 { // items. ctx.lower_macro_stmts(stmts) }, + ast::Pat(_pat) => { + // FIXME: This occurs because macros in pattern position are treated as inner + // items and expanded during block DefMap computation + return Default::default(); + }, ast::Expr(e) => { // Macros can expand to expressions. We return an empty item tree in this case, but // 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 { block_stack.push(self.source_ast_id_map.ast_id(&block)); }, ast::Item(item) => { - // FIXME: This triggers for macro calls in expression position + // FIXME: This triggers for macro calls in expression/pattern/type position let mod_items = self.lower_mod_item(&item, true); let current_block = block_stack.last(); if let (Some(mod_items), Some(block)) = (mod_items, current_block) { -- cgit v1.2.3