@@ -674,6 +674,67 @@ impl<'tcx> Constructor<'tcx> {
674
674
_ => 0 ,
675
675
}
676
676
}
677
+
678
+ /// Apply a constructor to a list of patterns, yielding a new pattern. `pats`
679
+ /// must have as many elements as this constructor's arity.
680
+ ///
681
+ /// Examples:
682
+ /// self: Single
683
+ /// ty: tuple of 3 elements
684
+ /// pats: [10, 20, _] => (10, 20, _)
685
+ ///
686
+ /// self: Option::Some
687
+ /// ty: Option<bool>
688
+ /// pats: [false] => Some(false)
689
+ fn apply < ' a > (
690
+ & self ,
691
+ cx : & MatchCheckCtxt < ' a , ' tcx > ,
692
+ ty : Ty < ' tcx > ,
693
+ pats : impl IntoIterator < Item = Pat < ' tcx > > ,
694
+ ) -> Pat < ' tcx > {
695
+ let mut pats = pats. into_iter ( ) ;
696
+ let pat = match ty. kind {
697
+ ty:: Adt ( ..) | ty:: Tuple ( ..) => {
698
+ let pats = pats
699
+ . enumerate ( )
700
+ . map ( |( i, p) | FieldPat { field : Field :: new ( i) , pattern : p } )
701
+ . collect ( ) ;
702
+
703
+ if let ty:: Adt ( adt, substs) = ty. kind {
704
+ if adt. is_enum ( ) {
705
+ PatKind :: Variant {
706
+ adt_def : adt,
707
+ substs,
708
+ variant_index : self . variant_index_for_adt ( cx, adt) ,
709
+ subpatterns : pats,
710
+ }
711
+ } else {
712
+ PatKind :: Leaf { subpatterns : pats }
713
+ }
714
+ } else {
715
+ PatKind :: Leaf { subpatterns : pats }
716
+ }
717
+ }
718
+
719
+ ty:: Ref ( ..) => PatKind :: Deref { subpattern : pats. nth ( 0 ) . unwrap ( ) } ,
720
+
721
+ ty:: Slice ( _) | ty:: Array ( ..) => {
722
+ PatKind :: Slice { prefix : pats. collect ( ) , slice : None , suffix : vec ! [ ] }
723
+ }
724
+
725
+ _ => match * self {
726
+ ConstantValue ( value, _) => PatKind :: Constant { value } ,
727
+ ConstantRange ( lo, hi, ty, end, _) => PatKind :: Range ( PatRange {
728
+ lo : ty:: Const :: from_bits ( cx. tcx , lo, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
729
+ hi : ty:: Const :: from_bits ( cx. tcx , hi, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
730
+ end,
731
+ } ) ,
732
+ _ => PatKind :: Wild ,
733
+ } ,
734
+ } ;
735
+
736
+ Pat { ty, span : DUMMY_SP , kind : Box :: new ( pat) }
737
+ }
677
738
}
678
739
679
740
#[ derive( Clone , Debug ) ]
@@ -778,50 +839,11 @@ impl<'tcx> Witness<'tcx> {
778
839
let arity = ctor. arity ( cx, ty) ;
779
840
let pat = {
780
841
let len = self . 0 . len ( ) as u64 ;
781
- let mut pats = self . 0 . drain ( ( len - arity) as usize ..) . rev ( ) ;
782
-
783
- match ty. kind {
784
- ty:: Adt ( ..) | ty:: Tuple ( ..) => {
785
- let pats = pats
786
- . enumerate ( )
787
- . map ( |( i, p) | FieldPat { field : Field :: new ( i) , pattern : p } )
788
- . collect ( ) ;
789
-
790
- if let ty:: Adt ( adt, substs) = ty. kind {
791
- if adt. is_enum ( ) {
792
- PatKind :: Variant {
793
- adt_def : adt,
794
- substs,
795
- variant_index : ctor. variant_index_for_adt ( cx, adt) ,
796
- subpatterns : pats,
797
- }
798
- } else {
799
- PatKind :: Leaf { subpatterns : pats }
800
- }
801
- } else {
802
- PatKind :: Leaf { subpatterns : pats }
803
- }
804
- }
805
-
806
- ty:: Ref ( ..) => PatKind :: Deref { subpattern : pats. nth ( 0 ) . unwrap ( ) } ,
807
-
808
- ty:: Slice ( _) | ty:: Array ( ..) => {
809
- PatKind :: Slice { prefix : pats. collect ( ) , slice : None , suffix : vec ! [ ] }
810
- }
811
-
812
- _ => match * ctor {
813
- ConstantValue ( value, _) => PatKind :: Constant { value } ,
814
- ConstantRange ( lo, hi, ty, end, _) => PatKind :: Range ( PatRange {
815
- lo : ty:: Const :: from_bits ( cx. tcx , lo, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
816
- hi : ty:: Const :: from_bits ( cx. tcx , hi, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
817
- end,
818
- } ) ,
819
- _ => PatKind :: Wild ,
820
- } ,
821
- }
842
+ let pats = self . 0 . drain ( ( len - arity) as usize ..) . rev ( ) ;
843
+ ctor. apply ( cx, ty, pats)
822
844
} ;
823
845
824
- self . 0 . push ( Pat { ty , span : DUMMY_SP , kind : Box :: new ( pat) } ) ;
846
+ self . 0 . push ( pat) ;
825
847
826
848
self
827
849
}
0 commit comments