@@ -674,6 +674,67 @@ impl<'tcx> Constructor<'tcx> {
674674 _ => 0 ,
675675 }
676676 }
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+ }
677738}
678739
679740#[ derive( Clone , Debug ) ]
@@ -778,50 +839,11 @@ impl<'tcx> Witness<'tcx> {
778839 let arity = ctor. arity ( cx, ty) ;
779840 let pat = {
780841 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)
822844 } ;
823845
824- self . 0 . push ( Pat { ty , span : DUMMY_SP , kind : Box :: new ( pat) } ) ;
846+ self . 0 . push ( pat) ;
825847
826848 self
827849 }
0 commit comments