@@ -1050,9 +1050,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
1050
1050
}
1051
1051
1052
1052
// FIXME(#19596) This is a workaround, but there should be a better way to do this
1053
- fn cat_pattern_ < F > ( & self , cmt : cmt < ' tcx > , pat : & hir:: Pat , op : & mut F )
1054
- -> McResult < ( ) >
1055
- where F : FnMut ( & MemCategorizationContext < ' a , ' gcx , ' tcx > , cmt < ' tcx > , & hir:: Pat ) ,
1053
+ fn cat_pattern_ < F > ( & self , cmt : cmt < ' tcx > , pat : & hir:: Pat , op : & mut F ) -> McResult < ( ) >
1054
+ where F : FnMut ( & MemCategorizationContext < ' a , ' gcx , ' tcx > , cmt < ' tcx > , & hir:: Pat )
1056
1055
{
1057
1056
// Here, `cmt` is the categorization for the value being
1058
1057
// matched and pat is the pattern it is being matched against.
@@ -1099,21 +1098,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
1099
1098
// step out of sync again. So you'll see below that we always
1100
1099
// get the type of the *subpattern* and use that.
1101
1100
1102
- debug ! ( "cat_pattern: {:?} cmt={:?}" ,
1103
- pat,
1104
- cmt) ;
1105
-
1106
- ( * op) ( self , cmt. clone ( ) , pat) ;
1101
+ debug ! ( "cat_pattern: {:?} cmt={:?}" , pat, cmt) ;
1107
1102
1108
- let opt_def = self . tcx ( ) . expect_def_or_none ( pat. id ) ;
1109
- if opt_def == Some ( Def :: Err ) {
1110
- return Err ( ( ) ) ;
1111
- }
1103
+ op ( self , cmt. clone ( ) , pat) ;
1112
1104
1113
1105
// Note: This goes up here (rather than within the PatKind::TupleStruct arm
1114
- // alone) because struct patterns can refer to struct types or
1115
- // to struct variants within enums.
1116
- let cmt = match opt_def {
1106
+ // alone) because PatKind::Struct can also refer to variants.
1107
+ let cmt = match self . tcx ( ) . expect_def_or_none ( pat . id ) {
1108
+ Some ( Def :: Err ) => return Err ( ( ) ) ,
1117
1109
Some ( Def :: Variant ( enum_did, variant_did) )
1118
1110
// univariant enums do not need downcasts
1119
1111
if !self . tcx ( ) . lookup_adt_def ( enum_did) . is_univariant ( ) => {
@@ -1123,66 +1115,33 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
1123
1115
} ;
1124
1116
1125
1117
match pat. node {
1126
- PatKind :: Wild => {
1127
- // _
1128
- }
1129
-
1130
1118
PatKind :: TupleStruct ( _, ref subpats, ddpos) => {
1131
- match opt_def {
1132
- Some ( Def :: Variant ( enum_def, def_id) ) => {
1133
- // variant(x, y, z)
1134
- let expected_len = self . tcx ( ) . lookup_adt_def ( enum_def)
1135
- . variant_with_id ( def_id) . fields . len ( ) ;
1136
- for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( expected_len, ddpos) {
1137
- let subpat_ty = self . pat_ty ( & subpat) ?; // see (*2)
1138
-
1139
- let subcmt =
1140
- self . cat_imm_interior (
1141
- pat, cmt. clone ( ) , subpat_ty,
1142
- InteriorField ( PositionalField ( i) ) ) ;
1143
-
1144
- self . cat_pattern_ ( subcmt, & subpat, op) ?;
1145
- }
1119
+ let expected_len = match self . tcx ( ) . expect_def ( pat. id ) {
1120
+ Def :: Variant ( enum_def, def_id) => {
1121
+ self . tcx ( ) . lookup_adt_def ( enum_def) . variant_with_id ( def_id) . fields . len ( )
1146
1122
}
1147
- Some ( Def :: Struct ( ..) ) => {
1148
- let expected_len = match self . pat_ty ( & pat) ?. sty {
1123
+ Def :: Struct ( ..) => {
1124
+ match self . pat_ty ( & pat) ?. sty {
1149
1125
ty:: TyStruct ( adt_def, _) => {
1150
1126
adt_def. struct_variant ( ) . fields . len ( )
1151
1127
}
1152
1128
ref ty => {
1153
1129
span_bug ! ( pat. span, "tuple struct pattern unexpected type {:?}" , ty) ;
1154
1130
}
1155
- } ;
1156
-
1157
- for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( expected_len, ddpos) {
1158
- let subpat_ty = self . pat_ty ( & subpat) ?; // see (*2)
1159
- let cmt_field =
1160
- self . cat_imm_interior (
1161
- pat, cmt. clone ( ) , subpat_ty,
1162
- InteriorField ( PositionalField ( i) ) ) ;
1163
- self . cat_pattern_ ( cmt_field, & subpat, op) ?;
1164
1131
}
1165
1132
}
1166
- Some ( Def :: Const ( ..) ) | Some ( Def :: AssociatedConst ( ..) ) => {
1167
- for subpat in subpats {
1168
- self . cat_pattern_ ( cmt. clone ( ) , & subpat, op) ?;
1169
- }
1170
- }
1171
- _ => {
1172
- span_bug ! (
1173
- pat. span,
1174
- "enum pattern didn't resolve to enum or struct {:?}" ,
1175
- opt_def) ;
1133
+ def => {
1134
+ span_bug ! ( pat. span, "tuple struct pattern didn't resolve \
1135
+ to variant or struct {:?}", def) ;
1176
1136
}
1177
- }
1178
- }
1179
-
1180
- PatKind :: Path ( ..) | PatKind :: QPath ( ..) | PatKind :: Binding ( _, _, None ) => {
1181
- // Lone constant, or unit variant or identifier: ignore
1182
- }
1137
+ } ;
1183
1138
1184
- PatKind :: Binding ( _, _, Some ( ref subpat) ) => {
1185
- self . cat_pattern_ ( cmt, & subpat, op) ?;
1139
+ for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( expected_len, ddpos) {
1140
+ let subpat_ty = self . pat_ty ( & subpat) ?; // see (*2)
1141
+ let subcmt = self . cat_imm_interior ( pat, cmt. clone ( ) , subpat_ty,
1142
+ InteriorField ( PositionalField ( i) ) ) ;
1143
+ self . cat_pattern_ ( subcmt, & subpat, op) ?;
1144
+ }
1186
1145
}
1187
1146
1188
1147
PatKind :: Struct ( _, ref field_pats, _) => {
@@ -1194,6 +1153,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
1194
1153
}
1195
1154
}
1196
1155
1156
+ PatKind :: Binding ( _, _, Some ( ref subpat) ) => {
1157
+ self . cat_pattern_ ( cmt, & subpat, op) ?;
1158
+ }
1159
+
1197
1160
PatKind :: Tuple ( ref subpats, ddpos) => {
1198
1161
// (p1, ..., pN)
1199
1162
let expected_len = match self . pat_ty ( & pat) ?. sty {
@@ -1202,10 +1165,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
1202
1165
} ;
1203
1166
for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( expected_len, ddpos) {
1204
1167
let subpat_ty = self . pat_ty ( & subpat) ?; // see (*2)
1205
- let subcmt =
1206
- self . cat_imm_interior (
1207
- pat, cmt. clone ( ) , subpat_ty,
1208
- InteriorField ( PositionalField ( i) ) ) ;
1168
+ let subcmt = self . cat_imm_interior ( pat, cmt. clone ( ) , subpat_ty,
1169
+ InteriorField ( PositionalField ( i) ) ) ;
1209
1170
self . cat_pattern_ ( subcmt, & subpat, op) ?;
1210
1171
}
1211
1172
}
@@ -1215,25 +1176,26 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
1215
1176
// PatKind::Ref since that information is already contained
1216
1177
// in the type.
1217
1178
let subcmt = self . cat_deref ( pat, cmt, 0 , None ) ?;
1218
- self . cat_pattern_ ( subcmt, & subpat, op) ?;
1179
+ self . cat_pattern_ ( subcmt, & subpat, op) ?;
1219
1180
}
1220
1181
1221
1182
PatKind :: Vec ( ref before, ref slice, ref after) => {
1222
- let context = InteriorOffsetKind :: Pattern ;
1223
- let elt_cmt = self . cat_index ( pat, cmt, context) ?;
1224
- for before_pat in before {
1225
- self . cat_pattern_ ( elt_cmt. clone ( ) , & before_pat, op) ?;
1226
- }
1227
- if let Some ( ref slice_pat) = * slice {
1228
- self . cat_pattern_ ( elt_cmt. clone ( ) , & slice_pat, op) ?;
1229
- }
1230
- for after_pat in after {
1231
- self . cat_pattern_ ( elt_cmt. clone ( ) , & after_pat, op) ?;
1232
- }
1183
+ let context = InteriorOffsetKind :: Pattern ;
1184
+ let elt_cmt = self . cat_index ( pat, cmt, context) ?;
1185
+ for before_pat in before {
1186
+ self . cat_pattern_ ( elt_cmt. clone ( ) , & before_pat, op) ?;
1187
+ }
1188
+ if let Some ( ref slice_pat) = * slice {
1189
+ self . cat_pattern_ ( elt_cmt. clone ( ) , & slice_pat, op) ?;
1190
+ }
1191
+ for after_pat in after {
1192
+ self . cat_pattern_ ( elt_cmt. clone ( ) , & after_pat, op) ?;
1193
+ }
1233
1194
}
1234
1195
1235
- PatKind :: Lit ( _) | PatKind :: Range ( _, _) => {
1236
- /*always ok*/
1196
+ PatKind :: Path ( ..) | PatKind :: QPath ( ..) | PatKind :: Binding ( _, _, None ) |
1197
+ PatKind :: Lit ( ..) | PatKind :: Range ( ..) | PatKind :: Wild => {
1198
+ // always ok
1237
1199
}
1238
1200
}
1239
1201
0 commit comments