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.
This commit is contained in:
bors 2023-05-22 19:53:39 +00:00
commit 2120c913c2
2 changed files with 26 additions and 4 deletions

View File

@ -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)
}

View File

@ -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(