1111//! This query borrow-checks the MIR to (further) ensure it is not broken.
1212
1313use rustc:: hir;
14- use rustc:: hir:: def:: Def ;
1514use rustc:: hir:: def_id:: { DefId } ;
1615use rustc:: infer:: { InferCtxt } ;
1716use rustc:: ty:: { self , TyCtxt , ParamEnv } ;
@@ -1022,7 +1021,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
10221021 access_lvalue : ( ShallowOrDeep , & Lvalue < ' tcx > ) ,
10231022 flow_state : & InProgress < ' b , ' gcx , ' tcx > ,
10241023 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
10261025 {
10271026 let ( access, lvalue) = access_lvalue;
10281027
@@ -1249,7 +1248,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
12491248 fn report_use_of_moved_or_uninitialized ( & mut self ,
12501249 _context : Context ,
12511250 desired_action : & str ,
1252- ( lvalue, span) : ( & Lvalue , Span ) ,
1251+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
12531252 mpi : MovePathIndex ,
12541253 curr_move_out : & IdxSetBuf < MoveOutIndex > ) {
12551254
@@ -1291,8 +1290,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
12911290
12921291 fn report_move_out_while_borrowed ( & mut self ,
12931292 _context : Context ,
1294- ( lvalue, span) : ( & Lvalue , Span ) ,
1295- borrow : & BorrowData ) {
1293+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1294+ borrow : & BorrowData < ' tcx > ) {
12961295 self . tcx . cannot_move_when_borrowed ( span,
12971296 & self . describe_lvalue ( lvalue) ,
12981297 Origin :: Mir )
@@ -1306,8 +1305,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
13061305
13071306 fn report_use_while_mutably_borrowed ( & mut self ,
13081307 _context : Context ,
1309- ( lvalue, span) : ( & Lvalue , Span ) ,
1310- borrow : & BorrowData ) {
1308+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1309+ borrow : & BorrowData < ' tcx > ) {
13111310
13121311 let mut err = self . tcx . cannot_use_when_mutably_borrowed (
13131312 span, & self . describe_lvalue ( lvalue) ,
@@ -1383,8 +1382,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
13831382
13841383 fn report_conflicting_borrow ( & mut self ,
13851384 context : Context ,
1386- common_prefix : & Lvalue ,
1387- ( lvalue, span) : ( & Lvalue , Span ) ,
1385+ common_prefix : & Lvalue < ' tcx > ,
1386+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
13881387 gen_borrow_kind : BorrowKind ,
13891388 issued_borrow : & BorrowData ,
13901389 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>
14541453
14551454 fn report_illegal_mutation_of_borrowed ( & mut self ,
14561455 _: Context ,
1457- ( lvalue, span) : ( & Lvalue , Span ) ,
1456+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
14581457 loan : & BorrowData ) {
14591458 let mut err = self . tcx . cannot_assign_to_borrowed (
14601459 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>
14641463
14651464 fn report_illegal_reassignment ( & mut self ,
14661465 _context : Context ,
1467- ( lvalue, span) : ( & Lvalue , Span ) ,
1466+ ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
14681467 assigned_span : Span ) {
14691468 self . tcx . cannot_reassign_immutable ( span,
14701469 & self . describe_lvalue ( lvalue) ,
@@ -1475,7 +1474,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
14751474 . emit ( ) ;
14761475 }
14771476
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 ) ) {
14791480 let mut err = self . tcx . cannot_assign_static (
14801481 span, & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
14811482 err. emit ( ) ;
@@ -1484,14 +1485,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
14841485
14851486impl < ' c , ' b , ' a : ' b +' c , ' gcx , ' tcx : ' a > MirBorrowckCtxt < ' c , ' b , ' a , ' gcx , ' tcx > {
14861487 // End-user visible description of `lvalue`
1487- fn describe_lvalue ( & self , lvalue : & Lvalue ) -> String {
1488+ fn describe_lvalue ( & self , lvalue : & Lvalue < ' tcx > ) -> String {
14881489 let mut buf = String :: new ( ) ;
14891490 self . append_lvalue_to_string ( lvalue, & mut buf, None ) ;
14901491 buf
14911492 }
14921493
14931494 // 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 > ) {
14951499 match * lvalue {
14961500 Lvalue :: Local ( local) => {
14971501 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>
15011505 }
15021506 Lvalue :: Projection ( ref proj) => {
15031507 let mut autoderef = autoderef. unwrap_or ( false ) ;
1504- let ( prefix, suffix, index_operand) = match proj. elem {
1508+
1509+ match proj. elem {
15051510 ProjectionElem :: Deref => {
15061511 if autoderef {
1507- ( "" , format ! ( "" ) , None )
1512+ self . append_lvalue_to_string ( & proj . base , buf , Some ( autoderef ) ) ;
15081513 } else {
1509- ( "(*" , format ! ( ")" ) , None )
1514+ buf. push_str ( & "(*" ) ;
1515+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1516+ buf. push_str ( & ")" ) ;
15101517 }
15111518 } ,
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+ } ,
15141522 ProjectionElem :: Field ( field, _ty) => {
15151523 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+ }
15171534 } ,
15181535 ProjectionElem :: Index ( index) => {
15191536 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 ( "]" ) ;
15211542 } ,
15221543 ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
15231544 autoderef = true ;
15241545 // Since it isn't possible to borrow an element on a particular index and
15251546 // then use another while the borrow is held, don't output indices details
15261547 // to avoid confusing the end-user
1527- ( "" , format ! ( "[..]" ) , None )
1548+ self . append_lvalue_to_string ( & proj. base , buf, Some ( autoderef) ) ;
1549+ buf. push_str ( & "[..]" ) ;
15281550 } ,
15291551 } ;
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- }
15391552 }
15401553 }
15411554 }
@@ -1609,12 +1622,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
16091622 // the closure comes from another crate. But in that case we wouldn't
16101623 // be borrowck'ing it, so we can just unwrap:
16111624 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] ) ;
16131626
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 ( )
16181628 }
16191629 _ => {
16201630 // Might need a revision when the fields in trait RFC is implemented
0 commit comments