@@ -30,6 +30,8 @@ use syntax::visit::Visitor;
30
30
use syntax:: visit;
31
31
use util:: ppaux:: Repr ;
32
32
33
+ use std:: rc:: Rc ;
34
+
33
35
struct CheckLoanCtxt < ' a > {
34
36
bccx : & ' a BorrowckCtxt < ' a > ,
35
37
dfcx_loans : & ' a LoanDataFlow < ' a > ,
@@ -82,7 +84,7 @@ pub fn check_loans(bccx: &BorrowckCtxt,
82
84
#[ deriving( Eq ) ]
83
85
enum MoveError {
84
86
MoveOk ,
85
- MoveWhileBorrowed ( /*loan*/ @ LoanPath , /*loan*/ Span )
87
+ MoveWhileBorrowed ( /*loan*/ Rc < LoanPath > , /*loan*/ Span )
86
88
}
87
89
88
90
impl < ' a > CheckLoanCtxt < ' a > {
@@ -121,7 +123,7 @@ impl<'a> CheckLoanCtxt<'a> {
121
123
122
124
pub fn each_in_scope_restriction ( & self ,
123
125
scope_id : ast:: NodeId ,
124
- loan_path : @ LoanPath ,
126
+ loan_path : & LoanPath ,
125
127
op : |& Loan , & Restriction | -> bool)
126
128
-> bool {
127
129
//! Iterates through all the in-scope restrictions for the
@@ -133,7 +135,7 @@ impl<'a> CheckLoanCtxt<'a> {
133
135
134
136
let mut ret = true ;
135
137
for restr in loan. restrictions . iter ( ) {
136
- if restr. loan_path == loan_path {
138
+ if * restr. loan_path == * loan_path {
137
139
if !op ( loan, restr) {
138
140
ret = false ;
139
141
break ;
@@ -243,7 +245,7 @@ impl<'a> CheckLoanCtxt<'a> {
243
245
"it" . to_owned ( )
244
246
} else {
245
247
format ! ( "`{}`" ,
246
- self . bccx. loan_path_to_str( old_loan. loan_path) )
248
+ self . bccx. loan_path_to_str( & * old_loan. loan_path) )
247
249
} ;
248
250
249
251
match ( new_loan. kind , old_loan. kind ) {
@@ -252,15 +254,15 @@ impl<'a> CheckLoanCtxt<'a> {
252
254
new_loan. span ,
253
255
format ! ( "cannot borrow `{}` as mutable \
254
256
more than once at a time",
255
- self . bccx. loan_path_to_str( new_loan. loan_path) ) ) ;
257
+ self . bccx. loan_path_to_str( & * new_loan. loan_path) ) ) ;
256
258
}
257
259
258
260
( ty:: UniqueImmBorrow , _) => {
259
261
self . bccx . span_err (
260
262
new_loan. span ,
261
263
format ! ( "closure requires unique access to `{}` \
262
264
but {} is already borrowed",
263
- self . bccx. loan_path_to_str( new_loan. loan_path) ,
265
+ self . bccx. loan_path_to_str( & * new_loan. loan_path) ,
264
266
old_pronoun) ) ;
265
267
}
266
268
@@ -269,7 +271,7 @@ impl<'a> CheckLoanCtxt<'a> {
269
271
new_loan. span ,
270
272
format ! ( "cannot borrow `{}` as {} because \
271
273
previous closure requires unique access",
272
- self . bccx. loan_path_to_str( new_loan. loan_path) ,
274
+ self . bccx. loan_path_to_str( & * new_loan. loan_path) ,
273
275
new_loan. kind. to_user_str( ) ) ) ;
274
276
}
275
277
@@ -278,7 +280,7 @@ impl<'a> CheckLoanCtxt<'a> {
278
280
new_loan. span ,
279
281
format ! ( "cannot borrow `{}` as {} because \
280
282
{} is also borrowed as {}",
281
- self . bccx. loan_path_to_str( new_loan. loan_path) ,
283
+ self . bccx. loan_path_to_str( & * new_loan. loan_path) ,
282
284
new_loan. kind. to_user_str( ) ,
283
285
old_pronoun,
284
286
old_loan. kind. to_user_str( ) ) ) ;
@@ -290,7 +292,7 @@ impl<'a> CheckLoanCtxt<'a> {
290
292
self . bccx . span_note (
291
293
span,
292
294
format ! ( "borrow occurs due to use of `{}` in closure" ,
293
- self . bccx. loan_path_to_str( new_loan. loan_path) ) ) ;
295
+ self . bccx. loan_path_to_str( & * new_loan. loan_path) ) ) ;
294
296
}
295
297
_ => { }
296
298
}
@@ -300,34 +302,34 @@ impl<'a> CheckLoanCtxt<'a> {
300
302
format ! ( "the mutable borrow prevents subsequent \
301
303
moves, borrows, or modification of `{0}` \
302
304
until the borrow ends",
303
- self . bccx. loan_path_to_str( old_loan. loan_path) )
305
+ self . bccx. loan_path_to_str( & * old_loan. loan_path) )
304
306
}
305
307
306
308
ty:: ImmBorrow => {
307
309
format ! ( "the immutable borrow prevents subsequent \
308
310
moves or mutable borrows of `{0}` \
309
311
until the borrow ends",
310
- self . bccx. loan_path_to_str( old_loan. loan_path) )
312
+ self . bccx. loan_path_to_str( & * old_loan. loan_path) )
311
313
}
312
314
313
315
ty:: UniqueImmBorrow => {
314
316
format ! ( "the unique capture prevents subsequent \
315
317
moves or borrows of `{0}` \
316
318
until the borrow ends",
317
- self . bccx. loan_path_to_str( old_loan. loan_path) )
319
+ self . bccx. loan_path_to_str( & * old_loan. loan_path) )
318
320
}
319
321
} ;
320
322
321
323
let borrow_summary = match old_loan. cause {
322
324
ClosureCapture ( _) => {
323
325
format ! ( "previous borrow of `{}` occurs here due to \
324
326
use in closure",
325
- self . bccx. loan_path_to_str( old_loan. loan_path) )
327
+ self . bccx. loan_path_to_str( & * old_loan. loan_path) )
326
328
}
327
329
328
330
AddrOf | AutoRef | RefBinding => {
329
331
format ! ( "previous borrow of `{}` occurs here" ,
330
- self . bccx. loan_path_to_str( old_loan. loan_path) )
332
+ self . bccx. loan_path_to_str( & * old_loan. loan_path) )
331
333
}
332
334
} ;
333
335
@@ -356,7 +358,7 @@ impl<'a> CheckLoanCtxt<'a> {
356
358
id : ast:: NodeId ,
357
359
span : Span ,
358
360
use_kind : MovedValueUseKind ,
359
- lp : @ LoanPath ) {
361
+ lp : & Rc < LoanPath > ) {
360
362
/*!
361
363
* Reports an error if `expr` (which should be a path)
362
364
* is using a moved/uninitialized value
@@ -368,7 +370,7 @@ impl<'a> CheckLoanCtxt<'a> {
368
370
self . bccx . report_use_of_moved_value (
369
371
span,
370
372
use_kind,
371
- lp,
373
+ & * * lp,
372
374
move ,
373
375
moved_lp) ;
374
376
false
@@ -404,10 +406,10 @@ impl<'a> CheckLoanCtxt<'a> {
404
406
if self . is_local_variable ( cmt) {
405
407
assert ! ( cmt. mutbl. is_immutable( ) ) ; // no "const" locals
406
408
let lp = opt_loan_path ( cmt) . unwrap ( ) ;
407
- self . move_data . each_assignment_of ( expr. id , lp, |assign| {
409
+ self . move_data . each_assignment_of ( expr. id , & lp, |assign| {
408
410
self . bccx . report_reassigned_immutable_variable (
409
411
expr. span ,
410
- lp,
412
+ & * lp,
411
413
assign) ;
412
414
false
413
415
} ) ;
@@ -422,7 +424,7 @@ impl<'a> CheckLoanCtxt<'a> {
422
424
format ! ( "cannot assign to {} {} `{}`" ,
423
425
cmt. mutbl. to_user_str( ) ,
424
426
self . bccx. cmt_to_str( cmt) ,
425
- self . bccx. loan_path_to_str( lp) ) ) ;
427
+ self . bccx. loan_path_to_str( & * lp) ) ) ;
426
428
}
427
429
None => {
428
430
self . bccx . span_err (
@@ -571,10 +573,10 @@ impl<'a> CheckLoanCtxt<'a> {
571
573
// owned pointer are borrowed, and hence while `v[*]` is not
572
574
// restricted from being written, `v` is.
573
575
let cont = this. each_in_scope_restriction ( expr. id ,
574
- loan_path,
576
+ & * loan_path,
575
577
|loan, restr| {
576
578
if restr. set . intersects ( RESTR_MUTATE ) {
577
- this. report_illegal_mutation ( expr, loan_path, loan) ;
579
+ this. report_illegal_mutation ( expr, & * loan_path, loan) ;
578
580
false
579
581
} else {
580
582
true
@@ -623,17 +625,17 @@ impl<'a> CheckLoanCtxt<'a> {
623
625
//
624
626
// Here the restriction that `v` not be mutated would be misapplied
625
627
// to block the subpath `v[1]`.
626
- let full_loan_path = loan_path;
628
+ let full_loan_path = loan_path. clone ( ) ;
627
629
let mut loan_path = loan_path;
628
630
loop {
629
- match * loan_path {
631
+ loan_path = match * loan_path {
630
632
// Peel back one layer if, for `loan_path` to be
631
633
// mutable, `lp_base` must be mutable. This occurs
632
634
// with inherited mutability and with `&mut`
633
635
// pointers.
634
- LpExtend ( lp_base, mc:: McInherited , _) |
635
- LpExtend ( lp_base, _, LpDeref ( mc:: BorrowedPtr ( ty:: MutBorrow , _) ) ) => {
636
- loan_path = lp_base;
636
+ LpExtend ( ref lp_base, mc:: McInherited , _) |
637
+ LpExtend ( ref lp_base, _, LpDeref ( mc:: BorrowedPtr ( ty:: MutBorrow , _) ) ) => {
638
+ lp_base. clone ( )
637
639
}
638
640
639
641
// Otherwise stop iterating
@@ -642,12 +644,12 @@ impl<'a> CheckLoanCtxt<'a> {
642
644
LpVar ( _) => {
643
645
return true ;
644
646
}
645
- }
647
+ } ;
646
648
647
649
// Check for a non-const loan of `loan_path`
648
650
let cont = this. each_in_scope_loan ( expr. id , |loan| {
649
651
if loan. loan_path == loan_path {
650
- this. report_illegal_mutation ( expr, full_loan_path, loan) ;
652
+ this. report_illegal_mutation ( expr, & * full_loan_path, loan) ;
651
653
false
652
654
} else {
653
655
true
@@ -700,7 +702,7 @@ impl<'a> CheckLoanCtxt<'a> {
700
702
self . bccx . span_note (
701
703
loan_span,
702
704
format ! ( "borrow of `{}` occurs here" ,
703
- self . bccx. loan_path_to_str( loan_path) ) ) ;
705
+ self . bccx. loan_path_to_str( & * loan_path) ) ) ;
704
706
}
705
707
}
706
708
true
@@ -712,13 +714,12 @@ impl<'a> CheckLoanCtxt<'a> {
712
714
span : Span ) {
713
715
for cap_var in self . bccx . capture_map . get ( & closure_id) . iter ( ) {
714
716
let var_id = ast_util:: def_id_of_def ( cap_var. def ) . node ;
715
- let var_path = @LpVar ( var_id) ;
716
717
self . check_if_path_is_moved ( closure_id, span,
717
- MovedInCapture , var_path ) ;
718
+ MovedInCapture , & Rc :: new ( LpVar ( var_id ) ) ) ;
718
719
match cap_var. mode {
719
720
moves:: CapRef | moves:: CapCopy => { }
720
721
moves:: CapMove => {
721
- check_by_move_capture ( self , closure_id, cap_var, var_path ) ;
722
+ check_by_move_capture ( self , closure_id, cap_var, & LpVar ( var_id ) ) ;
722
723
}
723
724
}
724
725
}
@@ -727,7 +728,7 @@ impl<'a> CheckLoanCtxt<'a> {
727
728
fn check_by_move_capture ( this : & CheckLoanCtxt ,
728
729
closure_id : ast:: NodeId ,
729
730
cap_var : & moves:: CaptureVar ,
730
- move_path : @ LoanPath ) {
731
+ move_path : & LoanPath ) {
731
732
let move_err = this. analyze_move_out_from ( closure_id, move_path) ;
732
733
match move_err {
733
734
MoveOk => { }
@@ -740,38 +741,39 @@ impl<'a> CheckLoanCtxt<'a> {
740
741
this. bccx . span_note (
741
742
loan_span,
742
743
format ! ( "borrow of `{}` occurs here" ,
743
- this. bccx. loan_path_to_str( loan_path) ) ) ;
744
+ this. bccx. loan_path_to_str( & * loan_path) ) ) ;
744
745
}
745
746
}
746
747
}
747
748
}
748
749
749
750
pub fn analyze_move_out_from ( & self ,
750
751
expr_id : ast:: NodeId ,
751
- mut move_path : @ LoanPath )
752
+ move_path : & LoanPath )
752
753
-> MoveError {
753
754
debug ! ( "analyze_move_out_from(expr_id={:?}, move_path={})" ,
754
755
self . tcx( ) . map. node_to_str( expr_id) ,
755
756
move_path. repr( self . tcx( ) ) ) ;
756
757
757
758
// We must check every element of a move path. See
758
759
// `borrowck-move-subcomponent.rs` for a test case.
759
- loop {
760
- // check for a conflicting loan:
761
- let mut ret = MoveOk ;
762
- self . each_in_scope_restriction ( expr_id, move_path, |loan, _| {
763
- // Any restriction prevents moves.
764
- ret = MoveWhileBorrowed ( loan. loan_path , loan. span ) ;
765
- false
766
- } ) ;
767
760
768
- if ret != MoveOk {
769
- return ret
770
- }
761
+ // check for a conflicting loan:
762
+ let mut ret = MoveOk ;
763
+ self . each_in_scope_restriction ( expr_id, move_path, |loan, _| {
764
+ // Any restriction prevents moves.
765
+ ret = MoveWhileBorrowed ( loan. loan_path . clone ( ) , loan. span ) ;
766
+ false
767
+ } ) ;
768
+
769
+ if ret != MoveOk {
770
+ return ret
771
+ }
771
772
772
- match * move_path {
773
- LpVar ( _) => return MoveOk ,
774
- LpExtend ( subpath, _, _) => move_path = subpath,
773
+ match * move_path {
774
+ LpVar ( _) => MoveOk ,
775
+ LpExtend ( ref subpath, _, _) => {
776
+ self . analyze_move_out_from ( expr_id, & * * subpath)
775
777
}
776
778
}
777
779
}
@@ -812,8 +814,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
812
814
if !this. move_data . is_assignee ( expr. id ) {
813
815
let cmt = this. bccx . cat_expr_unadjusted ( expr) ;
814
816
debug ! ( "path cmt={}" , cmt. repr( this. tcx( ) ) ) ;
815
- let r = opt_loan_path ( cmt) ;
816
- for & lp in r. iter ( ) {
817
+ for lp in opt_loan_path ( cmt) . iter ( ) {
817
818
this. check_if_path_is_moved ( expr. id , expr. span , MovedInUse , lp) ;
818
819
}
819
820
}
0 commit comments