@@ -1443,10 +1443,10 @@ fn check_expr(expr: @expr, this: @Liveness, vt: vt<@Liveness>) {
1443
1443
1444
1444
match this. ir. variable_moves_map. find( & expr. id) {
1445
1445
None => { }
1446
- Some ( & entire_expr ) => {
1446
+ Some ( & reason ) => {
1447
1447
debug!( "( checking expr) is a move : `%s`",
1448
1448
expr_to_str( expr, this. tcx. sess. intr( ) ) ) ;
1449
- this. check_move_from_var( ln, * var, entire_expr ) ;
1449
+ this. check_move_from_var( ln, * var, reason ) ;
1450
1450
}
1451
1451
}
1452
1452
}
@@ -1459,7 +1459,7 @@ fn check_expr(expr: @expr, this: @Liveness, vt: vt<@Liveness>) {
1459
1459
for caps. each |cap| {
1460
1460
let var = this. variable( cap. var_nid, expr. span) ;
1461
1461
if cap. is_move {
1462
- this. check_move_from_var( cap. ln, var, expr) ;
1462
+ this. check_move_from_var( cap. ln, var, moves :: MovedByExpr ( expr) ) ;
1463
1463
}
1464
1464
}
1465
1465
@@ -1549,24 +1549,20 @@ pub impl Liveness {
1549
1549
fn check_move_from_var( & self ,
1550
1550
ln: LiveNode ,
1551
1551
var: Variable ,
1552
- move_expr : @expr ) {
1552
+ move_reason : moves :: Reason ) {
1553
1553
/*!
1554
1554
* Checks whether `var` is live on entry to any of the
1555
1555
* successors of `ln`. If it is, report an error.
1556
- * `move_expr ` is the expression which caused the variable
1556
+ * `move_reason ` is the reason which caused the variable
1557
1557
* to be moved.
1558
- *
1559
- * Note that `move_expr` is not necessarily a reference to the
1560
- * variable. It might be an expression like `x.f` which could
1561
- * cause a move of the variable `x`, or a closure creation.
1562
1558
*/
1563
1559
1564
1560
debug!( "check_move_from_var( %s, %s) ",
1565
1561
ln. to_str( ) , var. to_str( ) ) ;
1566
1562
1567
1563
match self . live_on_exit( ln, var) {
1568
1564
None => { }
1569
- Some ( lnk) => self . report_illegal_move( lnk, var, move_expr )
1565
+ Some ( lnk) => self . report_illegal_move( lnk, var, move_reason )
1570
1566
}
1571
1567
}
1572
1568
@@ -1640,82 +1636,79 @@ pub impl Liveness {
1640
1636
1641
1637
fn report_illegal_move( & self , lnk: LiveNodeKind ,
1642
1638
var: Variable ,
1643
- move_expr: @expr) {
1644
- // the only time that it is possible to have a moved variable
1645
- // used by ExitNode would be arguments or fields in a ctor.
1646
- // we give a slightly different error message in those cases.
1647
- if lnk == ExitNode {
1648
- // FIXME #4715: this seems like it should be reported in the
1649
- // borrow checker
1650
- let vk = self . ir. var_kinds[ * var] ;
1651
- match vk {
1652
- Arg ( _, name) => {
1653
- self . tcx. sess. span_err(
1654
- move_expr. span,
1655
- fmt!( "illegal move from argument `%s`, which is not \
1656
- copy or move mode", * self . tcx. sess. str_of( name) ) ) ;
1657
- return ;
1658
- }
1659
- Local ( * ) | ImplicitRet => {
1660
- self . tcx. sess. span_bug(
1661
- move_expr. span,
1662
- fmt!( "illegal reader ( %?) for `%?`",
1663
- lnk, vk) ) ;
1664
- }
1639
+ move_reason: moves:: Reason ) {
1640
+ match move_reason {
1641
+ moves:: MovedByExpr ( move_expr) => {
1642
+ match move_expr. node {
1643
+ expr_fn_block( * ) => {
1644
+ self . report_illegal_read(
1645
+ move_expr. span, lnk, var, MovedValue ) ;
1646
+ let name = self . ir. variable_name( var) ;
1647
+ self . tcx. sess. span_note(
1648
+ move_expr. span,
1649
+ fmt!( "`%s` moved into closure environment here \
1650
+ because its type is moved by default ",
1651
+ * name) ) ;
1652
+ }
1653
+ expr_path( * ) => {
1654
+ self . report_illegal_read(
1655
+ move_expr. span, lnk, var, MovedValue ) ;
1656
+ self . report_move_location(
1657
+ move_expr. id, move_expr. span, var,
1658
+ "", "it", "copy") ;
1659
+ }
1660
+ expr_field( * ) => {
1661
+ self . report_illegal_read(
1662
+ move_expr. span, lnk, var, PartiallyMovedValue ) ;
1663
+ self . report_move_location(
1664
+ move_expr. id, move_expr. span, var,
1665
+ "field of ", "the field", "copy") ;
1666
+ }
1667
+ expr_index( * ) => {
1668
+ self . report_illegal_read(
1669
+ move_expr. span, lnk, var, PartiallyMovedValue ) ;
1670
+ self . report_move_location(
1671
+ move_expr. id, move_expr. span, var,
1672
+ "element of ", "the element", "copy") ;
1673
+ }
1674
+ _ => {
1675
+ self . report_illegal_read(
1676
+ move_expr. span, lnk, var, PartiallyMovedValue ) ;
1677
+ self . report_move_location(
1678
+ move_expr. id, move_expr. span, var,
1679
+ "subcomponent of ", "the subcomponent", "copy") ;
1680
+ }
1681
+ }
1665
1682
}
1666
- }
1667
1683
1668
- match move_expr. node {
1669
- expr_fn_block( * ) => {
1670
- self . report_illegal_read(
1671
- move_expr. span, lnk, var, MovedValue ) ;
1672
- let name = self . ir. variable_name( var) ;
1673
- self . tcx. sess. span_note(
1674
- move_expr. span,
1675
- fmt!( "`%s` moved into closure environment here \
1676
- because its type is moved by default ",
1677
- * name) ) ;
1678
- }
1679
- expr_path( * ) => {
1680
- self . report_illegal_read(
1681
- move_expr. span, lnk, var, MovedValue ) ;
1682
- self . report_move_location(
1683
- move_expr, var, "", "it") ;
1684
- }
1685
- expr_field( * ) => {
1686
- self . report_illegal_read(
1687
- move_expr. span, lnk, var, PartiallyMovedValue ) ;
1688
- self . report_move_location(
1689
- move_expr, var, "field of ", "the field") ;
1690
- }
1691
- expr_index( * ) => {
1692
- self . report_illegal_read(
1693
- move_expr. span, lnk, var, PartiallyMovedValue ) ;
1694
- self . report_move_location(
1695
- move_expr, var, "element of ", "the element") ;
1696
- }
1697
- _ => {
1684
+ moves:: MovedByPat ( move_binding) => {
1698
1685
self . report_illegal_read(
1699
- move_expr . span, lnk, var, PartiallyMovedValue ) ;
1686
+ move_binding . span, lnk, var, PartiallyMovedValue ) ;
1700
1687
self . report_move_location(
1701
- move_expr, var, "subcomponent of ", "the subcomponent") ;
1688
+ move_binding. id, move_binding. span, var,
1689
+ "", "the binding", "ref ") ;
1702
1690
}
1703
1691
} ;
1704
1692
}
1705
1693
1706
1694
fn report_move_location( & self ,
1707
- move_expr: @expr,
1695
+ move_loc_id: node_id,
1696
+ move_loc_span: span,
1708
1697
var: Variable ,
1709
1698
expr_descr: & str ,
1710
- pronoun: & str ) {
1711
- let move_expr_ty = ty:: expr_ty( self . tcx, move_expr) ;
1699
+ pronoun: & str ,
1700
+ override: & str ) {
1701
+ let move_expr_ty = ty:: node_id_to_type( self . tcx, move_loc_id) ;
1712
1702
let name = self . ir. variable_name( var) ;
1713
1703
self . tcx. sess. span_note(
1714
- move_expr . span ,
1704
+ move_loc_span ,
1715
1705
fmt!( "%s`%s` moved here because %s has type %s, \
1716
- which is moved by default ( use `copy` to override) ",
1717
- expr_descr, * name, pronoun,
1718
- ty_to_str( self . tcx, move_expr_ty) ) ) ;
1706
+ which is moved by default ( use `%s` to override) ",
1707
+ expr_descr,
1708
+ * name,
1709
+ pronoun,
1710
+ ty_to_str( self . tcx, move_expr_ty) ,
1711
+ override) ) ;
1719
1712
}
1720
1713
1721
1714
fn report_illegal_read( & self ,
0 commit comments