@@ -1343,20 +1343,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13431343 |moi| curr_move_out. contains ( moi) ) . collect :: < Vec < _ > > ( ) ;
13441344
13451345 if mois. is_empty ( ) {
1346+ let item_msg = match self . describe_lvalue ( lvalue) {
1347+ Some ( name) => format ! ( "`{}`" , name) ,
1348+ None => "value" . to_owned ( )
1349+ } ;
13461350 self . tcx . cannot_act_on_uninitialized_variable ( span,
13471351 desired_action. as_noun ( ) ,
1348- & self . describe_lvalue ( lvalue) ,
1352+ & self . describe_lvalue ( lvalue)
1353+ . unwrap_or ( "_" . to_owned ( ) ) ,
13491354 Origin :: Mir )
1350- . span_label ( span, format ! ( "use of possibly uninitialized `{}`" ,
1351- self . describe_lvalue( lvalue) ) )
1355+ . span_label ( span, format ! ( "use of possibly uninitialized {}" , item_msg) )
13521356 . emit ( ) ;
13531357 } else {
13541358 let msg = "" ; //FIXME: add "partially " or "collaterally "
13551359
13561360 let mut err = self . tcx . cannot_act_on_moved_value ( span,
13571361 desired_action. as_noun ( ) ,
13581362 msg,
1359- & self . describe_lvalue ( lvalue) ,
1363+ & self . describe_lvalue ( lvalue)
1364+ . unwrap_or ( "_" . to_owned ( ) ) ,
13601365 Origin :: Mir ) ;
13611366
13621367 err. span_label ( span, format ! ( "value {} here after move" ,
@@ -1381,14 +1386,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13811386 _context : Context ,
13821387 ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
13831388 borrow : & BorrowData < ' tcx > ) {
1389+ let value_msg = match self . describe_lvalue ( lvalue) {
1390+ Some ( name) => format ! ( "`{}`" , name) ,
1391+ None => "value" . to_owned ( )
1392+ } ;
1393+ let borrow_msg = match self . describe_lvalue ( & borrow. lvalue ) {
1394+ Some ( name) => format ! ( "`{}`" , name) ,
1395+ None => "value" . to_owned ( )
1396+ } ;
13841397 self . tcx . cannot_move_when_borrowed ( span,
1385- & self . describe_lvalue ( lvalue) ,
1398+ & self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ,
13861399 Origin :: Mir )
13871400 . span_label ( self . retrieve_borrow_span ( borrow) ,
1388- format ! ( "borrow of `{}` occurs here" ,
1389- self . describe_lvalue( & borrow. lvalue) ) )
1390- . span_label ( span, format ! ( "move out of `{}` occurs here" ,
1391- self . describe_lvalue( lvalue) ) )
1401+ format ! ( "borrow of {} occurs here" , borrow_msg) )
1402+ . span_label ( span, format ! ( "move out of {} occurs here" , value_msg) )
13921403 . emit ( ) ;
13931404 }
13941405
@@ -1398,8 +1409,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13981409 borrow : & BorrowData < ' tcx > ) {
13991410
14001411 let mut err = self . tcx . cannot_use_when_mutably_borrowed (
1401- span, & self . describe_lvalue ( lvalue) ,
1402- self . retrieve_borrow_span ( borrow) , & self . describe_lvalue ( & borrow. lvalue ) ,
1412+ span,
1413+ & self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ,
1414+ self . retrieve_borrow_span ( borrow) ,
1415+ & self . describe_lvalue ( & borrow. lvalue ) . unwrap_or ( "_" . to_owned ( ) ) ,
14031416 Origin :: Mir ) ;
14041417
14051418 err. emit ( ) ;
@@ -1488,7 +1501,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
14881501 let old_closure_span = self . find_closure_span ( issued_span, issued_borrow. location ) ;
14891502 let issued_span = old_closure_span. map ( |( args, _) | args) . unwrap_or ( issued_span) ;
14901503
1491- let desc_lvalue = self . describe_lvalue ( lvalue) ;
1504+ let desc_lvalue = self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ;
14921505
14931506 // FIXME: supply non-"" `opt_via` when appropriate
14941507 let mut err = match ( gen_borrow_kind, "immutable" , "mutable" ,
@@ -1566,7 +1579,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15661579 ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
15671580 loan : & BorrowData ) {
15681581 let mut err = self . tcx . cannot_assign_to_borrowed (
1569- span, self . retrieve_borrow_span ( loan) , & self . describe_lvalue ( lvalue) , Origin :: Mir ) ;
1582+ span,
1583+ self . retrieve_borrow_span ( loan) ,
1584+ & self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ,
1585+ Origin :: Mir ) ;
15701586
15711587 err. emit ( ) ;
15721588 }
@@ -1576,12 +1592,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15761592 ( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
15771593 assigned_span : Span ) {
15781594 let mut err = self . tcx . cannot_reassign_immutable ( span,
1579- & self . describe_lvalue ( lvalue) ,
1595+ & self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ,
15801596 Origin :: Mir ) ;
15811597 err. span_label ( span, "cannot assign twice to immutable variable" ) ;
15821598 if span != assigned_span {
1583- err. span_label ( assigned_span, format ! ( "first assignment to `{}`" ,
1584- self . describe_lvalue( lvalue) ) ) ;
1599+ let value_msg = match self . describe_lvalue ( lvalue) {
1600+ Some ( name) => format ! ( "`{}`" , name) ,
1601+ None => "value" . to_owned ( )
1602+ } ;
1603+ err. span_label ( assigned_span, format ! ( "first assignment to {}" , value_msg) ) ;
15851604 }
15861605 err. emit ( ) ;
15871606 }
@@ -1596,11 +1615,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
15961615}
15971616
15981617impl < ' cx , ' gcx , ' tcx > MirBorrowckCtxt < ' cx , ' gcx , ' tcx > {
1599- // End-user visible description of `lvalue`
1600- fn describe_lvalue ( & self , lvalue : & Lvalue < ' tcx > ) -> String {
1618+ // End-user visible description of `lvalue` if one can be found. If the
1619+ // lvalue is a temporary for instance, None will be returned.
1620+ fn describe_lvalue ( & self , lvalue : & Lvalue < ' tcx > ) -> Option < String > {
16011621 let mut buf = String :: new ( ) ;
1602- self . append_lvalue_to_string ( lvalue, & mut buf, false ) ;
1603- buf
1622+ match self . append_lvalue_to_string ( lvalue, & mut buf, false ) {
1623+ Ok ( ( ) ) => Some ( buf) ,
1624+ Err ( ( ) ) => None
1625+ }
16041626 }
16051627
16061628 /// If this is a field projection, and the field is being projected from a closure type,
@@ -1632,10 +1654,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16321654 fn append_lvalue_to_string ( & self ,
16331655 lvalue : & Lvalue < ' tcx > ,
16341656 buf : & mut String ,
1635- mut autoderef : bool ) {
1657+ mut autoderef : bool ) -> Result < ( ) , ( ) > {
16361658 match * lvalue {
16371659 Lvalue :: Local ( local) => {
1638- self . append_local_to_string ( local, buf, "_" ) ;
1660+ self . append_local_to_string ( local, buf, ) ? ;
16391661 }
16401662 Lvalue :: Static ( ref static_) => {
16411663 buf. push_str ( & format ! ( "{}" , & self . tcx. item_name( static_. def_id) ) ) ;
@@ -1653,15 +1675,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16531675 }
16541676 } else {
16551677 if autoderef {
1656- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1678+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
16571679 } else {
16581680 buf. push_str ( & "*" ) ;
1659- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1681+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
16601682 }
16611683 }
16621684 } ,
16631685 ProjectionElem :: Downcast ( ..) => {
1664- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1686+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
16651687 } ,
16661688 ProjectionElem :: Field ( field, _ty) => {
16671689 autoderef = true ;
@@ -1672,38 +1694,45 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16721694 buf. push_str ( & name) ;
16731695 } else {
16741696 let field_name = self . describe_field ( & proj. base , field) ;
1675- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1697+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
16761698 buf. push_str ( & format ! ( ".{}" , field_name) ) ;
16771699 }
16781700 } ,
16791701 ProjectionElem :: Index ( index) => {
16801702 autoderef = true ;
16811703
1682- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1704+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
16831705 buf. push_str ( "[" ) ;
1684- self . append_local_to_string ( index, buf, ".." ) ;
1706+ if let Err ( _) = self . append_local_to_string ( index, buf) {
1707+ buf. push_str ( ".." ) ;
1708+ }
16851709 buf. push_str ( "]" ) ;
16861710 } ,
16871711 ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
16881712 autoderef = true ;
16891713 // Since it isn't possible to borrow an element on a particular index and
16901714 // then use another while the borrow is held, don't output indices details
16911715 // to avoid confusing the end-user
1692- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1716+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
16931717 buf. push_str ( & "[..]" ) ;
16941718 } ,
16951719 } ;
16961720 }
16971721 }
1722+
1723+ Ok ( ( ) )
16981724 }
16991725
17001726 // Appends end-user visible description of the `local` lvalue to `buf`. If `local` doesn't have
1701- // a name, then `none_string ` is appended instead
1702- fn append_local_to_string ( & self , local_index : Local , buf : & mut String , none_string : & str ) {
1727+ // a name, then `Err ` is returned
1728+ fn append_local_to_string ( & self , local_index : Local , buf : & mut String ) -> Result < ( ) , ( ) > {
17031729 let local = & self . mir . local_decls [ local_index] ;
17041730 match local. name {
1705- Some ( name) => buf. push_str ( & format ! ( "{}" , name) ) ,
1706- None => buf. push_str ( none_string)
1731+ Some ( name) => {
1732+ buf. push_str ( & format ! ( "{}" , name) ) ;
1733+ Ok ( ( ) )
1734+ } ,
1735+ None => Err ( ( ) )
17071736 }
17081737 }
17091738
0 commit comments