From ac216880f5d1a3e5727b96d7b22433beec10382b Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Thu, 17 Jan 2019 00:08:10 +0100 Subject: Implement unlabeled struct field pattern inference --- crates/ra_hir/src/expr.rs | 11 ++++++----- crates/ra_hir/src/ty.rs | 15 ++++----------- crates/ra_hir/src/ty/tests.rs | 5 +++++ 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'crates/ra_hir/src') 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); #[derive(Debug, Clone, Eq, PartialEq)] pub struct FieldPat { pub(crate) name: Name, - pub(crate) pat: Option, + pub(crate) pat: PatId, } /// Close relative to rustc's hir::PatKind @@ -393,7 +393,7 @@ impl Pat { total_iter.map(|pat| *pat).for_each(f); } Pat::Struct { args, .. } => { - args.iter().filter_map(|a| a.pat).for_each(f); + args.iter().map(|f| f.pat).for_each(f); } } } @@ -821,9 +821,10 @@ impl ExprCollector { .expect("every struct should have a field list") .field_pats() .into_iter() - .map(|f| FieldPat { - name: Name::new(f.ident), - pat: f.pat.as_ref().map(|p| self.collect_pat(p)), + .map(|f| { + let name = Name::new(f.ident); + let pat = self.collect_pat(&*f.pat); + FieldPat { name, pat } }) .collect(); 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> { }; for sub_pat in sub_pats { - let tyref = fields - .iter() - .find(|field| field.name == sub_pat.name) - .map(|field| &field.type_ref); + let matching_field = fields.iter().find(|field| field.name == sub_pat.name); - if let Some(typeref) = tyref { + if let Some(field) = matching_field { + let typeref = &field.type_ref; let sub_ty = Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), typeref); - - if let Some(pat) = sub_pat.pat { - self.infer_pat(pat, &Expectation::has_type(sub_ty)); - } else { - // TODO: deal with this case: S { x, y } - } + self.infer_pat(sub_pat.pat, &Expectation::has_type(sub_ty)); } } 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() { let S(y, z) = foo; let E::A { x: new_var } = e; + + match e { + E::A { x } => x, + E::B => 1, + }; } "#, "adt_pattern.txt", -- cgit v1.2.3