Skip to content

Commit 4657917

Browse files
committed
Typeck break expr even if break is illegal
We were earlier 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.
1 parent 525c91d commit 4657917

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

Diff for: compiler/rustc_hir_typeck/src/expr.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -626,15 +626,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
626626
}
627627
};
628628

629-
let coerce_to = match opt_coerce_to {
630-
Some(c) => c,
631-
None => {
632-
// If the loop context is not a `loop { }`, then break with
633-
// a value is illegal, and `opt_coerce_to` will be `None`.
634-
// Return error in that case (#114529).
635-
return Ty::new_misc_error(tcx);
636-
}
637-
};
629+
// If the loop context is not a `loop { }`, then break with
630+
// a value is illegal, and `opt_coerce_to` will be `None`.
631+
// Set expectation to error in that case and set tainted
632+
// by error (#114529)
633+
let coerce_to = opt_coerce_to.unwrap_or_else(|| {
634+
let guar = tcx.sess.delay_span_bug(
635+
expr.span,
636+
"illegal break with value found but no error reported",
637+
);
638+
self.set_tainted_by_errors(guar);
639+
Ty::new_error(tcx, guar)
640+
});
638641

639642
// Recurse without `enclosing_breakables` borrowed.
640643
e_ty = self.check_expr_with_hint(e, coerce_to);

Diff for: tests/ui/typeck/issue-114529-illegal-break-with-value.rs

+6
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@ fn main() {
1717
};
1818
51
1919
}];
20+
21+
while true {
22+
break (|| { //~ ERROR `break` with value from a `while` loop
23+
let local = 9;
24+
});
25+
}
2026
}

Diff for: tests/ui/typeck/issue-114529-illegal-break-with-value.stderr

+16-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ help: use `break` on its own without a value inside this `while` loop
2424
LL | break;
2525
| ~~~~~
2626

27-
error: aborting due to 2 previous errors
27+
error[E0571]: `break` with value from a `while` loop
28+
--> $DIR/issue-114529-illegal-break-with-value.rs:22:9
29+
|
30+
LL | while true {
31+
| ---------- you can't `break` with a value in a `while` loop
32+
LL | / break (|| {
33+
LL | | let local = 9;
34+
LL | | });
35+
| |__________^ can only break with a value inside `loop` or breakable block
36+
|
37+
help: use `break` on its own without a value inside this `while` loop
38+
|
39+
LL | break;
40+
| ~~~~~
41+
42+
error: aborting due to 3 previous errors
2843

2944
For more information about this error, try `rustc --explain E0571`.

0 commit comments

Comments
 (0)