diff options
Diffstat (limited to 'crates/ra_hir/src/expr.rs')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6e98ebc69..8f7e75309 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -329,9 +329,25 @@ 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 | /// Close relative to rustc's hir::PatKind | ||
332 | #[derive(Debug, Clone, Eq, PartialEq)] | 333 | #[derive(Debug, Clone, Eq, PartialEq)] |
333 | pub enum Pat { | 334 | pub enum Pat { |
334 | Missing, | 335 | Missing, // do we need this? |
336 | Wild, | ||
337 | Tuple(Vec<PatId>), | ||
338 | Struct, // TODO | ||
339 | Range { | ||
340 | start: ExprId, | ||
341 | end: ExprId, | ||
342 | }, | ||
343 | Box(PatId), | ||
344 | Slice { | ||
345 | prefix: Vec<PatId>, | ||
346 | rest: Option<PatId>, | ||
347 | suffix: Vec<PatId>, | ||
348 | }, | ||
349 | Path(Path), | ||
350 | Lit(ExprId), | ||
335 | Bind { | 351 | Bind { |
336 | name: Name, | 352 | name: Name, |
337 | }, | 353 | }, |
@@ -348,11 +364,25 @@ pub enum Pat { | |||
348 | impl Pat { | 364 | impl Pat { |
349 | pub fn walk_child_pats(&self, mut f: impl FnMut(PatId)) { | 365 | pub fn walk_child_pats(&self, mut f: impl FnMut(PatId)) { |
350 | match self { | 366 | match self { |
351 | Pat::Missing | Pat::Bind { .. } => {} | 367 | Pat::Range { .. } |
352 | Pat::TupleStruct { args, .. } => { | 368 | | Pat::Lit(..) |
369 | | Pat::Path(..) | ||
370 | | Pat::Wild | ||
371 | | Pat::Missing | ||
372 | | Pat::Bind { .. } => {} | ||
373 | Pat::Tuple(args) | Pat::TupleStruct { args, .. } => { | ||
353 | args.iter().map(|pat| *pat).for_each(f); | 374 | args.iter().map(|pat| *pat).for_each(f); |
354 | } | 375 | } |
355 | Pat::Ref { pat, .. } => f(*pat), | 376 | Pat::Ref { pat, .. } | Pat::Box(pat) => f(*pat), |
377 | Pat::Slice { | ||
378 | prefix, | ||
379 | rest, | ||
380 | suffix, | ||
381 | } => { | ||
382 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); | ||
383 | total_iter.map(|pat| *pat).for_each(f); | ||
384 | } | ||
385 | Pat::Struct { .. } => {} // TODO | ||
356 | } | 386 | } |
357 | } | 387 | } |
358 | } | 388 | } |
@@ -745,30 +775,41 @@ impl ExprCollector { | |||
745 | } | 775 | } |
746 | 776 | ||
747 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { | 777 | fn collect_pat(&mut self, pat: &ast::Pat) -> PatId { |
748 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); | 778 | let pattern = match pat.kind() { |
749 | match pat.kind() { | ||
750 | ast::PatKind::BindPat(bp) => { | 779 | ast::PatKind::BindPat(bp) => { |
751 | let name = bp | 780 | let name = bp |
752 | .name() | 781 | .name() |
753 | .map(|nr| nr.as_name()) | 782 | .map(|nr| nr.as_name()) |
754 | .unwrap_or_else(Name::missing); | 783 | .unwrap_or_else(Name::missing); |
755 | self.alloc_pat(Pat::Bind { name }, syntax_ptr) | 784 | Pat::Bind { name } |
756 | } | 785 | } |
757 | ast::PatKind::TupleStructPat(p) => { | 786 | ast::PatKind::TupleStructPat(p) => { |
758 | let path = p.path().and_then(Path::from_ast); | 787 | let path = p.path().and_then(Path::from_ast); |
759 | let args = p.args().map(|p| self.collect_pat(p)).collect(); | 788 | let args = p.args().map(|p| self.collect_pat(p)).collect(); |
760 | self.alloc_pat(Pat::TupleStruct { path, args }, syntax_ptr) | 789 | Pat::TupleStruct { path, args } |
761 | } | 790 | } |
762 | ast::PatKind::RefPat(p) => { | 791 | ast::PatKind::RefPat(p) => { |
763 | let pat = self.collect_pat_opt(p.pat()); | 792 | let pat = self.collect_pat_opt(p.pat()); |
764 | let mutability = Mutability::from_mutable(p.is_mut()); | 793 | let mutability = Mutability::from_mutable(p.is_mut()); |
765 | self.alloc_pat(Pat::Ref { pat, mutability }, syntax_ptr) | 794 | Pat::Ref { pat, mutability } |
766 | } | 795 | } |
767 | _ => { | 796 | ast::PatKind::PathPat(p) => { |
768 | // TODO | 797 | let path = p.path().and_then(Path::from_ast); |
769 | self.alloc_pat(Pat::Missing, syntax_ptr) | 798 | path.map(|path| Pat::Path(path)).unwrap_or(Pat::Missing) |
770 | } | 799 | } |
771 | } | 800 | ast::PatKind::TuplePat(p) => { |
801 | let args = p.args().map(|p| self.collect_pat(p)).collect(); | ||
802 | Pat::Tuple(args) | ||
803 | } | ||
804 | ast::PatKind::PlaceholderPat(_) => Pat::Wild, | ||
805 | // TODO: implement | ||
806 | ast::PatKind::FieldPatList(_) | ||
807 | | ast::PatKind::SlicePat(_) | ||
808 | | ast::PatKind::StructPat(_) | ||
809 | | ast::PatKind::RangePat(_) => Pat::Missing, | ||
810 | }; | ||
811 | let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); | ||
812 | self.alloc_pat(pattern, syntax_ptr) | ||
772 | } | 813 | } |
773 | 814 | ||
774 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { | 815 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { |