handle array pattern matching type inference

This commit is contained in:
Josh Mcguigan 2020-03-01 14:02:32 -08:00
parent b9ef7a6b98
commit f5efa17515
2 changed files with 55 additions and 10 deletions

View File

@ -12,7 +12,7 @@ use hir_expand::name::Name;
use test_utils::tested_by;
use super::{BindingMode, InferenceContext};
use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, ApplicationTy};
use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor};
impl<'a, D: HirDatabase> InferenceContext<'a, D> {
fn infer_tuple_struct_pat(
@ -186,17 +186,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
return inner_ty;
}
Pat::Slice { prefix, slice: _slice, suffix } => {
let ty = if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Slice, parameters }) = expected {
for pat_id in prefix.iter().chain(suffix) {
self.infer_pat(*pat_id, parameters.as_single(), default_bm);
}
parameters.as_single().clone()
} else {
Ty::Unknown
let (container_ty, elem_ty) = match &expected {
ty_app!(TypeCtor::Array, st) => {
(TypeCtor::Array, st.as_single().clone())
},
ty_app!(TypeCtor::Slice, st) => {
(TypeCtor::Slice, st.as_single().clone())
},
_ => (TypeCtor::Slice, Ty::Unknown),
};
Ty::apply_one(TypeCtor::Slice, ty)
for pat_id in prefix.iter().chain(suffix) {
self.infer_pat(*pat_id, &elem_ty, default_bm);
}
Ty::apply_one(container_ty, elem_ty)
}
_ => Ty::Unknown,
};

View File

@ -54,6 +54,7 @@ fn test(x: &i32) {
[144; 145) 'e': {unknown}
[158; 205) 'if let... }': ()
[165; 170) '[val]': [{unknown}]
[166; 169) 'val': {unknown}
[173; 176) 'opt': [{unknown}]
[177; 205) '{ ... }': ()
[191; 192) 'h': {unknown}
@ -184,6 +185,46 @@ fn test() {
);
}
#[test]
fn infer_pattern_match_arr() {
assert_snapshot!(
infer(r#"
fn test() {
let arr: [f64; 2] = [0.0, 1.0];
match arr {
[1.0, a] => {
a;
},
[b, c] => {
b;
c;
}
}
}
"#),
@r###"
[11; 180) '{ ... } }': ()
[21; 24) 'arr': [f64; _]
[37; 47) '[0.0, 1.0]': [f64; _]
[38; 41) '0.0': f64
[43; 46) '1.0': f64
[53; 178) 'match ... }': ()
[59; 62) 'arr': [f64; _]
[73; 81) '[1.0, a]': [f64; _]
[74; 77) '1.0': f64
[79; 80) 'a': f64
[85; 111) '{ ... }': ()
[99; 100) 'a': f64
[121; 127) '[b, c]': [f64; _]
[122; 123) 'b': f64
[125; 126) 'c': f64
[131; 172) '{ ... }': ()
[145; 146) 'b': f64
[160; 161) 'c': f64
"###
);
}
#[test]
fn infer_adt_pattern() {
assert_snapshot!(