diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 39 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 2 |
2 files changed, 36 insertions, 5 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 8f7e75309..c6d442ec4 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -329,13 +329,23 @@ impl Expr { | |||
329 | pub struct PatId(RawId); | 329 | pub struct PatId(RawId); |
330 | impl_arena_id!(PatId); | 330 | impl_arena_id!(PatId); |
331 | 331 | ||
332 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
333 | pub struct FieldPat { | ||
334 | name: Name, | ||
335 | pat: Option<PatId>, | ||
336 | } | ||
337 | |||
332 | /// Close relative to rustc's hir::PatKind | 338 | /// Close relative to rustc's hir::PatKind |
333 | #[derive(Debug, Clone, Eq, PartialEq)] | 339 | #[derive(Debug, Clone, Eq, PartialEq)] |
334 | pub enum Pat { | 340 | pub enum Pat { |
335 | Missing, // do we need this? | 341 | Missing, // do we need this? |
336 | Wild, | 342 | Wild, |
337 | Tuple(Vec<PatId>), | 343 | Tuple(Vec<PatId>), |
338 | Struct, // TODO | 344 | Struct { |
345 | path: Option<Path>, | ||
346 | args: Vec<FieldPat>, | ||
347 | // TODO: 'ellipsis' option | ||
348 | }, | ||
339 | Range { | 349 | Range { |
340 | start: ExprId, | 350 | start: ExprId, |
341 | end: ExprId, | 351 | end: ExprId, |
@@ -802,11 +812,30 @@ impl ExprCollector { | |||
802 | Pat::Tuple(args) | 812 | Pat::Tuple(args) |
803 | } | 813 | } |
804 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, | 814 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, |
815 | ast::PatKind::StructPat(p) => { | ||
816 | let path = p.path().and_then(Path::from_ast); | ||
817 | |||
818 | if let Some(field_list) = p.field_pat_list() { | ||
819 | let fields = field_list | ||
820 | .field_pats() | ||
821 | .into_iter() | ||
822 | .map(|f| FieldPat { | ||
823 | name: Name::new(f.ident), | ||
824 | pat: f.pat.as_ref().map(|p| self.collect_pat(p)), | ||
825 | }) | ||
826 | .collect(); | ||
827 | |||
828 | Pat::Struct { | ||
829 | path: path, | ||
830 | args: fields, | ||
831 | } | ||
832 | } else { | ||
833 | Pat::Missing | ||
834 | } | ||
835 | } | ||
836 | |||
805 | // TODO: implement | 837 | // TODO: implement |
806 | ast::PatKind::FieldPatList(_) | 838 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
807 | | ast::PatKind::SlicePat(_) | ||
808 | | ast::PatKind::StructPat(_) | ||
809 | | ast::PatKind::RangePat(_) => Pat::Missing, | ||
810 | }; | 839 | }; |
811 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); | 840 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); |
812 | self.alloc_pat(pattern, syntax_ptr) | 841 | self.alloc_pat(pattern, syntax_ptr) |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index cdecbd064..3e1a4f02e 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -877,6 +877,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
877 | fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty { | 877 | fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty { |
878 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 878 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
879 | 879 | ||
880 | // FIXME: we can do some inference even if the expected ty isnt already | ||
881 | // of the right form | ||
880 | let ty = match (&body[pat], &expected.ty) { | 882 | let ty = match (&body[pat], &expected.ty) { |
881 | (Pat::Tuple(ref args), &Ty::Tuple(ref tuple_args)) | 883 | (Pat::Tuple(ref args), &Ty::Tuple(ref tuple_args)) |
882 | if args.len() == tuple_args.len() => | 884 | if args.len() == tuple_args.len() => |