diff options
| author | Ryo Yoshida <low.ryoshida@gmail.com> | 2023-05-21 21:25:01 +0900 |
|---|---|---|
| committer | Ryo Yoshida <low.ryoshida@gmail.com> | 2023-05-22 23:13:41 +0900 |
| commit | 01f42d240570fd933fb6407a7b010dbab53563ff (patch) | |
| tree | 5100a06e62806936e69bdb36034122852211de51 | |
| parent | a04d8456be1d289c814846178cc1ff63b4fc297b (diff) | |
| download | rust-01f42d240570fd933fb6407a7b010dbab53563ff.tar.gz rust-01f42d240570fd933fb6407a7b010dbab53563ff.zip | |
fix: introduce new type var when expectation for ref pat is not ref
| -rw-r--r-- | crates/hir-ty/src/infer/pat.rs | 13 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/patterns.rs | 17 |
2 files changed, 26 insertions, 4 deletions
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 05f6fcaead2..0c2b179a10d 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs @@ -313,16 +313,23 @@ impl<'a> InferenceContext<'a> { fn infer_ref_pat( &mut self, - pat: PatId, + inner_pat: PatId, mutability: Mutability, expected: &Ty, default_bm: BindingMode, ) -> Ty { let expectation = match expected.as_reference() { Some((inner_ty, _lifetime, _exp_mut)) => inner_ty.clone(), - _ => self.result.standard_types.unknown.clone(), + None => { + let inner_ty = self.table.new_type_var(); + let ref_ty = + TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner); + // Unification failure will be reported by the caller. + self.unify(&ref_ty, expected); + inner_ty + } }; - let subty = self.infer_pat(pat, &expectation, default_bm); + let subty = self.infer_pat(inner_pat, &expectation, default_bm); TyKind::Ref(mutability, static_lifetime(), subty).intern(Interner) } diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs index c8c31bdea5c..b73f0d72a3f 100644 --- a/crates/hir-ty/src/tests/patterns.rs +++ b/crates/hir-ty/src/tests/patterns.rs @@ -1,6 +1,6 @@ use expect_test::expect; -use super::{check, check_infer, check_infer_with_mismatches, check_types}; +use super::{check, check_infer, check_infer_with_mismatches, check_no_mismatches, check_types}; #[test] fn infer_pattern() { @@ -241,6 +241,21 @@ fn infer_pattern_match_ergonomics_ref() { } #[test] +fn ref_pat_with_inference_variable() { + check_no_mismatches( + r#" +enum E { A } +fn test() { + let f = |e| match e { + &E::A => {} + }; + f(&E::A); +} +"#, + ); +} + +#[test] fn infer_pattern_match_slice() { check_infer( r#" |
