about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs21
-rw-r--r--tests/ui/typeck/issue-114529-illegal-break-with-value.rs6
-rw-r--r--tests/ui/typeck/issue-114529-illegal-break-with-value.stderr17
3 files changed, 34 insertions, 10 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index d9b27fc1318..4b7de36e7c7 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -626,15 +626,18 @@ impl<'a, 'tcx> FnCtxt<'a, '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);
-                    }
-                };
+                // If the loop context is not a `loop { }`, then break with
+                // a value is illegal, and `opt_coerce_to` will be `None`.
+                // Set expectation to error in that case and set tainted
+                // by error (#114529)
+                let coerce_to = opt_coerce_to.unwrap_or_else(|| {
+                    let guar = tcx.sess.delay_span_bug(
+                        expr.span,
+                        "illegal break with value found but no error reported",
+                    );
+                    self.set_tainted_by_errors(guar);
+                    Ty::new_error(tcx, guar)
+                });
 
                 // 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
index 613d1b6343a..353a935e373 100644
--- a/tests/ui/typeck/issue-114529-illegal-break-with-value.rs
+++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.rs
@@ -17,4 +17,10 @@ fn main() {
         };
         51
     }];
+
+    while true {
+        break (|| { //~ ERROR `break` with value from a `while` loop
+            let local = 9;
+        });
+    }
 }
diff --git a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
index 4d6c27bbbd0..731f234c162 100644
--- a/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
+++ b/tests/ui/typeck/issue-114529-illegal-break-with-value.stderr
@@ -24,6 +24,21 @@ help: use `break` on its own without a value inside this `while` loop
 LL |             break;
    |             ~~~~~
 
-error: aborting due to 2 previous errors
+error[E0571]: `break` with value from a `while` loop
+  --> $DIR/issue-114529-illegal-break-with-value.rs:22:9
+   |
+LL |       while true {
+   |       ---------- you can't `break` with a value in a `while` loop
+LL | /         break (|| {
+LL | |             let local = 9;
+LL | |         });
+   | |__________^ 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 3 previous errors
 
 For more information about this error, try `rustc --explain E0571`.