@@ -1343,20 +1343,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1343
1343
|moi| curr_move_out. contains ( moi) ) . collect :: < Vec < _ > > ( ) ;
1344
1344
1345
1345
if mois. is_empty ( ) {
1346
+ let item_msg = match self . describe_lvalue ( lvalue) {
1347
+ Some ( name) => format ! ( "`{}`" , name) ,
1348
+ None => "value" . to_owned ( )
1349
+ } ;
1346
1350
self . tcx . cannot_act_on_uninitialized_variable ( span,
1347
1351
desired_action. as_noun ( ) ,
1348
- & self . describe_lvalue ( lvalue) ,
1352
+ & self . describe_lvalue ( lvalue)
1353
+ . unwrap_or ( "_" . to_owned ( ) ) ,
1349
1354
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) )
1352
1356
. emit ( ) ;
1353
1357
} else {
1354
1358
let msg = "" ; //FIXME: add "partially " or "collaterally "
1355
1359
1356
1360
let mut err = self . tcx . cannot_act_on_moved_value ( span,
1357
1361
desired_action. as_noun ( ) ,
1358
1362
msg,
1359
- & self . describe_lvalue ( lvalue) ,
1363
+ & self . describe_lvalue ( lvalue)
1364
+ . unwrap_or ( "_" . to_owned ( ) ) ,
1360
1365
Origin :: Mir ) ;
1361
1366
1362
1367
err. span_label ( span, format ! ( "value {} here after move" ,
@@ -1381,14 +1386,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1381
1386
_context : Context ,
1382
1387
( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1383
1388
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
+ } ;
1384
1397
self . tcx . cannot_move_when_borrowed ( span,
1385
- & self . describe_lvalue ( lvalue) ,
1398
+ & self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ,
1386
1399
Origin :: Mir )
1387
1400
. 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) )
1392
1403
. emit ( ) ;
1393
1404
}
1394
1405
@@ -1398,8 +1409,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1398
1409
borrow : & BorrowData < ' tcx > ) {
1399
1410
1400
1411
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 ( ) ) ,
1403
1416
Origin :: Mir ) ;
1404
1417
1405
1418
err. emit ( ) ;
@@ -1488,7 +1501,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1488
1501
let old_closure_span = self . find_closure_span ( issued_span, issued_borrow. location ) ;
1489
1502
let issued_span = old_closure_span. map ( |( args, _) | args) . unwrap_or ( issued_span) ;
1490
1503
1491
- let desc_lvalue = self . describe_lvalue ( lvalue) ;
1504
+ let desc_lvalue = self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ;
1492
1505
1493
1506
// FIXME: supply non-"" `opt_via` when appropriate
1494
1507
let mut err = match ( gen_borrow_kind, "immutable" , "mutable" ,
@@ -1566,7 +1579,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1566
1579
( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1567
1580
loan : & BorrowData ) {
1568
1581
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 ) ;
1570
1586
1571
1587
err. emit ( ) ;
1572
1588
}
@@ -1576,12 +1592,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1576
1592
( lvalue, span) : ( & Lvalue < ' tcx > , Span ) ,
1577
1593
assigned_span : Span ) {
1578
1594
let mut err = self . tcx . cannot_reassign_immutable ( span,
1579
- & self . describe_lvalue ( lvalue) ,
1595
+ & self . describe_lvalue ( lvalue) . unwrap_or ( "_" . to_owned ( ) ) ,
1580
1596
Origin :: Mir ) ;
1581
1597
err. span_label ( span, "cannot assign twice to immutable variable" ) ;
1582
1598
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) ) ;
1585
1604
}
1586
1605
err. emit ( ) ;
1587
1606
}
@@ -1596,11 +1615,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1596
1615
}
1597
1616
1598
1617
impl < ' 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 > {
1601
1621
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
+ }
1604
1626
}
1605
1627
1606
1628
/// 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> {
1632
1654
fn append_lvalue_to_string ( & self ,
1633
1655
lvalue : & Lvalue < ' tcx > ,
1634
1656
buf : & mut String ,
1635
- mut autoderef : bool ) {
1657
+ mut autoderef : bool ) -> Result < ( ) , ( ) > {
1636
1658
match * lvalue {
1637
1659
Lvalue :: Local ( local) => {
1638
- self . append_local_to_string ( local, buf, "_" ) ;
1660
+ self . append_local_to_string ( local, buf, ) ? ;
1639
1661
}
1640
1662
Lvalue :: Static ( ref static_) => {
1641
1663
buf. push_str ( & format ! ( "{}" , & self . tcx. item_name( static_. def_id) ) ) ;
@@ -1653,15 +1675,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1653
1675
}
1654
1676
} else {
1655
1677
if autoderef {
1656
- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1678
+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
1657
1679
} else {
1658
1680
buf. push_str ( & "*" ) ;
1659
- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1681
+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
1660
1682
}
1661
1683
}
1662
1684
} ,
1663
1685
ProjectionElem :: Downcast ( ..) => {
1664
- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1686
+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
1665
1687
} ,
1666
1688
ProjectionElem :: Field ( field, _ty) => {
1667
1689
autoderef = true ;
@@ -1672,38 +1694,45 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1672
1694
buf. push_str ( & name) ;
1673
1695
} else {
1674
1696
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) ? ;
1676
1698
buf. push_str ( & format ! ( ".{}" , field_name) ) ;
1677
1699
}
1678
1700
} ,
1679
1701
ProjectionElem :: Index ( index) => {
1680
1702
autoderef = true ;
1681
1703
1682
- self . append_lvalue_to_string ( & proj. base , buf, autoderef) ;
1704
+ self . append_lvalue_to_string ( & proj. base , buf, autoderef) ? ;
1683
1705
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
+ }
1685
1709
buf. push_str ( "]" ) ;
1686
1710
} ,
1687
1711
ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
1688
1712
autoderef = true ;
1689
1713
// Since it isn't possible to borrow an element on a particular index and
1690
1714
// then use another while the borrow is held, don't output indices details
1691
1715
// 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) ? ;
1693
1717
buf. push_str ( & "[..]" ) ;
1694
1718
} ,
1695
1719
} ;
1696
1720
}
1697
1721
}
1722
+
1723
+ Ok ( ( ) )
1698
1724
}
1699
1725
1700
1726
// 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 < ( ) , ( ) > {
1703
1729
let local = & self . mir . local_decls [ local_index] ;
1704
1730
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 ( ( ) )
1707
1736
}
1708
1737
}
1709
1738
0 commit comments