@@ -993,93 +993,6 @@ impl<'tcx> Constructor<'tcx> {
993
993
}
994
994
}
995
995
}
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
- }
1083
996
}
1084
997
1085
998
/// 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> {
1228
1141
ret
1229
1142
}
1230
1143
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
+
1231
1231
/// Returns the number of patterns from the viewpoint of match-checking, i.e. excluding hidden
1232
1232
/// fields. This is what we want in most cases in this file, the only exception being
1233
1233
/// conversion to/from `Pat`.
@@ -1534,8 +1534,7 @@ impl<'tcx> Witness<'tcx> {
1534
1534
let len = self . 0 . len ( ) ;
1535
1535
let arity = ctor_wild_subpatterns. len ( ) ;
1536
1536
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)
1539
1538
} ;
1540
1539
1541
1540
self . 0 . push ( pat) ;
@@ -2072,10 +2071,7 @@ impl<'tcx> MissingConstructors<'tcx> {
2072
2071
// it. For example, if `ctor` is a `Constructor::Variant` for
2073
2072
// `Option::Some`, we get the pattern `Some(_)`.
2074
2073
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) )
2079
2075
. collect ( )
2080
2076
}
2081
2077
}
0 commit comments