mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Merge #11844
11844: Fix divergence detection for bare match arms r=flodiebold a=flodiebold Fixes #11814 and #11837. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
commit
63c4d6b20d
2 changed files with 47 additions and 5 deletions
|
@ -45,10 +45,6 @@ use super::{
|
|||
impl<'a> InferenceContext<'a> {
|
||||
pub(crate) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
|
||||
let ty = self.infer_expr_inner(tgt_expr, expected);
|
||||
if self.resolve_ty_shallow(&ty).is_never() {
|
||||
// Any expression that produces a value of type `!` must have diverged
|
||||
self.diverges = Diverges::Always;
|
||||
}
|
||||
if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
|
||||
let could_unify = self.unify(&ty, &expected_ty);
|
||||
if !could_unify {
|
||||
|
@ -800,6 +796,10 @@ impl<'a> InferenceContext<'a> {
|
|||
// use a new type variable if we got unknown here
|
||||
let ty = self.insert_type_vars_shallow(ty);
|
||||
self.write_expr_ty(tgt_expr, ty.clone());
|
||||
if self.resolve_ty_shallow(&ty).is_never() {
|
||||
// Any expression that produces a value of type `!` must have diverged
|
||||
self.diverges = Diverges::Always;
|
||||
}
|
||||
ty
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use expect_test::expect;
|
||||
|
||||
use super::{check_infer_with_mismatches, check_types};
|
||||
use super::{check_infer_with_mismatches, check_no_mismatches, check_types};
|
||||
|
||||
#[test]
|
||||
fn infer_never1() {
|
||||
|
@ -441,3 +441,45 @@ fn let_else_must_diverge() {
|
|||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_11837() {
|
||||
check_no_mismatches(
|
||||
r#"
|
||||
//- minicore: result
|
||||
enum MyErr {
|
||||
Err1,
|
||||
Err2,
|
||||
}
|
||||
|
||||
fn example_ng() {
|
||||
let value: Result<i32, MyErr> = Ok(3);
|
||||
|
||||
loop {
|
||||
let ret = match value {
|
||||
Ok(value) => value,
|
||||
Err(ref err) => {
|
||||
match err {
|
||||
MyErr::Err1 => break,
|
||||
MyErr::Err2 => continue,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_11814() {
|
||||
check_no_mismatches(
|
||||
r#"
|
||||
fn example() -> bool {
|
||||
match 1 {
|
||||
_ => return true,
|
||||
};
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue