about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-11-20 20:56:42 +0100
committerGitHub <noreply@github.com>2023-11-20 20:56:42 +0100
commit1936e2c938357ab83bd8652d2192deafdfd08fa7 (patch)
tree54f61798d5cc71fa1ee74f99693014609ecc47ad
parent0270afee3148e8a97f9969f037ccbec046d65fd6 (diff)
parent4657917f6e6c49893e4fbcbe71469d4489b743d0 (diff)
downloadrust-1936e2c938357ab83bd8652d2192deafdfd08fa7.tar.gz
rust-1936e2c938357ab83bd8652d2192deafdfd08fa7.zip
Rollup merge of #118010 - gurry:117821-ice-no-type-for-local-var, r=compiler-errors
Typeck break expr even if break is illegal

Fixes #117821

We were returning immediately when encountering an illegal break. However, this caused problems later when the expr that the break was returning was evaluated during writeback. So now we don't return and instead simply set tainted by error. This lets typeck of break expr to occur even though we've encountered an illegal break.
-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`.