Skip to content

Commit 4f4b38c

Browse files
authored
Rollup merge of #117382 - gurry:114529-ice-const-eval, r=oli-obk
Fail typeck for illegal break-with-value This is fixes the issue wherein typeck was succeeding for break-with-value exprs at illegal locations such as inside `while`, `while let` and `for` loops which eventually caused an ICE during MIR interpretation for const eval. Now we fail typeck for such code which prevents faulty MIR from being generated and interpreted, thus fixing the ICE. Fixes #114529
2 parents 12eb539 + 0c8bdd0 commit 4f4b38c

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
625625
}
626626
};
627627

628-
// If the loop context is not a `loop { }`, then break with
629-
// a value is illegal, and `opt_coerce_to` will be `None`.
630-
// Just set expectation to error in that case.
631-
let coerce_to = opt_coerce_to.unwrap_or_else(|| Ty::new_misc_error(tcx));
628+
let coerce_to = match opt_coerce_to {
629+
Some(c) => c,
630+
None => {
631+
// If the loop context is not a `loop { }`, then break with
632+
// a value is illegal, and `opt_coerce_to` will be `None`.
633+
// Return error in that case (#114529).
634+
return Ty::new_misc_error(tcx);
635+
}
636+
};
632637

633638
// Recurse without `enclosing_breakables` borrowed.
634639
e_ty = self.check_expr_with_hint(e, coerce_to);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Regression test for issue #114529
2+
// Tests that we do not ICE during const eval for a
3+
// break-with-value in contexts where it is illegal
4+
5+
#[allow(while_true)]
6+
fn main() {
7+
[(); {
8+
while true {
9+
break 9; //~ ERROR `break` with value from a `while` loop
10+
};
11+
51
12+
}];
13+
14+
[(); {
15+
while let Some(v) = Some(9) {
16+
break v; //~ ERROR `break` with value from a `while` loop
17+
};
18+
51
19+
}];
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0571]: `break` with value from a `while` loop
2+
--> $DIR/issue-114529-illegal-break-with-value.rs:9:13
3+
|
4+
LL | while true {
5+
| ---------- you can't `break` with a value in a `while` loop
6+
LL | break 9;
7+
| ^^^^^^^ can only break with a value inside `loop` or breakable block
8+
|
9+
help: use `break` on its own without a value inside this `while` loop
10+
|
11+
LL | break;
12+
| ~~~~~
13+
14+
error[E0571]: `break` with value from a `while` loop
15+
--> $DIR/issue-114529-illegal-break-with-value.rs:16:13
16+
|
17+
LL | while let Some(v) = Some(9) {
18+
| --------------------------- you can't `break` with a value in a `while` loop
19+
LL | break v;
20+
| ^^^^^^^ can only break with a value inside `loop` or breakable block
21+
|
22+
help: use `break` on its own without a value inside this `while` loop
23+
|
24+
LL | break;
25+
| ~~~~~
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0571`.

0 commit comments

Comments
 (0)