@@ -240,7 +240,11 @@ impl ast_node for ast::Pat {
240
240
}
241
241
242
242
pub struct MemCategorizationContext < ' t , TYPER : ' t > {
243
- typer : & ' t TYPER
243
+ typer : & ' t TYPER ,
244
+
245
+ // tracks when looking at `pat` in context of `id @ (... pat ...)`
246
+ // (it affects whether we move into a wildcard or not).
247
+ pub pat_is_already_bound_by_value : bool ,
244
248
}
245
249
246
250
pub type McResult < T > = Result < T , ( ) > ;
@@ -378,7 +382,20 @@ macro_rules! if_ok(
378
382
379
383
impl < ' t , ' tcx , TYPER : Typer < ' tcx > > MemCategorizationContext < ' t , TYPER > {
380
384
pub fn new ( typer : & ' t TYPER ) -> MemCategorizationContext < ' t , TYPER > {
381
- MemCategorizationContext { typer : typer }
385
+ MemCategorizationContext {
386
+ typer : typer,
387
+ pat_is_already_bound_by_value : false ,
388
+ }
389
+ }
390
+
391
+ fn already_bound ( & self , mode : ast:: BindingMode ) -> MemCategorizationContext < ' t , TYPER > {
392
+ match mode {
393
+ ast:: BindByRef ( _) => * self ,
394
+ ast:: BindByValue ( _) => MemCategorizationContext {
395
+ pat_is_already_bound_by_value : true ,
396
+ ..* self
397
+ }
398
+ }
382
399
}
383
400
384
401
fn tcx ( & self ) -> & ' t ty:: ctxt < ' tcx > {
@@ -1126,8 +1143,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
1126
1143
}
1127
1144
}
1128
1145
1129
- ast:: PatIdent ( _ , _, Some ( ref subpat) ) => {
1130
- if_ok ! ( self . cat_pattern( cmt, & * * subpat, op) ) ;
1146
+ ast:: PatIdent ( binding_mode , _, Some ( ref subpat) ) => {
1147
+ if_ok ! ( self . already_bound ( binding_mode ) . cat_pattern( cmt, & * * subpat, op) ) ;
1131
1148
}
1132
1149
1133
1150
ast:: PatIdent ( _, _, None ) => {
@@ -1136,9 +1153,21 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
1136
1153
1137
1154
ast:: PatStruct ( _, ref field_pats, _) => {
1138
1155
// {f1: p1, ..., fN: pN}
1156
+ let downcast_cmt = match self . tcx ( ) . def_map . borrow ( ) . find ( & pat. id ) {
1157
+ Some ( & def:: DefVariant ( enum_did, variant_did, _) ) => {
1158
+ // variant{ a: x, b: y, c: z }
1159
+ if ty:: enum_is_univariant ( self . tcx ( ) , enum_did) {
1160
+ cmt // univariant, no downcast needed
1161
+ } else {
1162
+ self . cat_downcast ( pat, cmt. clone ( ) , cmt. ty , variant_did)
1163
+ }
1164
+ }
1165
+ _ => cmt,
1166
+ } ;
1167
+
1139
1168
for fp in field_pats. iter ( ) {
1140
1169
let field_ty = if_ok ! ( self . pat_ty( & * fp. pat) ) ; // see (*2)
1141
- let cmt_field = self . cat_field ( pat, cmt . clone ( ) , fp. ident , field_ty) ;
1170
+ let cmt_field = self . cat_field ( pat, downcast_cmt . clone ( ) , fp. ident , field_ty) ;
1142
1171
if_ok ! ( self . cat_pattern( cmt_field, & * fp. pat, |x, y, z| op( x, y, z) ) ) ;
1143
1172
}
1144
1173
}
@@ -1377,8 +1406,8 @@ impl Repr for categorization {
1377
1406
cat_interior( ref cmt, interior) => {
1378
1407
format ! ( "{}.{}" , cmt. cat. repr( tcx) , interior. repr( tcx) )
1379
1408
}
1380
- cat_downcast( ref cmt, _ ) => {
1381
- format ! ( "{}->(enum )" , cmt. cat. repr( tcx) )
1409
+ cat_downcast( ref cmt, ref variant_did ) => {
1410
+ format ! ( "( {}->{} )" , cmt. cat. repr ( tcx ) , variant_did . repr( tcx) )
1382
1411
}
1383
1412
cat_discr( ref cmt, _) => {
1384
1413
cmt. cat . repr ( tcx)
0 commit comments