1111use std:: cmp:: Ordering ;
1212use std:: fmt;
1313use std:: ops:: Index ;
14+ use std:: sync:: Arc ;
1415
1516use rustc_abi:: { FieldIdx , Integer , Size , VariantIdx } ;
1617use rustc_ast:: { AsmMacro , InlineAsmOptions , InlineAsmTemplatePiece } ;
@@ -108,7 +109,7 @@ pub enum BodyTy<'tcx> {
108109#[ derive( Clone , Debug , HashStable ) ]
109110pub struct Param < ' tcx > {
110111 /// The pattern that appears in the parameter list, or None for implicit parameters.
111- pub pat : Option < Box < Pat < ' tcx > > > ,
112+ pub pat : Option < Arc < Pat < ' tcx > > > ,
112113 /// The possibly inferred type.
113114 pub ty : Ty < ' tcx > ,
114115 /// Span of the explicitly provided type, or None if inferred for closures.
@@ -231,7 +232,7 @@ pub enum StmtKind<'tcx> {
231232 /// `let <PAT> = ...`
232233 ///
233234 /// If a type annotation is included, it is added as an ascription pattern.
234- pattern : Box < Pat < ' tcx > > ,
235+ pattern : Arc < Pat < ' tcx > > ,
235236
236237 /// `let pat: ty = <INIT>`
237238 initializer : Option < ExprId > ,
@@ -379,7 +380,7 @@ pub enum ExprKind<'tcx> {
379380 /// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
380381 Let {
381382 expr : ExprId ,
382- pat : Box < Pat < ' tcx > > ,
383+ pat : Arc < Pat < ' tcx > > ,
383384 } ,
384385 /// A `match` expression.
385386 Match {
@@ -571,7 +572,7 @@ pub struct FruInfo<'tcx> {
571572/// A `match` arm.
572573#[ derive( Clone , Debug , HashStable ) ]
573574pub struct Arm < ' tcx > {
574- pub pattern : Box < Pat < ' tcx > > ,
575+ pub pattern : Arc < Pat < ' tcx > > ,
575576 pub guard : Option < ExprId > ,
576577 pub body : ExprId ,
577578 pub lint_level : LintLevel ,
@@ -628,7 +629,7 @@ pub enum InlineAsmOperand<'tcx> {
628629#[ derive( Clone , Debug , HashStable , TypeVisitable ) ]
629630pub struct FieldPat < ' tcx > {
630631 pub field : FieldIdx ,
631- pub pattern : Box < Pat < ' tcx > > ,
632+ pub pattern : Arc < Pat < ' tcx > > ,
632633}
633634
634635#[ derive( Clone , Debug , HashStable , TypeVisitable ) ]
@@ -647,11 +648,17 @@ impl<'tcx> Pat<'tcx> {
647648 _ => None ,
648649 }
649650 }
651+ }
650652
653+ impl < ' tcx > Thir < ' tcx > {
651654 /// Call `f` on every "binding" in a pattern, e.g., on `a` in
652655 /// `match foo() { Some(a) => (), None => () }`
653- pub fn each_binding ( & self , mut f : impl FnMut ( Symbol , ByRef , Ty < ' tcx > , Span ) ) {
654- self . walk_always ( |p| {
656+ pub fn each_pat_binding (
657+ & self ,
658+ pat : & Pat < ' tcx > ,
659+ mut f : impl FnMut ( Symbol , ByRef , Ty < ' tcx > , Span ) ,
660+ ) {
661+ self . walk_pat_always ( pat, |p| {
655662 if let PatKind :: Binding { name, mode, ty, .. } = p. kind {
656663 f ( name, mode. 0 , ty, p. span ) ;
657664 }
@@ -661,17 +668,17 @@ impl<'tcx> Pat<'tcx> {
661668 /// Walk the pattern in left-to-right order.
662669 ///
663670 /// If `it(pat)` returns `false`, the children are not visited.
664- pub fn walk ( & self , mut it : impl FnMut ( & Pat < ' tcx > ) -> bool ) {
665- self . walk_ ( & mut it)
671+ pub fn walk_pat ( & self , pat : & Pat < ' tcx > , mut it : impl FnMut ( & Pat < ' tcx > ) -> bool ) {
672+ self . walk_pat_inner ( pat , & mut it) ;
666673 }
667674
668- fn walk_ ( & self , it : & mut impl FnMut ( & Pat < ' tcx > ) -> bool ) {
669- if !it ( self ) {
675+ fn walk_pat_inner ( & self , pat : & Pat < ' tcx > , it : & mut impl FnMut ( & Pat < ' tcx > ) -> bool ) {
676+ if !it ( pat ) {
670677 return ;
671678 }
672679
673680 use PatKind :: * ;
674- match & self . kind {
681+ match & pat . kind {
675682 Wild
676683 | Never
677684 | Range ( ..)
@@ -682,22 +689,24 @@ impl<'tcx> Pat<'tcx> {
682689 | Binding { subpattern : Some ( subpattern) , .. }
683690 | Deref { subpattern }
684691 | DerefPattern { subpattern, .. }
685- | ExpandedConstant { subpattern, .. } => subpattern . walk_ ( it) ,
692+ | ExpandedConstant { subpattern, .. } => self . walk_pat_inner ( subpattern , it) ,
686693 Leaf { subpatterns } | Variant { subpatterns, .. } => {
687- subpatterns. iter ( ) . for_each ( |field| field. pattern . walk_ ( it) )
694+ subpatterns. iter ( ) . for_each ( |field| self . walk_pat_inner ( & field. pattern , it) )
688695 }
689- Or { pats } => pats. iter ( ) . for_each ( |p| p . walk_ ( it) ) ,
696+ Or { pats } => pats. iter ( ) . for_each ( |p| self . walk_pat_inner ( p , it) ) ,
690697 Array { box ref prefix, ref slice, box ref suffix }
691- | Slice { box ref prefix, ref slice, box ref suffix } => {
692- prefix. iter ( ) . chain ( slice. iter ( ) ) . chain ( suffix. iter ( ) ) . for_each ( |p| p. walk_ ( it) )
693- }
698+ | Slice { box ref prefix, ref slice, box ref suffix } => prefix
699+ . iter ( )
700+ . chain ( slice. iter ( ) )
701+ . chain ( suffix. iter ( ) )
702+ . for_each ( |p| self . walk_pat_inner ( p, it) ) ,
694703 }
695704 }
696705
697706 /// Whether the pattern has a `PatKind::Error` nested within.
698- pub fn pat_error_reported ( & self ) -> Result < ( ) , ErrorGuaranteed > {
707+ pub fn pat_error_reported ( & self , pat : & Pat < ' tcx > ) -> Result < ( ) , ErrorGuaranteed > {
699708 let mut error = None ;
700- self . walk ( |pat| {
709+ self . walk_pat ( pat , |pat| {
701710 if let PatKind :: Error ( e) = pat. kind
702711 && error. is_none ( )
703712 {
@@ -714,23 +723,23 @@ impl<'tcx> Pat<'tcx> {
714723 /// Walk the pattern in left-to-right order.
715724 ///
716725 /// If you always want to recurse, prefer this method over `walk`.
717- pub fn walk_always ( & self , mut it : impl FnMut ( & Pat < ' tcx > ) ) {
718- self . walk ( |p| {
726+ pub fn walk_pat_always ( & self , pat : & Pat < ' tcx > , mut it : impl FnMut ( & Pat < ' tcx > ) ) {
727+ self . walk_pat ( pat , |p| {
719728 it ( p) ;
720729 true
721730 } )
722731 }
723732
724733 /// Whether this a never pattern.
725- pub fn is_never_pattern ( & self ) -> bool {
734+ pub fn is_never_pattern ( & self , pat : & Pat < ' tcx > ) -> bool {
726735 let mut is_never_pattern = false ;
727- self . walk ( |pat| match & pat. kind {
736+ self . walk_pat ( pat , |pat| match & pat. kind {
728737 PatKind :: Never => {
729738 is_never_pattern = true ;
730739 false
731740 }
732741 PatKind :: Or { pats } => {
733- is_never_pattern = pats. iter ( ) . all ( |p| p . is_never_pattern ( ) ) ;
742+ is_never_pattern = pats. iter ( ) . all ( |p| self . is_never_pattern ( p ) ) ;
734743 false
735744 }
736745 _ => true ,
@@ -770,7 +779,7 @@ pub enum PatKind<'tcx> {
770779
771780 AscribeUserType {
772781 ascription : Ascription < ' tcx > ,
773- subpattern : Box < Pat < ' tcx > > ,
782+ subpattern : Arc < Pat < ' tcx > > ,
774783 } ,
775784
776785 /// `x`, `ref x`, `x @ P`, etc.
@@ -781,7 +790,7 @@ pub enum PatKind<'tcx> {
781790 #[ type_visitable( ignore) ]
782791 var : LocalVarId ,
783792 ty : Ty < ' tcx > ,
784- subpattern : Option < Box < Pat < ' tcx > > > ,
793+ subpattern : Option < Arc < Pat < ' tcx > > > ,
785794 /// Is this the leftmost occurrence of the binding, i.e., is `var` the
786795 /// `HirId` of this pattern?
787796 is_primary : bool ,
@@ -804,12 +813,12 @@ pub enum PatKind<'tcx> {
804813
805814 /// `box P`, `&P`, `&mut P`, etc.
806815 Deref {
807- subpattern : Box < Pat < ' tcx > > ,
816+ subpattern : Arc < Pat < ' tcx > > ,
808817 } ,
809818
810819 /// Deref pattern, written `box P` for now.
811820 DerefPattern {
812- subpattern : Box < Pat < ' tcx > > ,
821+ subpattern : Arc < Pat < ' tcx > > ,
813822 mutability : hir:: Mutability ,
814823 } ,
815824
@@ -843,31 +852,31 @@ pub enum PatKind<'tcx> {
843852 /// Otherwise, the actual pattern that the constant lowered to. As with
844853 /// other constants, inline constants are matched structurally where
845854 /// possible.
846- subpattern : Box < Pat < ' tcx > > ,
855+ subpattern : Arc < Pat < ' tcx > > ,
847856 } ,
848857
849- Range ( Box < PatRange < ' tcx > > ) ,
858+ Range ( Arc < PatRange < ' tcx > > ) ,
850859
851860 /// Matches against a slice, checking the length and extracting elements.
852861 /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
853862 /// e.g., `&[ref xs @ ..]`.
854863 Slice {
855- prefix : Box < [ Box < Pat < ' tcx > > ] > ,
856- slice : Option < Box < Pat < ' tcx > > > ,
857- suffix : Box < [ Box < Pat < ' tcx > > ] > ,
864+ prefix : Box < [ Arc < Pat < ' tcx > > ] > ,
865+ slice : Option < Arc < Pat < ' tcx > > > ,
866+ suffix : Box < [ Arc < Pat < ' tcx > > ] > ,
858867 } ,
859868
860869 /// Fixed match against an array; irrefutable.
861870 Array {
862- prefix : Box < [ Box < Pat < ' tcx > > ] > ,
863- slice : Option < Box < Pat < ' tcx > > > ,
864- suffix : Box < [ Box < Pat < ' tcx > > ] > ,
871+ prefix : Box < [ Arc < Pat < ' tcx > > ] > ,
872+ slice : Option < Arc < Pat < ' tcx > > > ,
873+ suffix : Box < [ Arc < Pat < ' tcx > > ] > ,
865874 } ,
866875
867876 /// An or-pattern, e.g. `p | q`.
868877 /// Invariant: `pats.len() >= 2`.
869878 Or {
870- pats : Box < [ Box < Pat < ' tcx > > ] > ,
879+ pats : Box < [ Arc < Pat < ' tcx > > ] > ,
871880 } ,
872881
873882 /// A never pattern `!`.
0 commit comments