Check break target availability when checking breaks with values
Fixes #66702
This commit is contained in:
parent
4787e97475
commit
6857c93183
3 changed files with 32 additions and 4 deletions
|
@ -582,11 +582,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// If this is a break with a value, we need to type-check
|
// If this is a break with a value, we need to type-check
|
||||||
// the expression. Get an expected type from the loop context.
|
// the expression. Get an expected type from the loop context.
|
||||||
let opt_coerce_to = {
|
let opt_coerce_to = {
|
||||||
|
// We should release `enclosing_breakables` before the `check_expr_with_hint`
|
||||||
|
// below, so can't move this block of code to the enclosing scope and share
|
||||||
|
// `ctxt` with the second `encloding_breakables` borrow below.
|
||||||
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
|
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
|
||||||
enclosing_breakables.find_breakable(target_id)
|
match enclosing_breakables.opt_find_breakable(target_id) {
|
||||||
.coerce
|
Some(ctxt) =>
|
||||||
.as_ref()
|
ctxt.coerce.as_ref().map(|coerce| coerce.expected_ty()),
|
||||||
.map(|coerce| coerce.expected_ty())
|
None => { // Avoid ICE when `break` is inside a closure (#65383).
|
||||||
|
self.tcx.sess.delay_span_bug(
|
||||||
|
expr.span,
|
||||||
|
"break was outside loop, but no error was emitted",
|
||||||
|
);
|
||||||
|
return tcx.types.err;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the loop context is not a `loop { }`, then break with
|
// If the loop context is not a `loop { }`, then break with
|
||||||
|
|
7
src/test/ui/issues/issue-66702-break-outside-loop-val.rs
Normal file
7
src/test/ui/issues/issue-66702-break-outside-loop-val.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Breaks with values inside closures used to ICE (#66863)
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
'some_label: loop {
|
||||||
|
|| break 'some_label (); //~ ERROR: `break` inside of a closure
|
||||||
|
}
|
||||||
|
}
|
11
src/test/ui/issues/issue-66702-break-outside-loop-val.stderr
Normal file
11
src/test/ui/issues/issue-66702-break-outside-loop-val.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0267]: `break` inside of a closure
|
||||||
|
--> $DIR/issue-66702-break-outside-loop-val.rs:5:12
|
||||||
|
|
|
||||||
|
LL | || break 'some_label ();
|
||||||
|
| -- ^^^^^^^^^^^^^^^^^^^^ cannot `break` inside of a closure
|
||||||
|
| |
|
||||||
|
| enclosing closure
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0267`.
|
Loading…
Add table
Add a link
Reference in a new issue