diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-11 20:01:39 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-11 20:01:39 +0100 |
commit | da80dfc0226af546244dacf3fbfdbb2b7136539a (patch) | |
tree | d1c337ce069d3016a630fb48684a5410730f7d86 /crates/hir_def | |
parent | e290891dd75f2ae2d156e8610fd037a84c1b853f (diff) | |
parent | 11c926fd97d5efb61a771455fc233afe33939569 (diff) |
Merge #8398
8398: Fix inference with conditionally compiled tails r=flodiebold a=DJMcNab
Fixes #8378
Co-authored-by: Daniel McNab <[email protected]>
Diffstat (limited to 'crates/hir_def')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 24 | ||||
-rw-r--r-- | crates/hir_def/src/body/scope.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/expr.rs | 4 |
3 files changed, 20 insertions, 10 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( |
diff --git a/crates/hir_def/src/body/scope.rs b/crates/hir_def/src/body/scope.rs index bd7005ca6..6764de3a7 100644 --- a/crates/hir_def/src/body/scope.rs +++ b/crates/hir_def/src/body/scope.rs | |||
@@ -157,7 +157,7 @@ fn compute_block_scopes( | |||
157 | scope = scopes.new_scope(scope); | 157 | scope = scopes.new_scope(scope); |
158 | scopes.add_bindings(body, scope, *pat); | 158 | scopes.add_bindings(body, scope, *pat); |
159 | } | 159 | } |
160 | Statement::Expr(expr) => { | 160 | Statement::Expr { expr, .. } => { |
161 | scopes.set_scope(*expr, scope); | 161 | scopes.set_scope(*expr, scope); |
162 | compute_expr_scopes(*expr, body, scopes, scope); | 162 | compute_expr_scopes(*expr, body, scopes, scope); |
163 | } | 163 | } |
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs index b4ad984bd..0c3b41080 100644 --- a/crates/hir_def/src/expr.rs +++ b/crates/hir_def/src/expr.rs | |||
@@ -242,7 +242,7 @@ pub struct RecordLitField { | |||
242 | #[derive(Debug, Clone, Eq, PartialEq)] | 242 | #[derive(Debug, Clone, Eq, PartialEq)] |
243 | pub enum Statement { | 243 | pub enum Statement { |
244 | Let { pat: PatId, type_ref: Option<Interned<TypeRef>>, initializer: Option<ExprId> }, | 244 | Let { pat: PatId, type_ref: Option<Interned<TypeRef>>, initializer: Option<ExprId> }, |
245 | Expr(ExprId), | 245 | Expr { expr: ExprId, has_semi: bool }, |
246 | } | 246 | } |
247 | 247 | ||
248 | impl Expr { | 248 | impl Expr { |
@@ -265,7 +265,7 @@ impl Expr { | |||
265 | f(*expr); | 265 | f(*expr); |
266 | } | 266 | } |
267 | } | 267 | } |
268 | Statement::Expr(e) => f(*e), | 268 | Statement::Expr { expr: expression, .. } => f(*expression), |
269 | } | 269 | } |
270 | } | 270 | } |
271 | if let Some(expr) = tail { | 271 | if let Some(expr) = tail { |