mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-01 07:48:45 +00:00
Auto merge of #13183 - Veykril:break-break, r=Veykril
Fix nested break expressions, expecting unknown types
This commit is contained in:
commit
8ddb8b7e8e
2 changed files with 35 additions and 22 deletions
|
@ -382,36 +382,35 @@ impl<'a> InferenceContext<'a> {
|
||||||
TyKind::Never.intern(Interner)
|
TyKind::Never.intern(Interner)
|
||||||
}
|
}
|
||||||
Expr::Break { expr, label } => {
|
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 {
|
let val_ty = if let Some(expr) = *expr {
|
||||||
self.infer_expr(expr, &Expectation::none())
|
self.infer_expr(expr, &Expectation::none())
|
||||||
} else {
|
} else {
|
||||||
TyBuilder::unit()
|
TyBuilder::unit()
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
|
match find_breakable(&mut self.breakables, label.as_ref()) {
|
||||||
coerce.coerce(self, *expr, &val_ty);
|
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()) {
|
// FIXME: create a synthetic `()` during lowering so we have something to refer to here?
|
||||||
ctxt.coerce = coerce;
|
coerce.coerce(self, *expr, &val_ty);
|
||||||
ctxt.may_break = true;
|
|
||||||
} else {
|
|
||||||
self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
|
|
||||||
expr: tgt_expr,
|
|
||||||
is_break: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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)
|
TyKind::Never.intern(Interner)
|
||||||
}
|
}
|
||||||
Expr::Return { expr } => {
|
Expr::Return { expr } => {
|
||||||
|
|
|
@ -3069,3 +3069,17 @@ fn main() {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nested_break() {
|
||||||
|
check_no_mismatches(
|
||||||
|
r#"
|
||||||
|
fn func() {
|
||||||
|
let int = loop {
|
||||||
|
break 0;
|
||||||
|
break (break 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue