aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/body/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/body/lower.rs')
-rw-r--r--crates/hir_def/src/body/lower.rs24
1 files changed, 17 insertions, 7 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 75dc19c11..9f278d35b 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -205,7 +205,7 @@ impl ExprCollector<'_> {
205 self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr()) 205 self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr())
206 } 206 }
207 207
208 /// Returns `None` if the expression is `#[cfg]`d out. 208 /// Returns `None` if and only if the expression is `#[cfg]`d out.
209 fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> { 209 fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
210 let syntax_ptr = AstPtr::new(&expr); 210 let syntax_ptr = AstPtr::new(&expr);
211 self.check_cfg(&expr)?; 211 self.check_cfg(&expr)?;
@@ -668,7 +668,7 @@ impl ExprCollector<'_> {
668 if self.check_cfg(&stmt).is_none() { 668 if self.check_cfg(&stmt).is_none() {
669 return; 669 return;
670 } 670 }
671 671 let has_semi = stmt.semicolon_token().is_some();
672 // Note that macro could be expended to multiple statements 672 // Note that macro could be expended to multiple statements
673 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { 673 if let Some(ast::Expr::MacroCall(m)) = stmt.expr() {
674 let macro_ptr = AstPtr::new(&m); 674 let macro_ptr = AstPtr::new(&m);
@@ -685,18 +685,19 @@ impl ExprCollector<'_> {
685 statements.statements().for_each(|stmt| this.collect_stmt(stmt)); 685 statements.statements().for_each(|stmt| this.collect_stmt(stmt));
686 if let Some(expr) = statements.expr() { 686 if let Some(expr) = statements.expr() {
687 let expr = this.collect_expr(expr); 687 let expr = this.collect_expr(expr);
688 this.statements_in_scope.push(Statement::Expr(expr)); 688 this.statements_in_scope
689 .push(Statement::Expr { expr, has_semi });
689 } 690 }
690 } 691 }
691 None => { 692 None => {
692 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); 693 let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
693 this.statements_in_scope.push(Statement::Expr(expr)); 694 this.statements_in_scope.push(Statement::Expr { expr, has_semi });
694 } 695 }
695 }, 696 },
696 ); 697 );
697 } else { 698 } else {
698 let expr = self.collect_expr_opt(stmt.expr()); 699 let expr = self.collect_expr_opt(stmt.expr());
699 self.statements_in_scope.push(Statement::Expr(expr)); 700 self.statements_in_scope.push(Statement::Expr { expr, has_semi });
700 } 701 }
701 } 702 }
702 ast::Stmt::Item(item) => { 703 ast::Stmt::Item(item) => {
@@ -725,8 +726,17 @@ impl ExprCollector<'_> {
725 let prev_statements = std::mem::take(&mut self.statements_in_scope); 726 let prev_statements = std::mem::take(&mut self.statements_in_scope);
726 727
727 block.statements().for_each(|s| self.collect_stmt(s)); 728 block.statements().for_each(|s| self.collect_stmt(s));
728 729 block.tail_expr().and_then(|e| {
729 let tail = block.tail_expr().map(|e| self.collect_expr(e)); 730 let expr = self.maybe_collect_expr(e)?;
731 Some(self.statements_in_scope.push(Statement::Expr { expr, has_semi: false }))
732 });
733
734 let mut tail = None;
735 if let Some(Statement::Expr { expr, has_semi: false }) = self.statements_in_scope.last() {
736 tail = Some(*expr);
737 self.statements_in_scope.pop();
738 }
739 let tail = tail;
730 let statements = std::mem::replace(&mut self.statements_in_scope, prev_statements); 740 let statements = std::mem::replace(&mut self.statements_in_scope, prev_statements);
731 let syntax_node_ptr = AstPtr::new(&block.into()); 741 let syntax_node_ptr = AstPtr::new(&block.into());
732 let expr_id = self.alloc_expr( 742 let expr_id = self.alloc_expr(