Skip to content

Commit ea1d0bc

Browse files
committed
Fix divergence detection for bare match arms
Fixes #11814 and #11837.
1 parent 9eb7553 commit ea1d0bc

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

crates/hir_ty/src/infer/expr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ use super::{
4545
impl<'a> InferenceContext<'a> {
4646
pub(crate) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
4747
let ty = self.infer_expr_inner(tgt_expr, expected);
48-
if self.resolve_ty_shallow(&ty).is_never() {
49-
// Any expression that produces a value of type `!` must have diverged
50-
self.diverges = Diverges::Always;
51-
}
5248
if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
5349
let could_unify = self.unify(&ty, &expected_ty);
5450
if !could_unify {
@@ -800,6 +796,10 @@ impl<'a> InferenceContext<'a> {
800796
// use a new type variable if we got unknown here
801797
let ty = self.insert_type_vars_shallow(ty);
802798
self.write_expr_ty(tgt_expr, ty.clone());
799+
if self.resolve_ty_shallow(&ty).is_never() {
800+
// Any expression that produces a value of type `!` must have diverged
801+
self.diverges = Diverges::Always;
802+
}
803803
ty
804804
}
805805

crates/hir_ty/src/tests/never_type.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use expect_test::expect;
22

3-
use super::{check_infer_with_mismatches, check_types};
3+
use super::{check_infer_with_mismatches, check_no_mismatches, check_types};
44

55
#[test]
66
fn infer_never1() {
@@ -441,3 +441,45 @@ fn let_else_must_diverge() {
441441
"#]],
442442
);
443443
}
444+
445+
#[test]
446+
fn issue_11837() {
447+
check_no_mismatches(
448+
r#"
449+
//- minicore: result
450+
enum MyErr {
451+
Err1,
452+
Err2,
453+
}
454+
455+
fn example_ng() {
456+
let value: Result<i32, MyErr> = Ok(3);
457+
458+
loop {
459+
let ret = match value {
460+
Ok(value) => value,
461+
Err(ref err) => {
462+
match err {
463+
MyErr::Err1 => break,
464+
MyErr::Err2 => continue,
465+
};
466+
}
467+
};
468+
}
469+
}
470+
"#,
471+
);
472+
}
473+
474+
#[test]
475+
fn issue_11814() {
476+
check_no_mismatches(
477+
r#"
478+
fn example() -> bool {
479+
match 1 {
480+
_ => return true,
481+
};
482+
}
483+
"#,
484+
);
485+
}

0 commit comments

Comments
 (0)