aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs39
-rw-r--r--crates/ra_hir/src/ty.rs2
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 {
329pub struct PatId(RawId); 329pub struct PatId(RawId);
330impl_arena_id!(PatId); 330impl_arena_id!(PatId);
331 331
332#[derive(Debug, Clone, Eq, PartialEq)]
333pub 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)]
334pub enum Pat { 340pub 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() =>