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 | 73 |
1 files changed, 25 insertions, 48 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index cb6fdbfc56..8ebac5cb1c 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -628,8 +628,9 @@ impl ExprCollector<'_> { fn collect_macro_as_stmt( &mut self, + statements: &mut Vec<Statement>, mac: ast::MacroExpr, - ) -> Option<(Vec<Statement>, Option<ExprId>)> { + ) -> Option<ExprId> { let mac_call = mac.macro_call()?; let syntax_ptr = AstPtr::new(&ast::Expr::from(mac)); let macro_ptr = AstPtr::new(&mac_call); @@ -639,49 +640,32 @@ impl ExprCollector<'_> { false, |this, expansion: Option<ast::MacroStmts>| match expansion { Some(expansion) => { - let mut statements: Vec<_> = expansion - .statements() - .filter_map(|stmt| this.collect_stmt(stmt)) - .flatten() - .collect(); - let tail = expansion.expr().and_then(|expr| match expr { - ast::Expr::MacroExpr(mac) => { - let (stmts, tail) = this.collect_macro_as_stmt(mac)?; - statements.extend(stmts); - tail - } + expansion.statements().for_each(|stmt| this.collect_stmt(statements, stmt)); + expansion.expr().and_then(|expr| match expr { + ast::Expr::MacroExpr(mac) => this.collect_macro_as_stmt(statements, mac), expr => Some(this.collect_expr(expr)), - }); - Some((statements, tail)) + }) } None => None, }, ); - let mut stmts = Vec::new(); - let expr = match expansion { - Some((statements, tail)) => { - stmts.extend(statements); + match expansion { + Some(tail) => { // Make the macro-call point to its expanded expression so we can query // semantics on syntax pointers to the macro let src = self.expander.to_source(syntax_ptr); - match tail { - Some(tail) => { - self.source_map.expr_map.insert(src, tail); - tail - } - None => self.make_expr(Expr::Missing, Ok(src.clone())), - } + self.source_map.expr_map.insert(src, tail); + Some(tail) } - None => self.alloc_expr(Expr::Missing, syntax_ptr), - }; - Some((stmts, Some(expr))) + None => None, + } } - fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Vec<Statement>> { + fn collect_stmt(&mut self, statements: &mut Vec<Statement>, s: ast::Stmt) { match s { ast::Stmt::LetStmt(stmt) => { if self.check_cfg(&stmt).is_none() { - return None; + return; } let pat = self.collect_pat_opt(stmt.pat()); let type_ref = @@ -691,29 +675,26 @@ impl ExprCollector<'_> { .let_else() .and_then(|let_else| let_else.block_expr()) .map(|block| self.collect_block(block)); - Some(vec![Statement::Let { pat, type_ref, initializer, else_branch }]) + statements.push(Statement::Let { pat, type_ref, initializer, else_branch }); } ast::Stmt::ExprStmt(stmt) => { let expr = stmt.expr(); - if let Some(expr) = &expr { - if self.check_cfg(expr).is_none() { - return None; - } + match &expr { + Some(expr) if self.check_cfg(expr).is_none() => return, + _ => (), } let has_semi = stmt.semicolon_token().is_some(); // Note that macro could be expanded to multiple statements if let Some(ast::Expr::MacroExpr(mac)) = expr { - let (mut statements, tail) = self.collect_macro_as_stmt(mac)?; - if let Some(expr) = tail { - statements.push(Statement::Expr { expr, has_semi }); + if let Some(expr) = self.collect_macro_as_stmt(statements, mac) { + statements.push(Statement::Expr { expr, has_semi }) } - Some(statements) } else { let expr = self.collect_expr_opt(expr); - Some(vec![Statement::Expr { expr, has_semi }]) + statements.push(Statement::Expr { expr, has_semi }); } } - ast::Stmt::Item(_item) => None, + ast::Stmt::Item(_item) => (), } } @@ -734,14 +715,10 @@ impl ExprCollector<'_> { let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); let prev_local_module = mem::replace(&mut self.expander.module, module); - let mut statements: Vec<_> = - block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); + let mut statements = Vec::new(); + block.statements().for_each(|s| self.collect_stmt(&mut statements, s)); let tail = block.tail_expr().and_then(|e| match e { - ast::Expr::MacroExpr(mac) => { - let (stmts, tail) = self.collect_macro_as_stmt(mac)?; - statements.extend(stmts); - tail - } + ast::Expr::MacroExpr(mac) => self.collect_macro_as_stmt(&mut statements, mac), expr => self.maybe_collect_expr(expr), }); let tail = tail.or_else(|| { |