diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 05f6fcaead..0c2b179a10 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 c8c31bdea5..b73f0d72a3 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() { @@ -240,6 +240,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(