Skip to content

Commit 2120c91

Browse files
committed
Auto merge of #14872 - lowr:fix/ref-pat-with-type-var, r=HKalbasi
fix: introduce new type var when expectation for ref pat is not ref Fixes #14840 When we infer the type of ref patterns, its expected type may not be reference type: 1) expected type is an unresolved inference variable, or 2) expected type is erroneously other kind of type. In either case, we should produce a reference type with a new type variable rather than an error type so that we can continue inferring the inner patterns without further errors because of the (possible) type mismatch of this pattern.
2 parents 7ac161c + 01f42d2 commit 2120c91

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

crates/hir-ty/src/infer/pat.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,16 +313,23 @@ impl<'a> InferenceContext<'a> {
313313

314314
fn infer_ref_pat(
315315
&mut self,
316-
pat: PatId,
316+
inner_pat: PatId,
317317
mutability: Mutability,
318318
expected: &Ty,
319319
default_bm: BindingMode,
320320
) -> Ty {
321321
let expectation = match expected.as_reference() {
322322
Some((inner_ty, _lifetime, _exp_mut)) => inner_ty.clone(),
323-
_ => self.result.standard_types.unknown.clone(),
323+
None => {
324+
let inner_ty = self.table.new_type_var();
325+
let ref_ty =
326+
TyKind::Ref(mutability, static_lifetime(), inner_ty.clone()).intern(Interner);
327+
// Unification failure will be reported by the caller.
328+
self.unify(&ref_ty, expected);
329+
inner_ty
330+
}
324331
};
325-
let subty = self.infer_pat(pat, &expectation, default_bm);
332+
let subty = self.infer_pat(inner_pat, &expectation, default_bm);
326333
TyKind::Ref(mutability, static_lifetime(), subty).intern(Interner)
327334
}
328335

crates/hir-ty/src/tests/patterns.rs

Lines changed: 16 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, check_infer, check_infer_with_mismatches, check_types};
3+
use super::{check, check_infer, check_infer_with_mismatches, check_no_mismatches, check_types};
44

55
#[test]
66
fn infer_pattern() {
@@ -240,6 +240,21 @@ fn infer_pattern_match_ergonomics_ref() {
240240
);
241241
}
242242

243+
#[test]
244+
fn ref_pat_with_inference_variable() {
245+
check_no_mismatches(
246+
r#"
247+
enum E { A }
248+
fn test() {
249+
let f = |e| match e {
250+
&E::A => {}
251+
};
252+
f(&E::A);
253+
}
254+
"#,
255+
);
256+
}
257+
243258
#[test]
244259
fn infer_pattern_match_slice() {
245260
check_infer(

0 commit comments

Comments
 (0)