Skip to content

Commit

Permalink
Fix ICE for while loop with assignment condition with LHS place expr
Browse files Browse the repository at this point in the history
  • Loading branch information
jieyouxu committed Jun 7, 2023
1 parent afab366 commit adbfd0d
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 4 deletions.
13 changes: 11 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Stmt {
kind:
hir::StmtKind::Expr(hir::Expr {
kind: hir::ExprKind::Assign(..),
kind: hir::ExprKind::Assign(lhs, ..),
..
}),
..
Expand All @@ -1650,7 +1650,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} = blk
{
self.comes_from_while_condition(blk.hir_id, |_| {
err.downgrade_to_delayed_bug();
// We cannot suppress the error if the LHS of assignment
// is a syntactic place expression because E0070 would
// not be emitted by `check_lhs_assignable`.
let res = self.typeck_results.borrow().expr_ty_opt(lhs);

if !lhs.is_syntactic_place_expr()
|| res.references_error()
{
err.downgrade_to_delayed_bug();
}
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/suggestions/while-let-typo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ fn main() {
let foo = Some(0);
let bar = None;
while Some(x) = foo {} //~ ERROR cannot find value `x` in this scope
while Some(foo) = bar {}
while Some(foo) = bar {} //~ ERROR mismatched types
while 3 = foo {} //~ ERROR mismatched types
while Some(3) = foo {} //~ ERROR invalid left-hand side of assignment
while x = 5 {} //~ ERROR cannot find value `x` in this scope
Expand Down
13 changes: 12 additions & 1 deletion tests/ui/suggestions/while-let-typo.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ help: you might have meant to use pattern matching
LL | while let x = 5 {}
| +++

error[E0308]: mismatched types
--> $DIR/while-let-typo.rs:5:11
|
LL | while Some(foo) = bar {}
| ^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
help: consider adding `let`
|
LL | while let Some(foo) = bar {}
| +++

error[E0308]: mismatched types
--> $DIR/while-let-typo.rs:6:11
|
Expand All @@ -39,7 +50,7 @@ help: you might have meant to use pattern destructuring
LL | while let Some(3) = foo {}
| +++

error: aborting due to 4 previous errors
error: aborting due to 5 previous errors

Some errors have detailed explanations: E0070, E0308, E0425.
For more information about an error, try `rustc --explain E0070`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Previously, the while loop with an assignment statement (mistakenly) as the condition
// which has a place expr as the LHS would trigger an ICE in typeck.
// Reduced from https://github.com/rust-lang/rust/issues/112385.

fn main() {
let foo = Some(());
while Some(foo) = None {}
//~^ ERROR mismatched types
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/issue-112385-while-assign-lhs-place-expr-ice.rs:7:11
|
LL | while Some(foo) = None {}
| ^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
help: consider adding `let`
|
LL | while let Some(foo) = None {}
| +++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit adbfd0d

Please sign in to comment.