@@ -993,93 +993,6 @@ impl<'tcx> Constructor<'tcx> {
993993 }
994994 }
995995 }
996-
997- /// Apply a constructor to a list of patterns, yielding a new pattern. `pats`
998- /// must have as many elements as this constructor's arity.
999- ///
1000- /// This is roughly the inverse of `specialize_constructor`.
1001- ///
1002- /// Examples:
1003- /// `self`: `Constructor::Single`
1004- /// `ty`: `(u32, u32, u32)`
1005- /// `pats`: `[10, 20, _]`
1006- /// returns `(10, 20, _)`
1007- ///
1008- /// `self`: `Constructor::Variant(Option::Some)`
1009- /// `ty`: `Option<bool>`
1010- /// `pats`: `[false]`
1011- /// returns `Some(false)`
1012- fn apply < ' p > ( & self , pcx : PatCtxt < ' _ , ' p , ' tcx > , fields : Fields < ' p , ' tcx > ) -> Pat < ' tcx > {
1013- let mut subpatterns = fields. all_patterns ( ) ;
1014-
1015- let pat = match self {
1016- Single | Variant ( _) => match pcx. ty . kind ( ) {
1017- ty:: Adt ( ..) | ty:: Tuple ( ..) => {
1018- let subpatterns = subpatterns
1019- . enumerate ( )
1020- . map ( |( i, p) | FieldPat { field : Field :: new ( i) , pattern : p } )
1021- . collect ( ) ;
1022-
1023- if let ty:: Adt ( adt, substs) = pcx. ty . kind ( ) {
1024- if adt. is_enum ( ) {
1025- PatKind :: Variant {
1026- adt_def : adt,
1027- substs,
1028- variant_index : self . variant_index_for_adt ( adt) ,
1029- subpatterns,
1030- }
1031- } else {
1032- PatKind :: Leaf { subpatterns }
1033- }
1034- } else {
1035- PatKind :: Leaf { subpatterns }
1036- }
1037- }
1038- // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
1039- // be careful to reconstruct the correct constant pattern here. However a string
1040- // literal pattern will never be reported as a non-exhaustiveness witness, so we
1041- // can ignore this issue.
1042- ty:: Ref ( ..) => PatKind :: Deref { subpattern : subpatterns. next ( ) . unwrap ( ) } ,
1043- ty:: Slice ( _) | ty:: Array ( ..) => bug ! ( "bad slice pattern {:?} {:?}" , self , pcx. ty) ,
1044- _ => PatKind :: Wild ,
1045- } ,
1046- Slice ( slice) => match slice. kind {
1047- FixedLen ( _) => {
1048- PatKind :: Slice { prefix : subpatterns. collect ( ) , slice : None , suffix : vec ! [ ] }
1049- }
1050- VarLen ( prefix, _) => {
1051- let mut prefix: Vec < _ > = subpatterns. by_ref ( ) . take ( prefix as usize ) . collect ( ) ;
1052- if slice. array_len . is_some ( ) {
1053- // Improves diagnostics a bit: if the type is a known-size array, instead
1054- // of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
1055- // This is incorrect if the size is not known, since `[_, ..]` captures
1056- // arrays of lengths `>= 1` whereas `[..]` captures any length.
1057- while !prefix. is_empty ( ) && prefix. last ( ) . unwrap ( ) . is_wildcard ( ) {
1058- prefix. pop ( ) ;
1059- }
1060- }
1061- let suffix: Vec < _ > = if slice. array_len . is_some ( ) {
1062- // Same as above.
1063- subpatterns. skip_while ( Pat :: is_wildcard) . collect ( )
1064- } else {
1065- subpatterns. collect ( )
1066- } ;
1067- let wild = Pat :: wildcard_from_ty ( pcx. ty ) ;
1068- PatKind :: Slice { prefix, slice : Some ( wild) , suffix }
1069- }
1070- } ,
1071- & Str ( value) => PatKind :: Constant { value } ,
1072- & FloatRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end } ) ,
1073- IntRange ( range) => return range. to_pat ( pcx. cx . tcx ) ,
1074- NonExhaustive => PatKind :: Wild ,
1075- Opaque => bug ! ( "we should not try to apply an opaque constructor" ) ,
1076- Wildcard => bug ! (
1077- "trying to apply a wildcard constructor; this should have been done in `apply_constructors`"
1078- ) ,
1079- } ;
1080-
1081- Pat { ty : pcx. ty , span : DUMMY_SP , kind : Box :: new ( pat) }
1082- }
1083996}
1084997
1085998/// Some fields need to be explicitly hidden away in certain cases; see the comment above the
@@ -1228,6 +1141,93 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12281141 ret
12291142 }
12301143
1144+ /// Apply a constructor to a list of patterns, yielding a new pattern. `self`
1145+ /// must have as many elements as this constructor's arity.
1146+ ///
1147+ /// This is roughly the inverse of `specialize_constructor`.
1148+ ///
1149+ /// Examples:
1150+ /// `ctor`: `Constructor::Single`
1151+ /// `ty`: `Foo(u32, u32, u32)`
1152+ /// `self`: `[10, 20, _]`
1153+ /// returns `Foo(10, 20, _)`
1154+ ///
1155+ /// `ctor`: `Constructor::Variant(Option::Some)`
1156+ /// `ty`: `Option<bool>`
1157+ /// `self`: `[false]`
1158+ /// returns `Some(false)`
1159+ fn apply ( self , pcx : PatCtxt < ' _ , ' p , ' tcx > , ctor : & Constructor < ' tcx > ) -> Pat < ' tcx > {
1160+ let mut subpatterns = self . all_patterns ( ) ;
1161+
1162+ let pat = match ctor {
1163+ Single | Variant ( _) => match pcx. ty . kind ( ) {
1164+ ty:: Adt ( ..) | ty:: Tuple ( ..) => {
1165+ let subpatterns = subpatterns
1166+ . enumerate ( )
1167+ . map ( |( i, p) | FieldPat { field : Field :: new ( i) , pattern : p } )
1168+ . collect ( ) ;
1169+
1170+ if let ty:: Adt ( adt, substs) = pcx. ty . kind ( ) {
1171+ if adt. is_enum ( ) {
1172+ PatKind :: Variant {
1173+ adt_def : adt,
1174+ substs,
1175+ variant_index : ctor. variant_index_for_adt ( adt) ,
1176+ subpatterns,
1177+ }
1178+ } else {
1179+ PatKind :: Leaf { subpatterns }
1180+ }
1181+ } else {
1182+ PatKind :: Leaf { subpatterns }
1183+ }
1184+ }
1185+ // Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
1186+ // be careful to reconstruct the correct constant pattern here. However a string
1187+ // literal pattern will never be reported as a non-exhaustiveness witness, so we
1188+ // can ignore this issue.
1189+ ty:: Ref ( ..) => PatKind :: Deref { subpattern : subpatterns. next ( ) . unwrap ( ) } ,
1190+ ty:: Slice ( _) | ty:: Array ( ..) => bug ! ( "bad slice pattern {:?} {:?}" , ctor, pcx. ty) ,
1191+ _ => PatKind :: Wild ,
1192+ } ,
1193+ Slice ( slice) => match slice. kind {
1194+ FixedLen ( _) => {
1195+ PatKind :: Slice { prefix : subpatterns. collect ( ) , slice : None , suffix : vec ! [ ] }
1196+ }
1197+ VarLen ( prefix, _) => {
1198+ let mut prefix: Vec < _ > = subpatterns. by_ref ( ) . take ( prefix as usize ) . collect ( ) ;
1199+ if slice. array_len . is_some ( ) {
1200+ // Improves diagnostics a bit: if the type is a known-size array, instead
1201+ // of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
1202+ // This is incorrect if the size is not known, since `[_, ..]` captures
1203+ // arrays of lengths `>= 1` whereas `[..]` captures any length.
1204+ while !prefix. is_empty ( ) && prefix. last ( ) . unwrap ( ) . is_wildcard ( ) {
1205+ prefix. pop ( ) ;
1206+ }
1207+ }
1208+ let suffix: Vec < _ > = if slice. array_len . is_some ( ) {
1209+ // Same as above.
1210+ subpatterns. skip_while ( Pat :: is_wildcard) . collect ( )
1211+ } else {
1212+ subpatterns. collect ( )
1213+ } ;
1214+ let wild = Pat :: wildcard_from_ty ( pcx. ty ) ;
1215+ PatKind :: Slice { prefix, slice : Some ( wild) , suffix }
1216+ }
1217+ } ,
1218+ & Str ( value) => PatKind :: Constant { value } ,
1219+ & FloatRange ( lo, hi, end) => PatKind :: Range ( PatRange { lo, hi, end } ) ,
1220+ IntRange ( range) => return range. to_pat ( pcx. cx . tcx ) ,
1221+ NonExhaustive => PatKind :: Wild ,
1222+ Opaque => bug ! ( "we should not try to apply an opaque constructor" ) ,
1223+ Wildcard => bug ! (
1224+ "trying to apply a wildcard constructor; this should have been done in `apply_constructors`"
1225+ ) ,
1226+ } ;
1227+
1228+ Pat { ty : pcx. ty , span : DUMMY_SP , kind : Box :: new ( pat) }
1229+ }
1230+
12311231 /// Returns the number of patterns from the viewpoint of match-checking, i.e. excluding hidden
12321232 /// fields. This is what we want in most cases in this file, the only exception being
12331233 /// conversion to/from `Pat`.
@@ -1534,8 +1534,7 @@ impl<'tcx> Witness<'tcx> {
15341534 let len = self . 0 . len ( ) ;
15351535 let arity = ctor_wild_subpatterns. len ( ) ;
15361536 let pats = self . 0 . drain ( ( len - arity) ..) . rev ( ) ;
1537- let fields = ctor_wild_subpatterns. replace_fields ( pcx. cx , pats) ;
1538- ctor. apply ( pcx, fields)
1537+ ctor_wild_subpatterns. replace_fields ( pcx. cx , pats) . apply ( pcx, ctor)
15391538 } ;
15401539
15411540 self . 0 . push ( pat) ;
@@ -2072,10 +2071,7 @@ impl<'tcx> MissingConstructors<'tcx> {
20722071 // it. For example, if `ctor` is a `Constructor::Variant` for
20732072 // `Option::Some`, we get the pattern `Some(_)`.
20742073 self . iter ( pcx)
2075- . map ( |missing_ctor| {
2076- let fields = Fields :: wildcards ( pcx, & missing_ctor) ;
2077- missing_ctor. apply ( pcx, fields)
2078- } )
2074+ . map ( |missing_ctor| Fields :: wildcards ( pcx, & missing_ctor) . apply ( pcx, missing_ctor) )
20792075 . collect ( )
20802076 }
20812077 }
0 commit comments