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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::Stmt { hir::Stmt {
kind: kind:
hir::StmtKind::Expr(hir::Expr { hir::StmtKind::Expr(hir::Expr {
kind: hir::ExprKind::Assign(..), kind: hir::ExprKind::Assign(lhs, ..),
.. ..
}), }),
.. ..
@ -1650,7 +1650,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} = blk } = blk
{ {
self.comes_from_while_condition(blk.hir_id, |_| { 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 foo = Some(0);
let bar = None; let bar = None;
while Some(x) = foo {} //~ ERROR cannot find value `x` in this scope 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 3 = foo {} //~ ERROR mismatched types
while Some(3) = foo {} //~ ERROR invalid left-hand side of assignment while Some(3) = foo {} //~ ERROR invalid left-hand side of assignment
while x = 5 {} //~ ERROR cannot find value `x` in this scope 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 {} 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 error[E0308]: mismatched types
--> $DIR/while-let-typo.rs:6:11 --> $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 {} 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. Some errors have detailed explanations: E0070, E0308, E0425.
For more information about an error, try `rustc --explain E0070`. 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`.