@@ -1021,7 +1021,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1021
1021
access_lvalue : ( ShallowOrDeep , & Lvalue < ' tcx > ) ,
1022
1022
flow_state : & InProgress < ' b , ' gcx , ' tcx > ,
1023
1023
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
1025
1025
{
1026
1026
let ( access, lvalue) = access_lvalue;
1027
1027
@@ -1248,7 +1248,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1248
1248
fn report_use_of_moved_or_uninitialized ( & mut self ,
1249
1249
_context : Context ,
1250
1250
desired_action : & str ,
1251
- ( lvalue, span) : ( & Lvalue , Span ) ,
1251
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1252
1252
mpi : MovePathIndex ,
1253
1253
curr_move_out : & IdxSetBuf < MoveOutIndex > ) {
1254
1254
@@ -1290,8 +1290,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1290
1290
1291
1291
fn report_move_out_while_borrowed ( & mut self ,
1292
1292
_context : Context ,
1293
- ( lvalue, span) : ( & Lvalue , Span ) ,
1294
- borrow : & BorrowData ) {
1293
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1294
+ borrow : & BorrowData < ' tcx > ) {
1295
1295
self . tcx . cannot_move_when_borrowed ( span,
1296
1296
& self . describe_lvalue ( lvalue) ,
1297
1297
Origin :: Mir )
@@ -1305,8 +1305,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1305
1305
1306
1306
fn report_use_while_mutably_borrowed ( & mut self ,
1307
1307
_context : Context ,
1308
- ( lvalue, span) : ( & Lvalue , Span ) ,
1309
- borrow : & BorrowData ) {
1308
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1309
+ borrow : & BorrowData < ' tcx > ) {
1310
1310
1311
1311
let mut err = self . tcx . cannot_use_when_mutably_borrowed (
1312
1312
span, & self . describe_lvalue ( lvalue) ,
@@ -1382,8 +1382,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1382
1382
1383
1383
fn report_conflicting_borrow ( & mut self ,
1384
1384
context : Context ,
1385
- common_prefix : & Lvalue ,
1386
- ( lvalue, span) : ( & Lvalue , Span ) ,
1385
+ common_prefix : & Lvalue < ' tcx > ,
1386
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1387
1387
gen_borrow_kind : BorrowKind ,
1388
1388
issued_borrow : & BorrowData ,
1389
1389
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>
1453
1453
1454
1454
fn report_illegal_mutation_of_borrowed ( & mut self ,
1455
1455
_: Context ,
1456
- ( lvalue, span) : ( & Lvalue , Span ) ,
1456
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1457
1457
loan : & BorrowData ) {
1458
1458
let mut err = self . tcx . cannot_assign_to_borrowed (
1459
1459
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>
1463
1463
1464
1464
fn report_illegal_reassignment ( & mut self ,
1465
1465
_context : Context ,
1466
- ( lvalue, span) : ( & Lvalue , Span ) ,
1466
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1467
1467
assigned_span : Span ) {
1468
1468
self . tcx . cannot_reassign_immutable ( span,
1469
1469
& self . describe_lvalue ( lvalue) ,
@@ -1474,7 +1474,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1474
1474
. emit ( ) ;
1475
1475
}
1476
1476
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 ) ) {
1478
1480
let mut err = self . tcx . cannot_assign_static (
1479
1481
span, & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
1480
1482
err. emit ( ) ;
@@ -1483,14 +1485,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1483
1485
1484
1486
impl < ' c , ' b , ' a : ' b +' c , ' gcx , ' tcx : ' a > MirBorrowckCtxt < ' c , ' b , ' a , ' gcx , ' tcx > {
1485
1487
// End-user visible description of `lvalue`
1486
- fn describe_lvalue ( & self , lvalue : & Lvalue ) -> String {
1488
+ fn describe_lvalue ( & self , lvalue : & Lvalue < ' tcx > ) -> String {
1487
1489
let mut buf = String :: new ( ) ;
1488
1490
self . append_lvalue_to_string ( lvalue, & mut buf, None ) ;
1489
1491
buf
1490
1492
}
1491
1493
1492
1494
// 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 > ) {
1494
1499
match * lvalue {
1495
1500
Lvalue :: Local ( local) => {
1496
1501
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>
1500
1505
}
1501
1506
Lvalue :: Projection ( ref proj) => {
1502
1507
let mut autoderef = autoderef. unwrap_or ( false ) ;
1503
- let ( prefix, suffix, index_operand) = match proj. elem {
1508
+
1509
+ match proj. elem {
1504
1510
ProjectionElem :: Deref => {
1505
1511
if autoderef {
1506
- ( "" , format ! ( "" ) , None )
1512
+ self . append_lvalue_to_string ( & proj . base , buf , Some ( autoderef ) ) ;
1507
1513
} else {
1508
- ( "(*" , format ! ( ")" ) , None )
1514
+ buf. push_str ( & "(*" ) ;
1515
+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1516
+ buf. push_str ( & ")" ) ;
1509
1517
}
1510
1518
} ,
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
+ } ,
1513
1522
ProjectionElem :: Field ( field, _ty) => {
1514
1523
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
+ }
1516
1534
} ,
1517
1535
ProjectionElem :: Index ( index) => {
1518
1536
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 ( "]" ) ;
1520
1542
} ,
1521
1543
ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
1522
1544
autoderef = true ;
1523
1545
// Since it isn't possible to borrow an element on a particular index and
1524
1546
// then use another while the borrow is held, don't output indices details
1525
1547
// to avoid confusing the end-user
1526
- ( "" , format ! ( "[..]" ) , None )
1548
+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1549
+ buf. push_str ( & "[..]" ) ;
1527
1550
} ,
1528
1551
} ;
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
- }
1538
1552
}
1539
1553
}
1540
1554
}
@@ -1549,6 +1563,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1549
1563
}
1550
1564
}
1551
1565
1566
+ // FIXME Instead of passing usize, Field should be passed
1552
1567
// End-user visible description of the `field_index`nth field of `base`
1553
1568
fn describe_field ( & self , base : & Lvalue , field_index : usize ) -> String {
1554
1569
match * base {
@@ -1600,7 +1615,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1600
1615
} ,
1601
1616
ty:: TyArray ( ty, _) | ty:: TySlice ( ty) => {
1602
1617
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
+ }
1604
1629
_ => {
1605
1630
// Might need a revision when the fields in trait RFC is implemented
1606
1631
// (https://github.com/rust-lang/rfcs/pull/1546)
0 commit comments