diff options
author | Dmitry <[email protected]> | 2020-08-09 14:35:51 +0100 |
---|---|---|
committer | Dmitry <[email protected]> | 2020-08-09 14:39:32 +0100 |
commit | 8068302fefc75440b823f4bf1731a5f347d7c767 (patch) | |
tree | 251b967182e79bc82a58c2fb208c688f6152df1f /crates/ra_hir_def/src/body | |
parent | 1a43a0f63e0008787225abb6fb2baef97b6a39e0 (diff) | |
parent | 8a57afe5a4bfab40072a83f7dc4ca560bf860919 (diff) |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 163 |
1 files changed, 87 insertions, 76 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index c6bc85e2f..f5c37edb3 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -1,6 +1,8 @@ | |||
1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` | 1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` |
2 | //! representation. | 2 | //! representation. |
3 | 3 | ||
4 | use std::{any::type_name, sync::Arc}; | ||
5 | |||
4 | use either::Either; | 6 | use either::Either; |
5 | use hir_expand::{ | 7 | use hir_expand::{ |
6 | hygiene::Hygiene, | 8 | hygiene::Hygiene, |
@@ -10,11 +12,12 @@ use hir_expand::{ | |||
10 | use ra_arena::Arena; | 12 | use ra_arena::Arena; |
11 | use ra_syntax::{ | 13 | use ra_syntax::{ |
12 | ast::{ | 14 | ast::{ |
13 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, | 15 | self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner, |
14 | SlicePatComponents, TypeAscriptionOwner, | 16 | SlicePatComponents, |
15 | }, | 17 | }, |
16 | AstNode, AstPtr, | 18 | AstNode, AstPtr, |
17 | }; | 19 | }; |
20 | use rustc_hash::FxHashMap; | ||
18 | use test_utils::mark; | 21 | use test_utils::mark; |
19 | 22 | ||
20 | use crate::{ | 23 | use crate::{ |
@@ -35,9 +38,6 @@ use crate::{ | |||
35 | }; | 38 | }; |
36 | 39 | ||
37 | use super::{ExprSource, PatSource}; | 40 | use super::{ExprSource, PatSource}; |
38 | use ast::AstChildren; | ||
39 | use rustc_hash::FxHashMap; | ||
40 | use std::{any::type_name, sync::Arc}; | ||
41 | 41 | ||
42 | pub(crate) struct LowerCtx { | 42 | pub(crate) struct LowerCtx { |
43 | hygiene: Hygiene, | 43 | hygiene: Hygiene, |
@@ -224,9 +224,22 @@ impl ExprCollector<'_> { | |||
224 | self.alloc_expr(Expr::Unsafe { body }, syntax_ptr) | 224 | self.alloc_expr(Expr::Unsafe { body }, syntax_ptr) |
225 | } | 225 | } |
226 | // FIXME: we need to record these effects somewhere... | 226 | // FIXME: we need to record these effects somewhere... |
227 | ast::Effect::Async(_) | ast::Effect::Label(_) => { | 227 | ast::Effect::Label(label) => match e.block_expr() { |
228 | self.collect_block_opt(e.block_expr()) | 228 | Some(block) => { |
229 | } | 229 | let res = self.collect_block(block); |
230 | match &mut self.body.exprs[res] { | ||
231 | Expr::Block { label: block_label, .. } => { | ||
232 | *block_label = | ||
233 | label.lifetime_token().map(|t| Name::new_lifetime(&t)) | ||
234 | } | ||
235 | _ => unreachable!(), | ||
236 | } | ||
237 | res | ||
238 | } | ||
239 | None => self.missing_expr(), | ||
240 | }, | ||
241 | // FIXME: we need to record these effects somewhere... | ||
242 | ast::Effect::Async(_) => self.collect_block_opt(e.block_expr()), | ||
230 | }, | 243 | }, |
231 | ast::Expr::BlockExpr(e) => self.collect_block(e), | 244 | ast::Expr::BlockExpr(e) => self.collect_block(e), |
232 | ast::Expr::LoopExpr(e) => { | 245 | ast::Expr::LoopExpr(e) => { |
@@ -324,7 +337,7 @@ impl ExprCollector<'_> { | |||
324 | }; | 337 | }; |
325 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 338 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
326 | let generic_args = | 339 | let generic_args = |
327 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); | 340 | e.generic_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); |
328 | self.alloc_expr( | 341 | self.alloc_expr( |
329 | Expr::MethodCall { receiver, method_name, args, generic_args }, | 342 | Expr::MethodCall { receiver, method_name, args, generic_args }, |
330 | syntax_ptr, | 343 | syntax_ptr, |
@@ -379,10 +392,10 @@ impl ExprCollector<'_> { | |||
379 | let expr = e.expr().map(|e| self.collect_expr(e)); | 392 | let expr = e.expr().map(|e| self.collect_expr(e)); |
380 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) | 393 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) |
381 | } | 394 | } |
382 | ast::Expr::RecordLit(e) => { | 395 | ast::Expr::RecordExpr(e) => { |
383 | let path = e.path().and_then(|path| self.expander.parse_path(path)); | 396 | let path = e.path().and_then(|path| self.expander.parse_path(path)); |
384 | let mut field_ptrs = Vec::new(); | 397 | let mut field_ptrs = Vec::new(); |
385 | let record_lit = if let Some(nfl) = e.record_field_list() { | 398 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { |
386 | let fields = nfl | 399 | let fields = nfl |
387 | .fields() | 400 | .fields() |
388 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) | 401 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) |
@@ -432,7 +445,7 @@ impl ExprCollector<'_> { | |||
432 | } | 445 | } |
433 | ast::Expr::CastExpr(e) => { | 446 | ast::Expr::CastExpr(e) => { |
434 | let expr = self.collect_expr_opt(e.expr()); | 447 | let expr = self.collect_expr_opt(e.expr()); |
435 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); | 448 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty()); |
436 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) | 449 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) |
437 | } | 450 | } |
438 | ast::Expr::RefExpr(e) => { | 451 | ast::Expr::RefExpr(e) => { |
@@ -460,22 +473,19 @@ impl ExprCollector<'_> { | |||
460 | self.alloc_expr(Expr::Missing, syntax_ptr) | 473 | self.alloc_expr(Expr::Missing, syntax_ptr) |
461 | } | 474 | } |
462 | } | 475 | } |
463 | ast::Expr::LambdaExpr(e) => { | 476 | ast::Expr::ClosureExpr(e) => { |
464 | let mut args = Vec::new(); | 477 | let mut args = Vec::new(); |
465 | let mut arg_types = Vec::new(); | 478 | let mut arg_types = Vec::new(); |
466 | if let Some(pl) = e.param_list() { | 479 | if let Some(pl) = e.param_list() { |
467 | for param in pl.params() { | 480 | for param in pl.params() { |
468 | let pat = self.collect_pat_opt(param.pat()); | 481 | let pat = self.collect_pat_opt(param.pat()); |
469 | let type_ref = | 482 | let type_ref = param.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); |
470 | param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); | ||
471 | args.push(pat); | 483 | args.push(pat); |
472 | arg_types.push(type_ref); | 484 | arg_types.push(type_ref); |
473 | } | 485 | } |
474 | } | 486 | } |
475 | let ret_type = e | 487 | let ret_type = |
476 | .ret_type() | 488 | e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&self.ctx(), it)); |
477 | .and_then(|r| r.type_ref()) | ||
478 | .map(|it| TypeRef::from_ast(&self.ctx(), it)); | ||
479 | let body = self.collect_expr_opt(e.body()); | 489 | let body = self.collect_expr_opt(e.body()); |
480 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) | 490 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) |
481 | } | 491 | } |
@@ -486,7 +496,7 @@ impl ExprCollector<'_> { | |||
486 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) | 496 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) |
487 | } | 497 | } |
488 | ast::Expr::TupleExpr(e) => { | 498 | ast::Expr::TupleExpr(e) => { |
489 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); | 499 | let exprs = e.fields().map(|expr| self.collect_expr(expr)).collect(); |
490 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) | 500 | self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) |
491 | } | 501 | } |
492 | ast::Expr::BoxExpr(e) => { | 502 | ast::Expr::BoxExpr(e) => { |
@@ -559,9 +569,6 @@ impl ExprCollector<'_> { | |||
559 | } | 569 | } |
560 | } | 570 | } |
561 | } | 571 | } |
562 | |||
563 | // FIXME implement HIR for these: | ||
564 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
565 | } | 572 | } |
566 | } | 573 | } |
567 | 574 | ||
@@ -604,76 +611,84 @@ impl ExprCollector<'_> { | |||
604 | self.collect_block_items(&block); | 611 | self.collect_block_items(&block); |
605 | let statements = block | 612 | let statements = block |
606 | .statements() | 613 | .statements() |
607 | .map(|s| match s { | 614 | .filter_map(|s| { |
608 | ast::Stmt::LetStmt(stmt) => { | 615 | let stmt = match s { |
609 | let pat = self.collect_pat_opt(stmt.pat()); | 616 | ast::Stmt::LetStmt(stmt) => { |
610 | let type_ref = | 617 | let pat = self.collect_pat_opt(stmt.pat()); |
611 | stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); | 618 | let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); |
612 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 619 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
613 | Statement::Let { pat, type_ref, initializer } | 620 | Statement::Let { pat, type_ref, initializer } |
614 | } | 621 | } |
615 | ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())), | 622 | ast::Stmt::ExprStmt(stmt) => { |
623 | Statement::Expr(self.collect_expr_opt(stmt.expr())) | ||
624 | } | ||
625 | ast::Stmt::Item(_) => return None, | ||
626 | }; | ||
627 | Some(stmt) | ||
616 | }) | 628 | }) |
617 | .collect(); | 629 | .collect(); |
618 | let tail = block.expr().map(|e| self.collect_expr(e)); | 630 | let tail = block.expr().map(|e| self.collect_expr(e)); |
619 | let label = block.label().and_then(|l| l.lifetime_token()).map(|t| Name::new_lifetime(&t)); | 631 | self.alloc_expr(Expr::Block { statements, tail, label: None }, syntax_node_ptr) |
620 | self.alloc_expr(Expr::Block { statements, tail, label }, syntax_node_ptr) | ||
621 | } | 632 | } |
622 | 633 | ||
623 | fn collect_block_items(&mut self, block: &ast::BlockExpr) { | 634 | fn collect_block_items(&mut self, block: &ast::BlockExpr) { |
624 | let container = ContainerId::DefWithBodyId(self.def); | 635 | let container = ContainerId::DefWithBodyId(self.def); |
625 | 636 | ||
626 | let items = block | 637 | let items = block |
627 | .items() | 638 | .statements() |
639 | .filter_map(|stmt| match stmt { | ||
640 | ast::Stmt::Item(it) => Some(it), | ||
641 | ast::Stmt::LetStmt(_) | ast::Stmt::ExprStmt(_) => None, | ||
642 | }) | ||
628 | .filter_map(|item| { | 643 | .filter_map(|item| { |
629 | let (def, name): (ModuleDefId, Option<ast::Name>) = match item { | 644 | let (def, name): (ModuleDefId, Option<ast::Name>) = match item { |
630 | ast::ModuleItem::FnDef(def) => { | 645 | ast::Item::Fn(def) => { |
631 | let id = self.find_inner_item(&def)?; | 646 | let id = self.find_inner_item(&def)?; |
632 | ( | 647 | ( |
633 | FunctionLoc { container: container.into(), id }.intern(self.db).into(), | 648 | FunctionLoc { container: container.into(), id }.intern(self.db).into(), |
634 | def.name(), | 649 | def.name(), |
635 | ) | 650 | ) |
636 | } | 651 | } |
637 | ast::ModuleItem::TypeAliasDef(def) => { | 652 | ast::Item::TypeAlias(def) => { |
638 | let id = self.find_inner_item(&def)?; | 653 | let id = self.find_inner_item(&def)?; |
639 | ( | 654 | ( |
640 | TypeAliasLoc { container: container.into(), id }.intern(self.db).into(), | 655 | TypeAliasLoc { container: container.into(), id }.intern(self.db).into(), |
641 | def.name(), | 656 | def.name(), |
642 | ) | 657 | ) |
643 | } | 658 | } |
644 | ast::ModuleItem::ConstDef(def) => { | 659 | ast::Item::Const(def) => { |
645 | let id = self.find_inner_item(&def)?; | 660 | let id = self.find_inner_item(&def)?; |
646 | ( | 661 | ( |
647 | ConstLoc { container: container.into(), id }.intern(self.db).into(), | 662 | ConstLoc { container: container.into(), id }.intern(self.db).into(), |
648 | def.name(), | 663 | def.name(), |
649 | ) | 664 | ) |
650 | } | 665 | } |
651 | ast::ModuleItem::StaticDef(def) => { | 666 | ast::Item::Static(def) => { |
652 | let id = self.find_inner_item(&def)?; | 667 | let id = self.find_inner_item(&def)?; |
653 | (StaticLoc { container, id }.intern(self.db).into(), def.name()) | 668 | (StaticLoc { container, id }.intern(self.db).into(), def.name()) |
654 | } | 669 | } |
655 | ast::ModuleItem::StructDef(def) => { | 670 | ast::Item::Struct(def) => { |
656 | let id = self.find_inner_item(&def)?; | 671 | let id = self.find_inner_item(&def)?; |
657 | (StructLoc { container, id }.intern(self.db).into(), def.name()) | 672 | (StructLoc { container, id }.intern(self.db).into(), def.name()) |
658 | } | 673 | } |
659 | ast::ModuleItem::EnumDef(def) => { | 674 | ast::Item::Enum(def) => { |
660 | let id = self.find_inner_item(&def)?; | 675 | let id = self.find_inner_item(&def)?; |
661 | (EnumLoc { container, id }.intern(self.db).into(), def.name()) | 676 | (EnumLoc { container, id }.intern(self.db).into(), def.name()) |
662 | } | 677 | } |
663 | ast::ModuleItem::UnionDef(def) => { | 678 | ast::Item::Union(def) => { |
664 | let id = self.find_inner_item(&def)?; | 679 | let id = self.find_inner_item(&def)?; |
665 | (UnionLoc { container, id }.intern(self.db).into(), def.name()) | 680 | (UnionLoc { container, id }.intern(self.db).into(), def.name()) |
666 | } | 681 | } |
667 | ast::ModuleItem::TraitDef(def) => { | 682 | ast::Item::Trait(def) => { |
668 | let id = self.find_inner_item(&def)?; | 683 | let id = self.find_inner_item(&def)?; |
669 | (TraitLoc { container, id }.intern(self.db).into(), def.name()) | 684 | (TraitLoc { container, id }.intern(self.db).into(), def.name()) |
670 | } | 685 | } |
671 | ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks | 686 | ast::Item::ExternBlock(_) => return None, // FIXME: collect from extern blocks |
672 | ast::ModuleItem::ImplDef(_) | 687 | ast::Item::Impl(_) |
673 | | ast::ModuleItem::UseItem(_) | 688 | | ast::Item::Use(_) |
674 | | ast::ModuleItem::ExternCrateItem(_) | 689 | | ast::Item::ExternCrate(_) |
675 | | ast::ModuleItem::Module(_) | 690 | | ast::Item::Module(_) |
676 | | ast::ModuleItem::MacroCall(_) => return None, | 691 | | ast::Item::MacroCall(_) => return None, |
677 | }; | 692 | }; |
678 | 693 | ||
679 | Some((def, name)) | 694 | Some((def, name)) |
@@ -708,7 +723,7 @@ impl ExprCollector<'_> { | |||
708 | 723 | ||
709 | fn collect_pat(&mut self, pat: ast::Pat) -> PatId { | 724 | fn collect_pat(&mut self, pat: ast::Pat) -> PatId { |
710 | let pattern = match &pat { | 725 | let pattern = match &pat { |
711 | ast::Pat::BindPat(bp) => { | 726 | ast::Pat::IdentPat(bp) => { |
712 | let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 727 | let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
713 | let annotation = | 728 | let annotation = |
714 | BindingAnnotation::new(bp.mut_token().is_some(), bp.ref_token().is_some()); | 729 | BindingAnnotation::new(bp.mut_token().is_some(), bp.ref_token().is_some()); |
@@ -747,7 +762,7 @@ impl ExprCollector<'_> { | |||
747 | } | 762 | } |
748 | ast::Pat::TupleStructPat(p) => { | 763 | ast::Pat::TupleStructPat(p) => { |
749 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 764 | let path = p.path().and_then(|path| self.expander.parse_path(path)); |
750 | let (args, ellipsis) = self.collect_tuple_pat(p.args()); | 765 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); |
751 | Pat::TupleStruct { path, args, ellipsis } | 766 | Pat::TupleStruct { path, args, ellipsis } |
752 | } | 767 | } |
753 | ast::Pat::RefPat(p) => { | 768 | ast::Pat::RefPat(p) => { |
@@ -765,40 +780,36 @@ impl ExprCollector<'_> { | |||
765 | } | 780 | } |
766 | ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat()), | 781 | ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat()), |
767 | ast::Pat::TuplePat(p) => { | 782 | ast::Pat::TuplePat(p) => { |
768 | let (args, ellipsis) = self.collect_tuple_pat(p.args()); | 783 | let (args, ellipsis) = self.collect_tuple_pat(p.fields()); |
769 | Pat::Tuple { args, ellipsis } | 784 | Pat::Tuple { args, ellipsis } |
770 | } | 785 | } |
771 | ast::Pat::PlaceholderPat(_) => Pat::Wild, | 786 | ast::Pat::WildcardPat(_) => Pat::Wild, |
772 | ast::Pat::RecordPat(p) => { | 787 | ast::Pat::RecordPat(p) => { |
773 | let path = p.path().and_then(|path| self.expander.parse_path(path)); | 788 | let path = p.path().and_then(|path| self.expander.parse_path(path)); |
774 | let record_field_pat_list = | 789 | let args: Vec<_> = p |
775 | p.record_field_pat_list().expect("every struct should have a field list"); | 790 | .record_pat_field_list() |
776 | let mut fields: Vec<_> = record_field_pat_list | 791 | .expect("every struct should have a field list") |
777 | .bind_pats() | 792 | .fields() |
778 | .filter_map(|bind_pat| { | 793 | .filter_map(|f| { |
779 | let ast_pat = | 794 | let ast_pat = f.pat()?; |
780 | ast::Pat::cast(bind_pat.syntax().clone()).expect("bind pat is a pat"); | ||
781 | let pat = self.collect_pat(ast_pat); | 795 | let pat = self.collect_pat(ast_pat); |
782 | let name = bind_pat.name()?.as_name(); | 796 | let name = f.field_name()?.as_name(); |
783 | Some(RecordFieldPat { name, pat }) | 797 | Some(RecordFieldPat { name, pat }) |
784 | }) | 798 | }) |
785 | .collect(); | 799 | .collect(); |
786 | let iter = record_field_pat_list.record_field_pats().filter_map(|f| { | ||
787 | let ast_pat = f.pat()?; | ||
788 | let pat = self.collect_pat(ast_pat); | ||
789 | let name = f.field_name()?.as_name(); | ||
790 | Some(RecordFieldPat { name, pat }) | ||
791 | }); | ||
792 | fields.extend(iter); | ||
793 | 800 | ||
794 | let ellipsis = record_field_pat_list.dotdot_token().is_some(); | 801 | let ellipsis = p |
802 | .record_pat_field_list() | ||
803 | .expect("every struct should have a field list") | ||
804 | .dotdot_token() | ||
805 | .is_some(); | ||
795 | 806 | ||
796 | Pat::Record { path, args: fields, ellipsis } | 807 | Pat::Record { path, args, ellipsis } |
797 | } | 808 | } |
798 | ast::Pat::SlicePat(p) => { | 809 | ast::Pat::SlicePat(p) => { |
799 | let SlicePatComponents { prefix, slice, suffix } = p.components(); | 810 | let SlicePatComponents { prefix, slice, suffix } = p.components(); |
800 | 811 | ||
801 | // FIXME properly handle `DotDotPat` | 812 | // FIXME properly handle `RestPat` |
802 | Pat::Slice { | 813 | Pat::Slice { |
803 | prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(), | 814 | prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(), |
804 | slice: slice.map(|p| self.collect_pat(p)), | 815 | slice: slice.map(|p| self.collect_pat(p)), |
@@ -815,10 +826,10 @@ impl ExprCollector<'_> { | |||
815 | Pat::Missing | 826 | Pat::Missing |
816 | } | 827 | } |
817 | } | 828 | } |
818 | ast::Pat::DotDotPat(_) => { | 829 | ast::Pat::RestPat(_) => { |
819 | // `DotDotPat` requires special handling and should not be mapped | 830 | // `RestPat` requires special handling and should not be mapped |
820 | // to a Pat. Here we are using `Pat::Missing` as a fallback for | 831 | // to a Pat. Here we are using `Pat::Missing` as a fallback for |
821 | // when `DotDotPat` is mapped to `Pat`, which can easily happen | 832 | // when `RestPat` is mapped to `Pat`, which can easily happen |
822 | // when the source code being analyzed has a malformed pattern | 833 | // when the source code being analyzed has a malformed pattern |
823 | // which includes `..` in a place where it isn't valid. | 834 | // which includes `..` in a place where it isn't valid. |
824 | 835 | ||
@@ -842,10 +853,10 @@ impl ExprCollector<'_> { | |||
842 | fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Vec<PatId>, Option<usize>) { | 853 | fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Vec<PatId>, Option<usize>) { |
843 | // Find the location of the `..`, if there is one. Note that we do not | 854 | // Find the location of the `..`, if there is one. Note that we do not |
844 | // consider the possiblity of there being multiple `..` here. | 855 | // consider the possiblity of there being multiple `..` here. |
845 | let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::DotDotPat(_))); | 856 | let ellipsis = args.clone().position(|p| matches!(p, ast::Pat::RestPat(_))); |
846 | // We want to skip the `..` pattern here, since we account for it above. | 857 | // We want to skip the `..` pattern here, since we account for it above. |
847 | let args = args | 858 | let args = args |
848 | .filter(|p| !matches!(p, ast::Pat::DotDotPat(_))) | 859 | .filter(|p| !matches!(p, ast::Pat::RestPat(_))) |
849 | .map(|p| self.collect_pat(p)) | 860 | .map(|p| self.collect_pat(p)) |
850 | .collect(); | 861 | .collect(); |
851 | 862 | ||