Auto merge of #13183 - Veykril:break-break, r=Veykril

Fix nested break expressions, expecting unknown types
This commit is contained in:
bors 2022-09-03 15:33:21 +00:00
commit 8ddb8b7e8e
2 changed files with 35 additions and 22 deletions

View file

@ -382,36 +382,35 @@ impl<'a> InferenceContext<'a> {
TyKind::Never.intern(Interner)
}
Expr::Break { expr, label } => {
let mut coerce = match find_breakable(&mut self.breakables, label.as_ref()) {
Some(ctxt) => {
// avoiding the borrowck
mem::replace(
&mut ctxt.coerce,
CoerceMany::new(self.result.standard_types.unknown.clone()),
)
}
None => CoerceMany::new(self.result.standard_types.unknown.clone()),
};
let val_ty = if let Some(expr) = *expr {
self.infer_expr(expr, &Expectation::none())
} else {
TyBuilder::unit()
};
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
coerce.coerce(self, *expr, &val_ty);
match find_breakable(&mut self.breakables, label.as_ref()) {
Some(ctxt) => {
// avoiding the borrowck
let mut coerce = mem::replace(
&mut ctxt.coerce,
CoerceMany::new(self.result.standard_types.unknown.clone()),
);
if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
ctxt.coerce = coerce;
ctxt.may_break = true;
} else {
self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
expr: tgt_expr,
is_break: true,
});
};
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
coerce.coerce(self, *expr, &val_ty);
let ctxt = find_breakable(&mut self.breakables, label.as_ref())
.expect("breakable stack changed during coercion");
ctxt.coerce = coerce;
ctxt.may_break = true;
}
None => {
self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
expr: tgt_expr,
is_break: true,
});
}
}
TyKind::Never.intern(Interner)
}
Expr::Return { expr } => {

View file

@ -3069,3 +3069,17 @@ fn main() {
"#,
);
}
#[test]
fn nested_break() {
check_no_mismatches(
r#"
fn func() {
let int = loop {
break 0;
break (break 0);
};
}
"#,
);
}