11
11
use std:: cmp:: Ordering ;
12
12
use std:: fmt;
13
13
use std:: ops:: Index ;
14
+ use std:: sync:: Arc ;
14
15
15
16
use rustc_abi:: { FieldIdx , Integer , Size , VariantIdx } ;
16
17
use rustc_ast:: { AsmMacro , InlineAsmOptions , InlineAsmTemplatePiece } ;
@@ -108,7 +109,7 @@ pub enum BodyTy<'tcx> {
108
109
#[ derive( Clone , Debug , HashStable ) ]
109
110
pub struct Param < ' tcx > {
110
111
/// 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 > > > ,
112
113
/// The possibly inferred type.
113
114
pub ty : Ty < ' tcx > ,
114
115
/// Span of the explicitly provided type, or None if inferred for closures.
@@ -231,7 +232,7 @@ pub enum StmtKind<'tcx> {
231
232
/// `let <PAT> = ...`
232
233
///
233
234
/// If a type annotation is included, it is added as an ascription pattern.
234
- pattern : Box < Pat < ' tcx > > ,
235
+ pattern : Arc < Pat < ' tcx > > ,
235
236
236
237
/// `let pat: ty = <INIT>`
237
238
initializer : Option < ExprId > ,
@@ -379,7 +380,7 @@ pub enum ExprKind<'tcx> {
379
380
/// (Not to be confused with [`StmtKind::Let`], which is a normal `let` statement.)
380
381
Let {
381
382
expr : ExprId ,
382
- pat : Box < Pat < ' tcx > > ,
383
+ pat : Arc < Pat < ' tcx > > ,
383
384
} ,
384
385
/// A `match` expression.
385
386
Match {
@@ -571,7 +572,7 @@ pub struct FruInfo<'tcx> {
571
572
/// A `match` arm.
572
573
#[ derive( Clone , Debug , HashStable ) ]
573
574
pub struct Arm < ' tcx > {
574
- pub pattern : Box < Pat < ' tcx > > ,
575
+ pub pattern : Arc < Pat < ' tcx > > ,
575
576
pub guard : Option < ExprId > ,
576
577
pub body : ExprId ,
577
578
pub lint_level : LintLevel ,
@@ -628,7 +629,7 @@ pub enum InlineAsmOperand<'tcx> {
628
629
#[ derive( Clone , Debug , HashStable , TypeVisitable ) ]
629
630
pub struct FieldPat < ' tcx > {
630
631
pub field : FieldIdx ,
631
- pub pattern : Box < Pat < ' tcx > > ,
632
+ pub pattern : Arc < Pat < ' tcx > > ,
632
633
}
633
634
634
635
#[ derive( Clone , Debug , HashStable , TypeVisitable ) ]
@@ -647,11 +648,17 @@ impl<'tcx> Pat<'tcx> {
647
648
_ => None ,
648
649
}
649
650
}
651
+ }
650
652
653
+ impl < ' tcx > Thir < ' tcx > {
651
654
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
652
655
/// `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| {
655
662
if let PatKind :: Binding { name, mode, ty, .. } = p. kind {
656
663
f ( name, mode. 0 , ty, p. span ) ;
657
664
}
@@ -661,17 +668,17 @@ impl<'tcx> Pat<'tcx> {
661
668
/// Walk the pattern in left-to-right order.
662
669
///
663
670
/// 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) ;
666
673
}
667
674
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 ) {
670
677
return ;
671
678
}
672
679
673
680
use PatKind :: * ;
674
- match & self . kind {
681
+ match & pat . kind {
675
682
Wild
676
683
| Never
677
684
| Range ( ..)
@@ -682,22 +689,24 @@ impl<'tcx> Pat<'tcx> {
682
689
| Binding { subpattern : Some ( subpattern) , .. }
683
690
| Deref { subpattern }
684
691
| DerefPattern { subpattern, .. }
685
- | ExpandedConstant { subpattern, .. } => subpattern . walk_ ( it) ,
692
+ | ExpandedConstant { subpattern, .. } => self . walk_pat_inner ( subpattern , it) ,
686
693
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) )
688
695
}
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) ) ,
690
697
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) ) ,
694
703
}
695
704
}
696
705
697
706
/// 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 > {
699
708
let mut error = None ;
700
- self . walk ( |pat| {
709
+ self . walk_pat ( pat , |pat| {
701
710
if let PatKind :: Error ( e) = pat. kind
702
711
&& error. is_none ( )
703
712
{
@@ -714,23 +723,23 @@ impl<'tcx> Pat<'tcx> {
714
723
/// Walk the pattern in left-to-right order.
715
724
///
716
725
/// 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| {
719
728
it ( p) ;
720
729
true
721
730
} )
722
731
}
723
732
724
733
/// Whether this a never pattern.
725
- pub fn is_never_pattern ( & self ) -> bool {
734
+ pub fn is_never_pattern ( & self , pat : & Pat < ' tcx > ) -> bool {
726
735
let mut is_never_pattern = false ;
727
- self . walk ( |pat| match & pat. kind {
736
+ self . walk_pat ( pat , |pat| match & pat. kind {
728
737
PatKind :: Never => {
729
738
is_never_pattern = true ;
730
739
false
731
740
}
732
741
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 ) ) ;
734
743
false
735
744
}
736
745
_ => true ,
@@ -770,7 +779,7 @@ pub enum PatKind<'tcx> {
770
779
771
780
AscribeUserType {
772
781
ascription : Ascription < ' tcx > ,
773
- subpattern : Box < Pat < ' tcx > > ,
782
+ subpattern : Arc < Pat < ' tcx > > ,
774
783
} ,
775
784
776
785
/// `x`, `ref x`, `x @ P`, etc.
@@ -781,7 +790,7 @@ pub enum PatKind<'tcx> {
781
790
#[ type_visitable( ignore) ]
782
791
var : LocalVarId ,
783
792
ty : Ty < ' tcx > ,
784
- subpattern : Option < Box < Pat < ' tcx > > > ,
793
+ subpattern : Option < Arc < Pat < ' tcx > > > ,
785
794
/// Is this the leftmost occurrence of the binding, i.e., is `var` the
786
795
/// `HirId` of this pattern?
787
796
is_primary : bool ,
@@ -804,12 +813,12 @@ pub enum PatKind<'tcx> {
804
813
805
814
/// `box P`, `&P`, `&mut P`, etc.
806
815
Deref {
807
- subpattern : Box < Pat < ' tcx > > ,
816
+ subpattern : Arc < Pat < ' tcx > > ,
808
817
} ,
809
818
810
819
/// Deref pattern, written `box P` for now.
811
820
DerefPattern {
812
- subpattern : Box < Pat < ' tcx > > ,
821
+ subpattern : Arc < Pat < ' tcx > > ,
813
822
mutability : hir:: Mutability ,
814
823
} ,
815
824
@@ -843,31 +852,31 @@ pub enum PatKind<'tcx> {
843
852
/// Otherwise, the actual pattern that the constant lowered to. As with
844
853
/// other constants, inline constants are matched structurally where
845
854
/// possible.
846
- subpattern : Box < Pat < ' tcx > > ,
855
+ subpattern : Arc < Pat < ' tcx > > ,
847
856
} ,
848
857
849
- Range ( Box < PatRange < ' tcx > > ) ,
858
+ Range ( Arc < PatRange < ' tcx > > ) ,
850
859
851
860
/// Matches against a slice, checking the length and extracting elements.
852
861
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
853
862
/// e.g., `&[ref xs @ ..]`.
854
863
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 > > ] > ,
858
867
} ,
859
868
860
869
/// Fixed match against an array; irrefutable.
861
870
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 > > ] > ,
865
874
} ,
866
875
867
876
/// An or-pattern, e.g. `p | q`.
868
877
/// Invariant: `pats.len() >= 2`.
869
878
Or {
870
- pats : Box < [ Box < Pat < ' tcx > > ] > ,
879
+ pats : Box < [ Arc < Pat < ' tcx > > ] > ,
871
880
} ,
872
881
873
882
/// A never pattern `!`.
0 commit comments