@@ -240,7 +240,11 @@ impl ast_node for ast::Pat {
240240}
241241
242242pub 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 ,
244248}
245249
246250pub type McResult < T > = Result < T , ( ) > ;
@@ -378,7 +382,20 @@ macro_rules! if_ok(
378382
379383impl < ' t , ' tcx , TYPER : Typer < ' tcx > > MemCategorizationContext < ' t , TYPER > {
380384 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+ }
382399 }
383400
384401 fn tcx ( & self ) -> & ' t ty:: ctxt < ' tcx > {
@@ -1126,8 +1143,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
11261143 }
11271144 }
11281145
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) ) ;
11311148 }
11321149
11331150 ast:: PatIdent ( _, _, None ) => {
@@ -1136,9 +1153,21 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
11361153
11371154 ast:: PatStruct ( _, ref field_pats, _) => {
11381155 // {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+
11391168 for fp in field_pats. iter ( ) {
11401169 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) ;
11421171 if_ok ! ( self . cat_pattern( cmt_field, & * fp. pat, |x, y, z| op( x, y, z) ) ) ;
11431172 }
11441173 }
@@ -1377,8 +1406,8 @@ impl Repr for categorization {
13771406 cat_interior( ref cmt, interior) => {
13781407 format ! ( "{}.{}" , cmt. cat. repr( tcx) , interior. repr( tcx) )
13791408 }
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) )
13821411 }
13831412 cat_discr( ref cmt, _) => {
13841413 cmt. cat . repr ( tcx)
0 commit comments