Fix ICE for while loop with assignment condition with LHS place expr

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2023-06-08 00:52:53 +08:00
parent afab3662eb
commit adbfd0da68
No known key found for this signature in database
GPG key ID: C5FD5D32014FDB47
5 changed files with 47 additions and 4 deletions

View file

@ -1640,7 +1640,7 @@ pub(in super::super) fn check_block_with_expected(
hir::Stmt {
kind:
hir::StmtKind::Expr(hir::Expr {
kind: hir::ExprKind::Assign(..),
kind: hir::ExprKind::Assign(lhs, ..),
..
}),
..
@ -1650,7 +1650,16 @@ pub(in super::super) fn check_block_with_expected(
} = 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();
}
})
}
}

View file

@ -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

View file

@ -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
|
@ -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`.

View file

@ -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
}

View file

@ -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`.