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:
commit
2120c913c2
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user