Skip to content

Commit ebbcf9f

Browse files
committed
Fix inference with conditionally compiled tails
Fixes #8378
1 parent eb741e8 commit ebbcf9f

File tree

5 files changed

+22
-12
lines changed

5 files changed

+22
-12
lines changed

crates/hir_def/src/body/lower.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ impl ExprCollector<'_> {
203203
self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr())
204204
}
205205

206-
/// Returns `None` if the expression is `#[cfg]`d out.
206+
/// Returns `None` if and only if the expression is `#[cfg]`d out.
207207
fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
208208
let syntax_ptr = AstPtr::new(&expr);
209209
self.check_cfg(&expr)?;
@@ -665,7 +665,7 @@ impl ExprCollector<'_> {
665665
if self.check_cfg(&stmt).is_none() {
666666
return;
667667
}
668-
668+
let has_semi = stmt.semicolon_token().is_some();
669669
// Note that macro could be expended to multiple statements
670670
if let Some(ast::Expr::MacroCall(m)) = stmt.expr() {
671671
let macro_ptr = AstPtr::new(&m);
@@ -682,18 +682,19 @@ impl ExprCollector<'_> {
682682
statements.statements().for_each(|stmt| this.collect_stmt(stmt));
683683
if let Some(expr) = statements.expr() {
684684
let expr = this.collect_expr(expr);
685-
this.statements_in_scope.push(Statement::Expr(expr));
685+
this.statements_in_scope
686+
.push(Statement::Expr { expr, has_semi });
686687
}
687688
}
688689
None => {
689690
let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
690-
this.statements_in_scope.push(Statement::Expr(expr));
691+
this.statements_in_scope.push(Statement::Expr { expr, has_semi });
691692
}
692693
},
693694
);
694695
} else {
695696
let expr = self.collect_expr_opt(stmt.expr());
696-
self.statements_in_scope.push(Statement::Expr(expr));
697+
self.statements_in_scope.push(Statement::Expr { expr, has_semi });
697698
}
698699
}
699700
ast::Stmt::Item(item) => {
@@ -722,8 +723,17 @@ impl ExprCollector<'_> {
722723
let prev_statements = std::mem::take(&mut self.statements_in_scope);
723724

724725
block.statements().for_each(|s| self.collect_stmt(s));
725-
726-
let tail = block.tail_expr().map(|e| self.collect_expr(e));
726+
block.tail_expr().and_then(|e| {
727+
let expr = self.maybe_collect_expr(e)?;
728+
Some(self.statements_in_scope.push(Statement::Expr { expr, has_semi: false }))
729+
});
730+
731+
let mut tail = None;
732+
if let Some(Statement::Expr { expr, has_semi: false }) = self.statements_in_scope.last() {
733+
tail = Some(*expr);
734+
self.statements_in_scope.pop();
735+
}
736+
let tail = tail;
727737
let statements = std::mem::replace(&mut self.statements_in_scope, prev_statements);
728738
let syntax_node_ptr = AstPtr::new(&block.into());
729739
let expr_id = self.alloc_expr(

crates/hir_def/src/body/scope.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn compute_block_scopes(
157157
scope = scopes.new_scope(scope);
158158
scopes.add_bindings(body, scope, *pat);
159159
}
160-
Statement::Expr(expr) => {
160+
Statement::Expr { expr, .. } => {
161161
scopes.set_scope(*expr, scope);
162162
compute_expr_scopes(*expr, body, scopes, scope);
163163
}

crates/hir_def/src/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ pub struct RecordLitField {
242242
#[derive(Debug, Clone, Eq, PartialEq)]
243243
pub enum Statement {
244244
Let { pat: PatId, type_ref: Option<Interned<TypeRef>>, initializer: Option<ExprId> },
245-
Expr(ExprId),
245+
Expr { expr: ExprId, has_semi: bool },
246246
}
247247

248248
impl Expr {
@@ -265,7 +265,7 @@ impl Expr {
265265
f(*expr);
266266
}
267267
}
268-
Statement::Expr(e) => f(*e),
268+
Statement::Expr { expr: expression, .. } => f(*expression),
269269
}
270270
}
271271
if let Some(expr) = tail {

crates/hir_ty/src/diagnostics/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
8383
if let Expr::Block { statements, tail, .. } = body_expr {
8484
if let Some(t) = tail {
8585
self.validate_results_in_tail_expr(body.body_expr, *t, db);
86-
} else if let Some(Statement::Expr(id)) = statements.last() {
86+
} else if let Some(Statement::Expr { expr: id, .. }) = statements.last() {
8787
self.validate_missing_tail_expr(body.body_expr, *id, db);
8888
}
8989
}

crates/hir_ty/src/infer/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ impl<'a> InferenceContext<'a> {
809809
let ty = self.resolve_ty_as_possible(ty);
810810
self.infer_pat(*pat, &ty, BindingMode::default());
811811
}
812-
Statement::Expr(expr) => {
812+
Statement::Expr { expr, .. } => {
813813
self.infer_expr(*expr, &Expectation::none());
814814
}
815815
}

0 commit comments

Comments
 (0)