diff options
author | Marcus Klaas de Vries <[email protected]> | 2019-01-16 23:08:10 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-19 12:37:25 +0000 |
commit | ac216880f5d1a3e5727b96d7b22433beec10382b (patch) | |
tree | f9d87289f7d870e5346ecb5c007a9ea43e63651b /crates/ra_hir/src | |
parent | 3340807bd24f398dca158e85eebae74012d8ef4b (diff) |
Implement unlabeled struct field pattern inference
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 5 |
3 files changed, 15 insertions, 16 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 893bad9cd..e7235c1a1 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -332,7 +332,7 @@ impl_arena_id!(PatId); | |||
332 | #[derive(Debug, Clone, Eq, PartialEq)] | 332 | #[derive(Debug, Clone, Eq, PartialEq)] |
333 | pub struct FieldPat { | 333 | pub struct FieldPat { |
334 | pub(crate) name: Name, | 334 | pub(crate) name: Name, |
335 | pub(crate) pat: Option<PatId>, | 335 | pub(crate) pat: PatId, |
336 | } | 336 | } |
337 | 337 | ||
338 | /// Close relative to rustc's hir::PatKind | 338 | /// Close relative to rustc's hir::PatKind |
@@ -393,7 +393,7 @@ impl Pat { | |||
393 | total_iter.map(|pat| *pat).for_each(f); | 393 | total_iter.map(|pat| *pat).for_each(f); |
394 | } | 394 | } |
395 | Pat::Struct { args, .. } => { | 395 | Pat::Struct { args, .. } => { |
396 | args.iter().filter_map(|a| a.pat).for_each(f); | 396 | args.iter().map(|f| f.pat).for_each(f); |
397 | } | 397 | } |
398 | } | 398 | } |
399 | } | 399 | } |
@@ -821,9 +821,10 @@ impl ExprCollector { | |||
821 | .expect("every struct should have a field list") | 821 | .expect("every struct should have a field list") |
822 | .field_pats() | 822 | .field_pats() |
823 | .into_iter() | 823 | .into_iter() |
824 | .map(|f| FieldPat { | 824 | .map(|f| { |
825 | name: Name::new(f.ident), | 825 | let name = Name::new(f.ident); |
826 | pat: f.pat.as_ref().map(|p| self.collect_pat(p)), | 826 | let pat = self.collect_pat(&*f.pat); |
827 | FieldPat { name, pat } | ||
827 | }) | 828 | }) |
828 | .collect(); | 829 | .collect(); |
829 | 830 | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 6bad61a2a..66940ec30 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -937,19 +937,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
937 | }; | 937 | }; |
938 | 938 | ||
939 | for sub_pat in sub_pats { | 939 | for sub_pat in sub_pats { |
940 | let tyref = fields | 940 | let matching_field = fields.iter().find(|field| field.name == sub_pat.name); |
941 | .iter() | ||
942 | .find(|field| field.name == sub_pat.name) | ||
943 | .map(|field| &field.type_ref); | ||
944 | 941 | ||
945 | if let Some(typeref) = tyref { | 942 | if let Some(field) = matching_field { |
943 | let typeref = &field.type_ref; | ||
946 | let sub_ty = Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), typeref); | 944 | let sub_ty = Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), typeref); |
947 | 945 | self.infer_pat(sub_pat.pat, &Expectation::has_type(sub_ty)); | |
948 | if let Some(pat) = sub_pat.pat { | ||
949 | self.infer_pat(pat, &Expectation::has_type(sub_ty)); | ||
950 | } else { | ||
951 | // TODO: deal with this case: S { x, y } | ||
952 | } | ||
953 | } | 946 | } |
954 | } | 947 | } |
955 | 948 | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 75fe2cc6e..10842f967 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -389,6 +389,11 @@ fn test() { | |||
389 | 389 | ||
390 | let S(y, z) = foo; | 390 | let S(y, z) = foo; |
391 | let E::A { x: new_var } = e; | 391 | let E::A { x: new_var } = e; |
392 | |||
393 | match e { | ||
394 | E::A { x } => x, | ||
395 | E::B => 1, | ||
396 | }; | ||
392 | } | 397 | } |
393 | "#, | 398 | "#, |
394 | "adt_pattern.txt", | 399 | "adt_pattern.txt", |