@@ -65,7 +65,7 @@ pub fn check_loans(bccx: @BorrowckCtxt,
65
65
66
66
enum MoveError {
67
67
MoveOk ,
68
- MoveWhileBorrowed ( /*move*/ @ LoanPath , /* loan*/ @LoanPath , /*loan*/ span )
68
+ MoveWhileBorrowed ( /*loan*/ @LoanPath , /*loan*/ span )
69
69
}
70
70
71
71
impl < ' self > CheckLoanCtxt < ' self > {
@@ -348,7 +348,7 @@ impl<'self> CheckLoanCtxt<'self> {
348
348
cmt = b;
349
349
}
350
350
351
- mc:: cat_rvalue |
351
+ mc:: cat_rvalue( * ) |
352
352
mc:: cat_static_item |
353
353
mc:: cat_implicit_self |
354
354
mc:: cat_copied_upvar( * ) |
@@ -547,45 +547,50 @@ impl<'self> CheckLoanCtxt<'self> {
547
547
self . bccx. loan_path_to_str( loan_path) ) ) ;
548
548
}
549
549
550
- pub fn check_move_out_from_expr( & self , ex : @ast:: expr) {
551
- match ex . node {
552
- ast:: expr_paren ( * ) => {
553
- /* In the case of an expr_paren(), the expression inside
554
- * the parens will also be marked as being moved. Ignore
555
- * the parents then so as not to report duplicate errors. */
550
+ fn check_move_out_from_expr( & self , expr : @ast:: expr) {
551
+ match expr . node {
552
+ ast:: expr_fn_block ( * ) => {
553
+ // moves due to capture clauses are checked
554
+ // in `check_loans_in_fn`, so that we can
555
+ // give a better error message
556
556
}
557
557
_ => {
558
- let cmt = self . bccx. cat_expr( ex) ;
559
- match self . analyze_move_out_from_cmt( cmt) {
560
- MoveOk => { }
561
- MoveWhileBorrowed ( move_path, loan_path, loan_span) => {
562
- self . bccx. span_err(
563
- cmt. span,
564
- fmt!( "cannot move out of `%s` \
565
- because it is borrowed",
566
- self . bccx. loan_path_to_str( move_path) ) ) ;
567
- self . bccx. span_note(
568
- loan_span,
569
- fmt!( "borrow of `%s` occurs here",
570
- self . bccx. loan_path_to_str( loan_path) ) ) ;
571
- }
558
+ self . check_move_out_from_id( expr. id, expr. span)
559
+ }
560
+ }
561
+ }
562
+
563
+ fn check_move_out_from_id( & self , id: ast:: node_id, span: span) {
564
+ for self . move_data. each_path_moved_by( id) |_, move_path| {
565
+ match self . analyze_move_out_from( id, move_path) {
566
+ MoveOk => { }
567
+ MoveWhileBorrowed ( loan_path, loan_span) => {
568
+ self . bccx. span_err(
569
+ span,
570
+ fmt!( "cannot move out of `%s` \
571
+ because it is borrowed",
572
+ self . bccx. loan_path_to_str( move_path) ) ) ;
573
+ self . bccx. span_note(
574
+ loan_span,
575
+ fmt!( "borrow of `%s` occurs here",
576
+ self . bccx. loan_path_to_str( loan_path) ) ) ;
572
577
}
573
578
}
574
579
}
575
580
}
576
581
577
- pub fn analyze_move_out_from_cmt( & self , cmt: mc:: cmt) -> MoveError {
578
- debug!( "analyze_move_out_from_cmt( cmt=%s) ", cmt. repr( self . tcx( ) ) ) ;
582
+ pub fn analyze_move_out_from( & self ,
583
+ expr_id: ast:: node_id,
584
+ move_path: @LoanPath ) -> MoveError {
585
+ debug!( "analyze_move_out_from( expr_id=%?, move_path=%s) ",
586
+ expr_id, move_path. repr( self . tcx( ) ) ) ;
579
587
580
588
// FIXME(#4384) inadequare if/when we permit `move a.b`
581
589
582
590
// check for a conflicting loan:
583
- let r = opt_loan_path( cmt) ;
584
- for r. iter( ) . advance |& lp| {
585
- for self . each_in_scope_restriction( cmt. id, lp) |loan, _| {
586
- // Any restriction prevents moves.
587
- return MoveWhileBorrowed ( lp, loan. loan_path, loan. span) ;
588
- }
591
+ for self . each_in_scope_restriction( expr_id, move_path) |loan, _| {
592
+ // Any restriction prevents moves.
593
+ return MoveWhileBorrowed ( loan. loan_path, loan. span) ;
589
594
}
590
595
591
596
MoveOk
@@ -652,13 +657,11 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind,
652
657
closure_id: ast:: node_id,
653
658
cap_var: & moves:: CaptureVar ) {
654
659
let var_id = ast_util:: def_id_of_def( cap_var. def) . node;
655
- let ty = ty:: node_id_to_type( this. tcx( ) , var_id) ;
656
- let cmt = this. bccx. cat_def( closure_id, cap_var. span,
657
- ty, cap_var. def) ;
658
- let move_err = this. analyze_move_out_from_cmt( cmt) ;
660
+ let move_path = @LpVar ( var_id) ;
661
+ let move_err = this. analyze_move_out_from( closure_id, move_path) ;
659
662
match move_err {
660
663
MoveOk => { }
661
- MoveWhileBorrowed ( move_path , loan_path, loan_span) => {
664
+ MoveWhileBorrowed ( loan_path, loan_span) => {
662
665
this. bccx. span_err(
663
666
cap_var. span,
664
667
fmt!( "cannot move `%s` into closure \
@@ -689,10 +692,7 @@ fn check_loans_in_expr<'a>(expr: @ast::expr,
689
692
expr. repr( this. tcx( ) ) ) ;
690
693
691
694
this. check_for_conflicting_loans( expr. id) ;
692
-
693
- if this. bccx. moves_map. contains( & expr. id) {
694
- this. check_move_out_from_expr( expr) ;
695
- }
695
+ this. check_move_out_from_expr( expr) ;
696
696
697
697
match expr. node {
698
698
ast:: expr_self |
@@ -742,18 +742,7 @@ fn check_loans_in_pat<'a>(pat: @ast::pat,
742
742
visit:: vt<@mut CheckLoanCtxt <' a>>) )
743
743
{
744
744
this. check_for_conflicting_loans( pat. id) ;
745
-
746
- // Note: moves out of pattern bindings are not checked by
747
- // the borrow checker, at least not directly. What happens
748
- // is that if there are any moved bindings, the discriminant
749
- // will be considered a move, and this will be checked as
750
- // normal. Then, in `middle::check_match`, we will check
751
- // that no move occurs in a binding that is underneath an
752
- // `@` or `&`. Together these give the same guarantees as
753
- // `check_move_out_from_expr()` without requiring us to
754
- // rewalk the patterns and rebuild the pattern
755
- // categorizations.
756
-
745
+ this. check_move_out_from_id( pat. id, pat. span) ;
757
746
visit:: visit_pat( pat, ( this, vt) ) ;
758
747
}
759
748
0 commit comments