11
11
//! This query borrow-checks the MIR to (further) ensure it is not broken.
12
12
13
13
use rustc:: hir;
14
- use rustc:: hir:: def:: Def ;
15
14
use rustc:: hir:: def_id:: { DefId } ;
16
15
use rustc:: infer:: { InferCtxt } ;
17
16
use rustc:: ty:: { self , TyCtxt , ParamEnv } ;
@@ -1022,7 +1021,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1022
1021
access_lvalue : ( ShallowOrDeep , & Lvalue < ' tcx > ) ,
1023
1022
flow_state : & InProgress < ' b , ' gcx , ' tcx > ,
1024
1023
mut op : F )
1025
- where F : FnMut ( & mut Self , BorrowIndex , & BorrowData < ' tcx > , & Lvalue ) -> Control
1024
+ where F : FnMut ( & mut Self , BorrowIndex , & BorrowData < ' tcx > , & Lvalue < ' tcx > ) -> Control
1026
1025
{
1027
1026
let ( access, lvalue) = access_lvalue;
1028
1027
@@ -1249,7 +1248,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1249
1248
fn report_use_of_moved_or_uninitialized ( & mut self ,
1250
1249
_context : Context ,
1251
1250
desired_action : & str ,
1252
- ( lvalue, span) : ( & Lvalue , Span ) ,
1251
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1253
1252
mpi : MovePathIndex ,
1254
1253
curr_move_out : & IdxSetBuf < MoveOutIndex > ) {
1255
1254
@@ -1291,8 +1290,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1291
1290
1292
1291
fn report_move_out_while_borrowed ( & mut self ,
1293
1292
_context : Context ,
1294
- ( lvalue, span) : ( & Lvalue , Span ) ,
1295
- borrow : & BorrowData ) {
1293
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1294
+ borrow : & BorrowData < ' tcx > ) {
1296
1295
self . tcx . cannot_move_when_borrowed ( span,
1297
1296
& self . describe_lvalue ( lvalue) ,
1298
1297
Origin :: Mir )
@@ -1306,8 +1305,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1306
1305
1307
1306
fn report_use_while_mutably_borrowed ( & mut self ,
1308
1307
_context : Context ,
1309
- ( lvalue, span) : ( & Lvalue , Span ) ,
1310
- borrow : & BorrowData ) {
1308
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1309
+ borrow : & BorrowData < ' tcx > ) {
1311
1310
1312
1311
let mut err = self . tcx . cannot_use_when_mutably_borrowed (
1313
1312
span, & self . describe_lvalue ( lvalue) ,
@@ -1383,8 +1382,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1383
1382
1384
1383
fn report_conflicting_borrow ( & mut self ,
1385
1384
context : Context ,
1386
- common_prefix : & Lvalue ,
1387
- ( lvalue, span) : ( & Lvalue , Span ) ,
1385
+ common_prefix : & Lvalue < ' tcx > ,
1386
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1388
1387
gen_borrow_kind : BorrowKind ,
1389
1388
issued_borrow : & BorrowData ,
1390
1389
end_issued_loan_span : Option < Span > ) {
@@ -1454,7 +1453,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1454
1453
1455
1454
fn report_illegal_mutation_of_borrowed ( & mut self ,
1456
1455
_: Context ,
1457
- ( lvalue, span) : ( & Lvalue , Span ) ,
1456
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1458
1457
loan : & BorrowData ) {
1459
1458
let mut err = self . tcx . cannot_assign_to_borrowed (
1460
1459
span, self . retrieve_borrow_span ( loan) , & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
@@ -1464,7 +1463,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1464
1463
1465
1464
fn report_illegal_reassignment ( & mut self ,
1466
1465
_context : Context ,
1467
- ( lvalue, span) : ( & Lvalue , Span ) ,
1466
+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1468
1467
assigned_span : Span ) {
1469
1468
self . tcx . cannot_reassign_immutable ( span,
1470
1469
& self . describe_lvalue ( lvalue) ,
@@ -1475,7 +1474,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1475
1474
. emit ( ) ;
1476
1475
}
1477
1476
1478
- 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 ) ) {
1479
1480
let mut err = self . tcx . cannot_assign_static (
1480
1481
span, & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
1481
1482
err. emit ( ) ;
@@ -1484,14 +1485,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1484
1485
1485
1486
impl < ' c , ' b , ' a : ' b +' c , ' gcx , ' tcx : ' a > MirBorrowckCtxt < ' c , ' b , ' a , ' gcx , ' tcx > {
1486
1487
// End-user visible description of `lvalue`
1487
- fn describe_lvalue ( & self , lvalue : & Lvalue ) -> String {
1488
+ fn describe_lvalue ( & self , lvalue : & Lvalue < ' tcx > ) -> String {
1488
1489
let mut buf = String :: new ( ) ;
1489
1490
self . append_lvalue_to_string ( lvalue, & mut buf, None ) ;
1490
1491
buf
1491
1492
}
1492
1493
1493
1494
// Appends end-user visible description of `lvalue` to `buf`.
1494
- 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 > ) {
1495
1499
match * lvalue {
1496
1500
Lvalue :: Local ( local) => {
1497
1501
self . append_local_to_string ( local, buf, "_" ) ;
@@ -1501,41 +1505,50 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1501
1505
}
1502
1506
Lvalue :: Projection ( ref proj) => {
1503
1507
let mut autoderef = autoderef. unwrap_or ( false ) ;
1504
- let ( prefix, suffix, index_operand) = match proj. elem {
1508
+
1509
+ match proj. elem {
1505
1510
ProjectionElem :: Deref => {
1506
1511
if autoderef {
1507
- ( "" , format ! ( "" ) , None )
1512
+ self . append_lvalue_to_string ( & proj . base , buf , Some ( autoderef ) ) ;
1508
1513
} else {
1509
- ( "(*" , format ! ( ")" ) , None )
1514
+ buf. push_str ( & "(*" ) ;
1515
+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1516
+ buf. push_str ( & ")" ) ;
1510
1517
}
1511
1518
} ,
1512
- ProjectionElem :: Downcast ( ..) =>
1513
- ( "" , format ! ( "" ) , None ) , // (dont emit downcast info)
1519
+ ProjectionElem :: Downcast ( ..) => {
1520
+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1521
+ } ,
1514
1522
ProjectionElem :: Field ( field, _ty) => {
1515
1523
autoderef = true ;
1516
- ( "" , 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
+ }
1517
1534
} ,
1518
1535
ProjectionElem :: Index ( index) => {
1519
1536
autoderef = true ;
1520
- ( "" , 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 ( "]" ) ;
1521
1542
} ,
1522
1543
ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
1523
1544
autoderef = true ;
1524
1545
// Since it isn't possible to borrow an element on a particular index and
1525
1546
// then use another while the borrow is held, don't output indices details
1526
1547
// to avoid confusing the end-user
1527
- ( "" , format ! ( "[..]" ) , None )
1548
+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1549
+ buf. push_str ( & "[..]" ) ;
1528
1550
} ,
1529
1551
} ;
1530
- buf. push_str ( prefix) ;
1531
- self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1532
- if let Some ( index) = index_operand {
1533
- buf. push_str ( "[" ) ;
1534
- self . append_local_to_string ( index, buf, ".." ) ;
1535
- buf. push_str ( "]" ) ;
1536
- } else {
1537
- buf. push_str ( & suffix) ;
1538
- }
1539
1552
}
1540
1553
}
1541
1554
}
@@ -1609,12 +1622,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1609
1622
// the closure comes from another crate. But in that case we wouldn't
1610
1623
// be borrowck'ing it, so we can just unwrap:
1611
1624
let node_id = self . tcx . hir . as_local_node_id ( closure_def_id) . unwrap ( ) ;
1612
- let local_def = self . tcx . with_freevars ( node_id, |fv| fv[ field_index] . def ) ;
1625
+ let freevar = self . tcx . with_freevars ( node_id, |fv| fv[ field_index] ) ;
1613
1626
1614
- match local_def {
1615
- Def :: Local ( local_node_id) => self . tcx . hir . name ( local_node_id) . to_string ( ) ,
1616
- _ => unreachable ! ( )
1617
- }
1627
+ self . tcx . hir . name ( freevar. var_id ( ) ) . to_string ( )
1618
1628
}
1619
1629
_ => {
1620
1630
// Might need a revision when the fields in trait RFC is implemented
0 commit comments