@@ -1050,9 +1050,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10501050 }
10511051
10521052 // 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 )
10561055 {
10571056 // Here, `cmt` is the categorization for the value being
10581057 // matched and pat is the pattern it is being matched against.
@@ -1099,21 +1098,14 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
10991098 // step out of sync again. So you'll see below that we always
11001099 // get the type of the *subpattern* and use that.
11011100
1102- debug ! ( "cat_pattern: {:?} cmt={:?}" ,
1103- pat,
1104- cmt) ;
1105-
1106- ( * op) ( self , cmt. clone ( ) , pat) ;
1101+ debug ! ( "cat_pattern: {:?} cmt={:?}" , pat, cmt) ;
11071102
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) ;
11121104
11131105 // 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 ( ( ) ) ,
11171109 Some ( Def :: Variant ( enum_did, variant_did) )
11181110 // univariant enums do not need downcasts
11191111 if !self . tcx ( ) . lookup_adt_def ( enum_did) . is_univariant ( ) => {
@@ -1123,66 +1115,33 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
11231115 } ;
11241116
11251117 match pat. node {
1126- PatKind :: Wild => {
1127- // _
1128- }
1129-
11301118 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 ( )
11461122 }
1147- Some ( Def :: Struct ( ..) ) => {
1148- let expected_len = match self . pat_ty ( & pat) ?. sty {
1123+ Def :: Struct ( ..) => {
1124+ match self . pat_ty ( & pat) ?. sty {
11491125 ty:: TyStruct ( adt_def, _) => {
11501126 adt_def. struct_variant ( ) . fields . len ( )
11511127 }
11521128 ref ty => {
11531129 span_bug ! ( pat. span, "tuple struct pattern unexpected type {:?}" , ty) ;
11541130 }
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) ?;
11641131 }
11651132 }
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) ;
11761136 }
1177- }
1178- }
1179-
1180- PatKind :: Path ( ..) | PatKind :: QPath ( ..) | PatKind :: Binding ( _, _, None ) => {
1181- // Lone constant, or unit variant or identifier: ignore
1182- }
1137+ } ;
11831138
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+ }
11861145 }
11871146
11881147 PatKind :: Struct ( _, ref field_pats, _) => {
@@ -1194,6 +1153,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
11941153 }
11951154 }
11961155
1156+ PatKind :: Binding ( _, _, Some ( ref subpat) ) => {
1157+ self . cat_pattern_ ( cmt, & subpat, op) ?;
1158+ }
1159+
11971160 PatKind :: Tuple ( ref subpats, ddpos) => {
11981161 // (p1, ..., pN)
11991162 let expected_len = match self . pat_ty ( & pat) ?. sty {
@@ -1202,10 +1165,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12021165 } ;
12031166 for ( i, subpat) in subpats. iter ( ) . enumerate_and_adjust ( expected_len, ddpos) {
12041167 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) ) ) ;
12091170 self . cat_pattern_ ( subcmt, & subpat, op) ?;
12101171 }
12111172 }
@@ -1215,25 +1176,26 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12151176 // PatKind::Ref since that information is already contained
12161177 // in the type.
12171178 let subcmt = self . cat_deref ( pat, cmt, 0 , None ) ?;
1218- self . cat_pattern_ ( subcmt, & subpat, op) ?;
1179+ self . cat_pattern_ ( subcmt, & subpat, op) ?;
12191180 }
12201181
12211182 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+ }
12331194 }
12341195
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
12371199 }
12381200 }
12391201
0 commit comments