Unnamed repository; edit this file 'description' to name the repository.
Fix nested break expressions, expecting unknown types
Lukas Wirth 2022-09-03
parent afa374e · commit 020f689
-rw-r--r--crates/hir-ty/src/infer/expr.rs43
-rw-r--r--crates/hir-ty/src/tests/simple.rs14
2 files changed, 35 insertions, 22 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index f3f4ee65bb..2d04a864a2 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -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 } => {
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index 707e9e8450..4ea103e5d9 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -3069,3 +3069,17 @@ fn main() {
"#,
);
}
+
+#[test]
+fn nested_break() {
+ check_no_mismatches(
+ r#"
+fn func() {
+ let int = loop {
+ break 0;
+ break (break 0);
+ };
+}
+ "#,
+ );
+}