diff options
| author | Florian Diebold <flodiebold@gmail.com> | 2022-03-29 21:55:34 +0200 |
|---|---|---|
| committer | Florian Diebold <flodiebold@gmail.com> | 2022-03-29 21:56:49 +0200 |
| commit | ea1d0bccef335ed55ddc7af1312074990249eb77 (patch) | |
| tree | 17ecd0084270eec411bf2731fdac52a8e8afafda | |
| parent | 9eb7553d5ab7cd512b7edf8d8a30b191be0dc761 (diff) | |
| download | rust-ea1d0bccef335ed55ddc7af1312074990249eb77.tar.gz rust-ea1d0bccef335ed55ddc7af1312074990249eb77.zip | |
Fix divergence detection for bare match arms
Fixes #11814 and #11837.
| -rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 8 | ||||
| -rw-r--r-- | crates/hir_ty/src/tests/never_type.rs | 44 |
2 files changed, 47 insertions, 5 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 0b67f2c32e5..01022f20bd1 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -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 } diff --git a/crates/hir_ty/src/tests/never_type.rs b/crates/hir_ty/src/tests/never_type.rs index 3ca0a5b391d..fbdc8209f8f 100644 --- a/crates/hir_ty/src/tests/never_type.rs +++ b/crates/hir_ty/src/tests/never_type.rs @@ -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, + }; +} +"#, + ); +} |
