Skip to content

Commit 2d1c998

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 the break was returning was evaluated during writeback. So now we allow the typeck of break expr to happen even though we've encountered an illegal break.
1 parent 525c91d commit 2d1c998

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -626,18 +626,20 @@ 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.
632+
let coerce_to = opt_coerce_to.unwrap_or_else(|| Ty::new_misc_error(tcx));
638633

639634
// Recurse without `enclosing_breakables` borrowed.
640635
e_ty = self.check_expr_with_hint(e, coerce_to);
636+
637+
// If break with value was found illegal above,
638+
// return error right here or we risk passing typeck
639+
if let ty::Error(_) = coerce_to.kind() {
640+
return coerce_to;
641+
}
642+
641643
cause = self.misc(e.span);
642644
} else {
643645
// Otherwise, this is a break *without* a value. That's

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
}

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)