Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_def/src/body/lower.rs')
| -rw-r--r-- | crates/hir_def/src/body/lower.rs | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 512a9312a7..d1cfc501e5 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -13,6 +13,7 @@ use hir_expand::{ use la_arena::Arena; use profile::Count; use rustc_hash::FxHashMap; +use smallvec::smallvec; use syntax::{ ast::{ self, ArrayExprKind, AstChildren, HasArgList, HasLoopBody, HasName, LiteralKind, @@ -507,14 +508,18 @@ impl ExprCollector<'_> { } ast::Expr::MacroCall(e) => { let macro_ptr = AstPtr::new(&e); - let mut ids = None; - self.collect_macro_call(e, macro_ptr, true, |this, expansion| { - ids.get_or_insert(match expansion { - Some(it) => this.collect_expr(it), - None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), - }); + let id = self.collect_macro_call(e, macro_ptr.clone(), true, |this, expansion| { + expansion.map(|it| this.collect_expr(it)) }); - ids.unwrap_or_else(|| self.alloc_expr(Expr::Missing, syntax_ptr.clone())) + match id { + Some(id) => { + self.source_map + .macro_call_to_exprs + .insert(self.expander.to_source(macro_ptr), smallvec![id]); + id + } + None => self.alloc_expr(Expr::Missing, syntax_ptr.clone()), + } } ast::Expr::MacroStmts(e) => { e.statements().for_each(|s| self.collect_stmt(s)); @@ -529,13 +534,17 @@ impl ExprCollector<'_> { }) } - fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>( + fn collect_macro_call<F, T, U>( &mut self, mcall: ast::MacroCall, syntax_ptr: AstPtr<ast::MacroCall>, record_diagnostics: bool, - mut collector: F, - ) { + collector: F, + ) -> U + where + F: FnOnce(&mut Self, Option<T>) -> U, + T: ast::AstNode, + { // File containing the macro call. Expansion errors will be attached here. let outer_file = self.expander.current_file_id; @@ -551,8 +560,7 @@ impl ExprCollector<'_> { path, }); } - collector(self, None); - return; + return collector(self, None); } }; @@ -625,11 +633,9 @@ impl ExprCollector<'_> { let macro_ptr = AstPtr::new(&m); let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); - self.collect_macro_call( - m, - macro_ptr, - false, - |this, expansion| match expansion { + let prev_stmt = self.statements_in_scope.len(); + self.collect_macro_call(m, macro_ptr.clone(), false, |this, expansion| { + match expansion { Some(expansion) => { let statements: ast::MacroStmts = expansion; @@ -644,8 +650,24 @@ impl ExprCollector<'_> { let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); this.statements_in_scope.push(Statement::Expr { expr, has_semi }); } - }, - ); + } + }); + + let mut macro_exprs = smallvec![]; + for stmt in &self.statements_in_scope[prev_stmt..] { + match *stmt { + Statement::Let { initializer, else_branch, .. } => { + macro_exprs.extend(initializer); + macro_exprs.extend(else_branch); + } + Statement::Expr { expr, .. } => macro_exprs.push(expr), + } + } + if !macro_exprs.is_empty() { + self.source_map + .macro_call_to_exprs + .insert(self.expander.to_source(macro_ptr), macro_exprs); + } } else { let expr = self.collect_expr_opt(stmt.expr()); self.statements_in_scope.push(Statement::Expr { expr, has_semi }); @@ -870,15 +892,11 @@ impl ExprCollector<'_> { 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, - } + let pat = + self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { + this.collect_pat_opt_(expanded_pat) + }); + return pat; } None => Pat::Missing, }, |