@@ -1021,7 +1021,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
10211021 access_lvalue : ( ShallowOrDeep , & Lvalue < ' tcx > ) ,
10221022 flow_state : & InProgress < ' b , ' gcx , ' tcx > ,
10231023 mut op : F )
1024- where F : FnMut ( & mut Self , BorrowIndex , & BorrowData < ' tcx > , & Lvalue ) -> Control
1024+ where F : FnMut ( & mut Self , BorrowIndex , & BorrowData < ' tcx > , & Lvalue < ' tcx > ) -> Control
10251025 {
10261026 let ( access, lvalue) = access_lvalue;
10271027
@@ -1248,7 +1248,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
12481248 fn report_use_of_moved_or_uninitialized ( & mut self ,
12491249 _context : Context ,
12501250 desired_action : & str ,
1251- ( lvalue, span) : ( & Lvalue , Span ) ,
1251+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
12521252 mpi : MovePathIndex ,
12531253 curr_move_out : & IdxSetBuf < MoveOutIndex > ) {
12541254
@@ -1290,8 +1290,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
12901290
12911291 fn report_move_out_while_borrowed ( & mut self ,
12921292 _context : Context ,
1293- ( lvalue, span) : ( & Lvalue , Span ) ,
1294- borrow : & BorrowData ) {
1293+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1294+ borrow : & BorrowData < ' tcx > ) {
12951295 self . tcx . cannot_move_when_borrowed ( span,
12961296 & self . describe_lvalue ( lvalue) ,
12971297 Origin :: Mir )
@@ -1305,8 +1305,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
13051305
13061306 fn report_use_while_mutably_borrowed ( & mut self ,
13071307 _context : Context ,
1308- ( lvalue, span) : ( & Lvalue , Span ) ,
1309- borrow : & BorrowData ) {
1308+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1309+ borrow : & BorrowData < ' tcx > ) {
13101310
13111311 let mut err = self . tcx . cannot_use_when_mutably_borrowed (
13121312 span, & self . describe_lvalue ( lvalue) ,
@@ -1382,8 +1382,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
13821382
13831383 fn report_conflicting_borrow ( & mut self ,
13841384 context : Context ,
1385- common_prefix : & Lvalue ,
1386- ( lvalue, span) : ( & Lvalue , Span ) ,
1385+ common_prefix : & Lvalue < ' tcx > ,
1386+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
13871387 gen_borrow_kind : BorrowKind ,
13881388 issued_borrow : & BorrowData ,
13891389 end_issued_loan_span : Option < Span > ) {
@@ -1453,7 +1453,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
14531453
14541454 fn report_illegal_mutation_of_borrowed ( & mut self ,
14551455 _: Context ,
1456- ( lvalue, span) : ( & Lvalue , Span ) ,
1456+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
14571457 loan : & BorrowData ) {
14581458 let mut err = self . tcx . cannot_assign_to_borrowed (
14591459 span, self . retrieve_borrow_span ( loan) , & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
@@ -1463,7 +1463,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
14631463
14641464 fn report_illegal_reassignment ( & mut self ,
14651465 _context : Context ,
1466- ( lvalue, span) : ( & Lvalue , Span ) ,
1466+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
14671467 assigned_span : Span ) {
14681468 self . tcx . cannot_reassign_immutable ( span,
14691469 & self . describe_lvalue ( lvalue) ,
@@ -1474,7 +1474,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
14741474 . emit ( ) ;
14751475 }
14761476
1477- fn report_assignment_to_static ( & mut self , _context : Context , ( lvalue, span) : ( & Lvalue , Span ) ) {
1477+ fn report_assignment_to_static ( & mut self ,
1478+ _context : Context ,
1479+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ) {
14781480 let mut err = self . tcx . cannot_assign_static (
14791481 span, & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
14801482 err. emit ( ) ;
@@ -1483,14 +1485,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
14831485
14841486impl < ' c , ' b , ' a : ' b +' c , ' gcx , ' tcx : ' a > MirBorrowckCtxt < ' c , ' b , ' a , ' gcx , ' tcx > {
14851487 // End-user visible description of `lvalue`
1486- fn describe_lvalue ( & self , lvalue : & Lvalue ) -> String {
1488+ fn describe_lvalue ( & self , lvalue : & Lvalue < ' tcx > ) -> String {
14871489 let mut buf = String :: new ( ) ;
14881490 self . append_lvalue_to_string ( lvalue, & mut buf, None ) ;
14891491 buf
14901492 }
14911493
14921494 // Appends end-user visible description of `lvalue` to `buf`.
1493- fn append_lvalue_to_string ( & self , lvalue : & Lvalue , buf : & mut String , autoderef : Option < bool > ) {
1495+ fn append_lvalue_to_string ( & self ,
1496+ lvalue : & Lvalue < ' tcx > ,
1497+ buf : & mut String ,
1498+ autoderef : Option < bool > ) {
14941499 match * lvalue {
14951500 Lvalue :: Local ( local) => {
14961501 self . append_local_to_string ( local, buf, "_" ) ;
@@ -1500,41 +1505,50 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
15001505 }
15011506 Lvalue :: Projection ( ref proj) => {
15021507 let mut autoderef = autoderef. unwrap_or ( false ) ;
1503- let ( prefix, suffix, index_operand) = match proj. elem {
1508+
1509+ match proj. elem {
15041510 ProjectionElem :: Deref => {
15051511 if autoderef {
1506- ( "" , format ! ( "" ) , None )
1512+ self . append_lvalue_to_string ( & proj . base , buf , Some ( autoderef ) ) ;
15071513 } else {
1508- ( "(*" , format ! ( ")" ) , None )
1514+ buf. push_str ( & "(*" ) ;
1515+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1516+ buf. push_str ( & ")" ) ;
15091517 }
15101518 } ,
1511- ProjectionElem :: Downcast ( ..) =>
1512- ( "" , format ! ( "" ) , None ) , // (dont emit downcast info)
1519+ ProjectionElem :: Downcast ( ..) => {
1520+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1521+ } ,
15131522 ProjectionElem :: Field ( field, _ty) => {
15141523 autoderef = true ;
1515- ( "" , format ! ( ".{}" , self . describe_field( & proj. base, field. index( ) ) ) , None )
1524+ let is_projection_from_ty_closure = proj. base . ty ( self . mir , self . tcx )
1525+ . to_ty ( self . tcx ) . is_closure ( ) ;
1526+
1527+ let field_name = self . describe_field ( & proj. base , field. index ( ) ) ;
1528+ if is_projection_from_ty_closure {
1529+ buf. push_str ( & format ! ( "{}" , field_name) ) ;
1530+ } else {
1531+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1532+ buf. push_str ( & format ! ( ".{}" , field_name) ) ;
1533+ }
15161534 } ,
15171535 ProjectionElem :: Index ( index) => {
15181536 autoderef = true ;
1519- ( "" , format ! ( "" ) , Some ( index) )
1537+
1538+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1539+ buf. push_str ( "[" ) ;
1540+ self . append_local_to_string ( index, buf, ".." ) ;
1541+ buf. push_str ( "]" ) ;
15201542 } ,
15211543 ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
15221544 autoderef = true ;
15231545 // Since it isn't possible to borrow an element on a particular index and
15241546 // then use another while the borrow is held, don't output indices details
15251547 // to avoid confusing the end-user
1526- ( "" , format ! ( "[..]" ) , None )
1548+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1549+ buf. push_str ( & "[..]" ) ;
15271550 } ,
15281551 } ;
1529- buf. push_str ( prefix) ;
1530- self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1531- if let Some ( index) = index_operand {
1532- buf. push_str ( "[" ) ;
1533- self . append_local_to_string ( index, buf, ".." ) ;
1534- buf. push_str ( "]" ) ;
1535- } else {
1536- buf. push_str ( & suffix) ;
1537- }
15381552 }
15391553 }
15401554 }
@@ -1549,6 +1563,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
15491563 }
15501564 }
15511565
1566+ // FIXME Instead of passing usize, Field should be passed
15521567 // End-user visible description of the `field_index`nth field of `base`
15531568 fn describe_field ( & self , base : & Lvalue , field_index : usize ) -> String {
15541569 match * base {
@@ -1600,7 +1615,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
16001615 } ,
16011616 ty:: TyArray ( ty, _) | ty:: TySlice ( ty) => {
16021617 self . describe_field_from_ty ( & ty, field_index)
1603- }
1618+ } ,
1619+ ty:: TyClosure ( closure_def_id, _) => {
1620+ // Convert the def-id into a node-id. node-ids are only valid for
1621+ // the local code in the current crate, so this returns an `Option` in case
1622+ // the closure comes from another crate. But in that case we wouldn't
1623+ // be borrowck'ing it, so we can just unwrap:
1624+ let node_id = self . tcx . hir . as_local_node_id ( closure_def_id) . unwrap ( ) ;
1625+ let freevar = self . tcx . with_freevars ( node_id, |fv| fv[ field_index] ) ;
1626+
1627+ self . tcx . hir . name ( freevar. var_id ( ) ) . to_string ( )
1628+ }
16041629 _ => {
16051630 // Might need a revision when the fields in trait RFC is implemented
16061631 // (https://github.com/rust-lang/rfcs/pull/1546)
0 commit comments