@@ -15,9 +15,9 @@ use rustc::hir::def_id::{DefId};
1515use  rustc:: infer:: { InferCtxt } ; 
1616use  rustc:: ty:: { self ,  TyCtxt ,  ParamEnv } ; 
1717use  rustc:: ty:: maps:: Providers ; 
18- use  rustc:: mir:: { AssertMessage ,  BasicBlock ,  BorrowKind ,  Field ,   Location ,  Lvalue ,  Local } ; 
18+ use  rustc:: mir:: { AssertMessage ,  BasicBlock ,  BorrowKind ,  Location ,  Lvalue ,  Local } ; 
1919use  rustc:: mir:: { Mir ,  Mutability ,  Operand ,  Projection ,  ProjectionElem ,  Rvalue } ; 
20- use  rustc:: mir:: { Statement ,  StatementKind ,  Terminator ,  TerminatorKind } ; 
20+ use  rustc:: mir:: { Field ,   Statement ,  StatementKind ,  Terminator ,  TerminatorKind } ; 
2121use  transform:: nll; 
2222
2323use  rustc_data_structures:: fx:: FxHashSet ; 
@@ -1581,6 +1581,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15811581        buf
15821582    } 
15831583
1584+     /// If this is a field projection, and the field is being projected from a closure type, 
1585+ /// then returns the index of the field being projected. Note that this closure will always 
1586+ /// be `self` in the current MIR, because that is the only time we directly access the fields 
1587+ /// of a closure type. 
1588+ fn  is_upvar_field_projection ( & self ,  lvalue :  & Lvalue < ' tcx > )  -> Option < Field >  { 
1589+         match  * lvalue { 
1590+             Lvalue :: Projection ( ref  proj)  => { 
1591+                 match  proj. elem  { 
1592+                     ProjectionElem :: Field ( field,  _ty)  => { 
1593+                         let  is_projection_from_ty_closure = proj. base . ty ( self . mir ,  self . tcx ) 
1594+                                 . to_ty ( self . tcx ) . is_closure ( ) ; 
1595+ 
1596+                         if  is_projection_from_ty_closure { 
1597+                             Some ( field) 
1598+                         }  else  { 
1599+                             None 
1600+                         } 
1601+                     } , 
1602+                     _ => None 
1603+                 } 
1604+             } , 
1605+             _ => None 
1606+         } 
1607+     } 
1608+ 
15841609    // Appends end-user visible description of `lvalue` to `buf`. 
15851610    fn  append_lvalue_to_string ( & self , 
15861611                               lvalue :  & Lvalue < ' tcx > , 
@@ -1596,25 +1621,35 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15961621            Lvalue :: Projection ( ref  proj)  => { 
15971622                match  proj. elem  { 
15981623                    ProjectionElem :: Deref  => { 
1599-                         if  autoderef { 
1600-                             self . append_lvalue_to_string ( & proj. base ,  buf,  autoderef) ; 
1624+                         if  let  Some ( field)  = self . is_upvar_field_projection ( & proj. base )  { 
1625+                             let  var_index = field. index ( ) ; 
1626+                             let  name = self . mir . upvar_decls [ var_index] . debug_name . to_string ( ) ; 
1627+                             if  self . mir . upvar_decls [ var_index] . by_ref  { 
1628+                                 buf. push_str ( & name) ; 
1629+                             }  else  { 
1630+                                 buf. push_str ( & format ! ( "*{}" ,  & name) ) ; 
1631+                             } 
16011632                        }  else  { 
1602-                             buf. push_str ( & "*" ) ; 
1603-                             self . append_lvalue_to_string ( & proj. base ,  buf,  autoderef) ; 
1633+                             if  autoderef { 
1634+                                 self . append_lvalue_to_string ( & proj. base ,  buf,  autoderef) ; 
1635+                             }  else  { 
1636+                                 buf. push_str ( & "*" ) ; 
1637+                                 self . append_lvalue_to_string ( & proj. base ,  buf,  autoderef) ; 
1638+                             } 
16041639                        } 
16051640                    } , 
16061641                    ProjectionElem :: Downcast ( ..)  => { 
16071642                        self . append_lvalue_to_string ( & proj. base ,  buf,  autoderef) ; 
16081643                    } , 
16091644                    ProjectionElem :: Field ( field,  _ty)  => { 
16101645                        autoderef = true ; 
1611-                         let  is_projection_from_ty_closure = proj. base . ty ( self . mir ,  self . tcx ) 
1612-                                 . to_ty ( self . tcx ) . is_closure ( ) ; 
16131646
1614-                         let  field_name = self . describe_field ( & proj. base ,  field) ; 
1615-                         if  is_projection_from_ty_closure { 
1616-                             buf. push_str ( & format ! ( "{}" ,  field_name) ) ; 
1647+                         if  let  Some ( field)  = self . is_upvar_field_projection ( lvalue)  { 
1648+                             let  var_index = field. index ( ) ; 
1649+                             let  name = self . mir . upvar_decls [ var_index] . debug_name . to_string ( ) ; 
1650+                             buf. push_str ( & name) ; 
16171651                        }  else  { 
1652+                             let  field_name = self . describe_field ( & proj. base ,  field) ; 
16181653                            self . append_lvalue_to_string ( & proj. base ,  buf,  autoderef) ; 
16191654                            buf. push_str ( & format ! ( ".{}" ,  field_name) ) ; 
16201655                        } 
0 commit comments