diff options
author | Josh Mcguigan <[email protected]> | 2020-03-01 22:02:32 +0000 |
---|---|---|
committer | Josh Mcguigan <[email protected]> | 2020-03-01 22:02:32 +0000 |
commit | f5efa17515a543c1405ecad2caf93ed25052500e (patch) | |
tree | cb91b80bee65f81bb408ab0c1f1240733f3156f1 /crates/ra_hir_ty | |
parent | b9ef7a6b987eea4b0b14298fbbe44d912806f50f (diff) |
handle array pattern matching type inference
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/patterns.rs | 41 |
2 files changed, 55 insertions, 10 deletions
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index 06b09af82..623e52599 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -12,7 +12,7 @@ use hir_expand::name::Name; | |||
12 | use test_utils::tested_by; | 12 | use test_utils::tested_by; |
13 | 13 | ||
14 | use super::{BindingMode, InferenceContext}; | 14 | use super::{BindingMode, InferenceContext}; |
15 | use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, ApplicationTy}; | 15 | use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor}; |
16 | 16 | ||
17 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 17 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
18 | fn infer_tuple_struct_pat( | 18 | fn infer_tuple_struct_pat( |
@@ -186,17 +186,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
186 | return inner_ty; | 186 | return inner_ty; |
187 | } | 187 | } |
188 | Pat::Slice { prefix, slice: _slice, suffix } => { | 188 | Pat::Slice { prefix, slice: _slice, suffix } => { |
189 | let ty = if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Slice, parameters }) = expected { | 189 | let (container_ty, elem_ty) = match &expected { |
190 | for pat_id in prefix.iter().chain(suffix) { | 190 | ty_app!(TypeCtor::Array, st) => { |
191 | self.infer_pat(*pat_id, parameters.as_single(), default_bm); | 191 | (TypeCtor::Array, st.as_single().clone()) |
192 | } | 192 | }, |
193 | 193 | ty_app!(TypeCtor::Slice, st) => { | |
194 | parameters.as_single().clone() | 194 | (TypeCtor::Slice, st.as_single().clone()) |
195 | } else { | 195 | }, |
196 | Ty::Unknown | 196 | _ => (TypeCtor::Slice, Ty::Unknown), |
197 | }; | 197 | }; |
198 | 198 | ||
199 | Ty::apply_one(TypeCtor::Slice, ty) | 199 | for pat_id in prefix.iter().chain(suffix) { |
200 | self.infer_pat(*pat_id, &elem_ty, default_bm); | ||
201 | } | ||
202 | |||
203 | Ty::apply_one(container_ty, elem_ty) | ||
200 | } | 204 | } |
201 | _ => Ty::Unknown, | 205 | _ => Ty::Unknown, |
202 | }; | 206 | }; |
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index d8e95112f..76aa32024 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs | |||
@@ -54,6 +54,7 @@ fn test(x: &i32) { | |||
54 | [144; 145) 'e': {unknown} | 54 | [144; 145) 'e': {unknown} |
55 | [158; 205) 'if let... }': () | 55 | [158; 205) 'if let... }': () |
56 | [165; 170) '[val]': [{unknown}] | 56 | [165; 170) '[val]': [{unknown}] |
57 | [166; 169) 'val': {unknown} | ||
57 | [173; 176) 'opt': [{unknown}] | 58 | [173; 176) 'opt': [{unknown}] |
58 | [177; 205) '{ ... }': () | 59 | [177; 205) '{ ... }': () |
59 | [191; 192) 'h': {unknown} | 60 | [191; 192) 'h': {unknown} |
@@ -185,6 +186,46 @@ fn test() { | |||
185 | } | 186 | } |
186 | 187 | ||
187 | #[test] | 188 | #[test] |
189 | fn infer_pattern_match_arr() { | ||
190 | assert_snapshot!( | ||
191 | infer(r#" | ||
192 | fn test() { | ||
193 | let arr: [f64; 2] = [0.0, 1.0]; | ||
194 | match arr { | ||
195 | [1.0, a] => { | ||
196 | a; | ||
197 | }, | ||
198 | [b, c] => { | ||
199 | b; | ||
200 | c; | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | "#), | ||
205 | @r###" | ||
206 | [11; 180) '{ ... } }': () | ||
207 | [21; 24) 'arr': [f64; _] | ||
208 | [37; 47) '[0.0, 1.0]': [f64; _] | ||
209 | [38; 41) '0.0': f64 | ||
210 | [43; 46) '1.0': f64 | ||
211 | [53; 178) 'match ... }': () | ||
212 | [59; 62) 'arr': [f64; _] | ||
213 | [73; 81) '[1.0, a]': [f64; _] | ||
214 | [74; 77) '1.0': f64 | ||
215 | [79; 80) 'a': f64 | ||
216 | [85; 111) '{ ... }': () | ||
217 | [99; 100) 'a': f64 | ||
218 | [121; 127) '[b, c]': [f64; _] | ||
219 | [122; 123) 'b': f64 | ||
220 | [125; 126) 'c': f64 | ||
221 | [131; 172) '{ ... }': () | ||
222 | [145; 146) 'b': f64 | ||
223 | [160; 161) 'c': f64 | ||
224 | "### | ||
225 | ); | ||
226 | } | ||
227 | |||
228 | #[test] | ||
188 | fn infer_adt_pattern() { | 229 | fn infer_adt_pattern() { |
189 | assert_snapshot!( | 230 | assert_snapshot!( |
190 | infer(r#" | 231 | infer(r#" |