aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-16 23:08:10 +0000
committerAleksey Kladov <[email protected]>2019-01-19 12:37:25 +0000
commitac216880f5d1a3e5727b96d7b22433beec10382b (patch)
treef9d87289f7d870e5346ecb5c007a9ea43e63651b /crates/ra_hir/src
parent3340807bd24f398dca158e85eebae74012d8ef4b (diff)
Implement unlabeled struct field pattern inference
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs11
-rw-r--r--crates/ra_hir/src/ty.rs15
-rw-r--r--crates/ra_hir/src/ty/tests.rs5
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)]
333pub struct FieldPat { 333pub 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",