Merge #3387
3387: Type inference for slice patterns r=flodiebold a=JoshMcguigan Fixes #3043 Notes to reviewer: 1. This only works if `expected` is `Ty::Apply`. I'm not sure of the implications of this. 1. This only works if the slice pattern only has a prefix. I think this means it doesn't work for subslice patterns, which are currently only available behind a feature flag. Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>
This commit is contained in:
commit
b71fc18abe
@ -185,6 +185,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||
self.write_pat_ty(pat, bound_ty);
|
||||
return inner_ty;
|
||||
}
|
||||
Pat::Slice { prefix, slice: _slice, suffix } => {
|
||||
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),
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
// use a new type variable if we got Ty::Unknown here
|
||||
|
@ -53,8 +53,9 @@ fn test(x: &i32) {
|
||||
[140; 141) 'g': {unknown}
|
||||
[144; 145) 'e': {unknown}
|
||||
[158; 205) 'if let... }': ()
|
||||
[165; 170) '[val]': {unknown}
|
||||
[173; 176) 'opt': {unknown}
|
||||
[165; 170) '[val]': [{unknown}]
|
||||
[166; 169) 'val': {unknown}
|
||||
[173; 176) 'opt': [{unknown}]
|
||||
[177; 205) '{ ... }': ()
|
||||
[191; 192) 'h': {unknown}
|
||||
[195; 198) 'val': {unknown}
|
||||
@ -136,6 +137,94 @@ fn test() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_pattern_match_slice() {
|
||||
assert_snapshot!(
|
||||
infer(r#"
|
||||
fn test() {
|
||||
let slice: &[f64] = &[0.0];
|
||||
match slice {
|
||||
&[] => {},
|
||||
&[a] => {
|
||||
a;
|
||||
},
|
||||
&[b, c] => {
|
||||
b;
|
||||
c;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
"#),
|
||||
@r###"
|
||||
[11; 210) '{ ... } }': ()
|
||||
[21; 26) 'slice': &[f64]
|
||||
[37; 43) '&[0.0]': &[f64; _]
|
||||
[38; 43) '[0.0]': [f64; _]
|
||||
[39; 42) '0.0': f64
|
||||
[49; 208) 'match ... }': ()
|
||||
[55; 60) 'slice': &[f64]
|
||||
[71; 74) '&[]': &[f64]
|
||||
[72; 74) '[]': [f64]
|
||||
[78; 80) '{}': ()
|
||||
[90; 94) '&[a]': &[f64]
|
||||
[91; 94) '[a]': [f64]
|
||||
[92; 93) 'a': f64
|
||||
[98; 124) '{ ... }': ()
|
||||
[112; 113) 'a': f64
|
||||
[134; 141) '&[b, c]': &[f64]
|
||||
[135; 141) '[b, c]': [f64]
|
||||
[136; 137) 'b': f64
|
||||
[139; 140) 'c': f64
|
||||
[145; 186) '{ ... }': ()
|
||||
[159; 160) 'b': f64
|
||||
[174; 175) 'c': f64
|
||||
[195; 196) '_': &[f64]
|
||||
[200; 202) '{}': ()
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[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!(
|
||||
|
Loading…
x
Reference in New Issue
Block a user