about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs13
-rw-r--r--tests/ui/typeck/issue-114529-illegal-break-with-value.rs20
-rw-r--r--tests/ui/typeck/issue-114529-illegal-break-with-value.stderr29
3 files changed, 58 insertions, 4 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index be225ceb843..b1d6e4f0523 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 00000000000..613d1b6343a
--- /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 00000000000..4d6c27bbbd0
--- /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`.