diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index be225ceb84321..b1d6e4f0523b6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -625,10 +625,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - // If the loop context is not a `loop { }`, then break with - // a value is illegal, and `opt_coerce_to` will be `None`. - // Just set expectation to error in that case. - let coerce_to = opt_coerce_to.unwrap_or_else(|| Ty::new_misc_error(tcx)); + let coerce_to = match opt_coerce_to { + Some(c) => c, + None => { + // If the loop context is not a `loop { }`, then break with + // a value is illegal, and `opt_coerce_to` will be `None`. + // Return error in that case (#114529). + return Ty::new_misc_error(tcx); + } + }; // Recurse without `enclosing_breakables` borrowed. e_ty = self.check_expr_with_hint(e, coerce_to); diff --git a/tests/ui/typeck/issue-114529-illegal-break-with-value.rs b/tests/ui/typeck/issue-114529-illegal-break-with-value.rs new file mode 100644 index 0000000000000..613d1b6343a34 --- /dev/null +++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.rs @@ -0,0 +1,20 @@ +// Regression test for issue #114529 +// Tests that we do not ICE during const eval for a +// break-with-value in contexts where it is illegal + +#[allow(while_true)] +fn main() { + [(); { + while true { + break 9; //~ ERROR `break` with value from a `while` loop + }; + 51 + }]; + + [(); { + while let Some(v) = Some(9) { + break v; //~ ERROR `break` with value from a `while` loop + }; + 51 + }]; +} diff --git a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr new file mode 100644 index 0000000000000..4d6c27bbbd03b --- /dev/null +++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr @@ -0,0 +1,29 @@ +error[E0571]: `break` with value from a `while` loop + --> $DIR/issue-114529-illegal-break-with-value.rs:9:13 + | +LL | while true { + | ---------- you can't `break` with a value in a `while` loop +LL | break 9; + | ^^^^^^^ can only break with a value inside `loop` or breakable block + | +help: use `break` on its own without a value inside this `while` loop + | +LL | break; + | ~~~~~ + +error[E0571]: `break` with value from a `while` loop + --> $DIR/issue-114529-illegal-break-with-value.rs:16:13 + | +LL | while let Some(v) = Some(9) { + | --------------------------- you can't `break` with a value in a `while` loop +LL | break v; + | ^^^^^^^ can only break with a value inside `loop` or breakable block + | +help: use `break` on its own without a value inside this `while` loop + | +LL | break; + | ~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0571`.