@@ -385,37 +385,47 @@ impl<'a> CheckLoanCtxt<'a> {
385
385
} ) ;
386
386
}
387
387
388
- pub fn check_assignment ( & self , expr : & ast:: Expr ) {
388
+ pub fn check_assignment_expr ( & self , expr : & ast:: Expr ) {
389
+ let assignment_id = expr. id ;
390
+ let assignment_span = expr. span ;
391
+
389
392
// We don't use cat_expr() here because we don't want to treat
390
393
// auto-ref'd parameters in overloaded operators as rvalues.
391
- let cmt = match self . bccx . tcx . adjustments . borrow ( ) . find ( & expr . id ) {
394
+ let assignee_cmt = match self . bccx . tcx . adjustments . borrow ( ) . find ( & assignment_id ) {
392
395
None => self . bccx . cat_expr_unadjusted ( expr) ,
393
396
Some ( adj) => self . bccx . cat_expr_autoderefd ( expr, adj)
394
397
} ;
395
398
396
- debug ! ( "check_assignment(cmt={})" , cmt. repr( self . tcx( ) ) ) ;
399
+ self . check_assignment ( assignment_id, assignment_span, assignee_cmt) ;
400
+ }
401
+
402
+ fn check_assignment ( & self ,
403
+ assignment_id : ast:: NodeId ,
404
+ assignment_span : Span ,
405
+ assignee_cmt : mc:: cmt ) {
406
+ debug ! ( "check_assignment(assignee_cmt={})" , assignee_cmt. repr( self . tcx( ) ) ) ;
397
407
398
408
// Mutable values can be assigned, as long as they obey loans
399
409
// and aliasing restrictions:
400
- if cmt . mutbl . is_mutable ( ) {
401
- if check_for_aliasable_mutable_writes ( self , expr , cmt . clone ( ) ) {
410
+ if assignee_cmt . mutbl . is_mutable ( ) {
411
+ if check_for_aliasable_mutable_writes ( self , assignment_span , assignee_cmt . clone ( ) ) {
402
412
if check_for_assignment_to_restricted_or_frozen_location (
403
- self , expr , cmt . clone ( ) ) {
413
+ self , assignment_id , assignment_span , assignee_cmt . clone ( ) ) {
404
414
// Safe, but record for lint pass later:
405
- mark_variable_as_used_mut ( self , cmt ) ;
415
+ mark_variable_as_used_mut ( self , assignee_cmt ) ;
406
416
}
407
417
}
408
418
return ;
409
419
}
410
420
411
421
// For immutable local variables, assignments are legal
412
422
// if they cannot already have been assigned
413
- if self . is_local_variable ( cmt . clone ( ) ) {
414
- assert ! ( cmt . mutbl. is_immutable( ) ) ; // no "const" locals
415
- let lp = opt_loan_path ( & cmt ) . unwrap ( ) ;
416
- self . move_data . each_assignment_of ( expr . id , & lp, |assign| {
423
+ if self . is_local_variable ( assignee_cmt . clone ( ) ) {
424
+ assert ! ( assignee_cmt . mutbl. is_immutable( ) ) ; // no "const" locals
425
+ let lp = opt_loan_path ( & assignee_cmt ) . unwrap ( ) ;
426
+ self . move_data . each_assignment_of ( assignment_id , & lp, |assign| {
417
427
self . bccx . report_reassigned_immutable_variable (
418
- expr . span ,
428
+ assignment_span ,
419
429
& * lp,
420
430
assign) ;
421
431
false
@@ -424,21 +434,21 @@ impl<'a> CheckLoanCtxt<'a> {
424
434
}
425
435
426
436
// Otherwise, just a plain error.
427
- match opt_loan_path ( & cmt ) {
437
+ match opt_loan_path ( & assignee_cmt ) {
428
438
Some ( lp) => {
429
439
self . bccx . span_err (
430
- expr . span ,
440
+ assignment_span ,
431
441
format ! ( "cannot assign to {} {} `{}`" ,
432
- cmt . mutbl. to_user_str( ) ,
433
- self . bccx. cmt_to_str( & * cmt ) ,
442
+ assignee_cmt . mutbl. to_user_str( ) ,
443
+ self . bccx. cmt_to_str( & * assignee_cmt ) ,
434
444
self . bccx. loan_path_to_str( & * lp) ) . as_slice ( ) ) ;
435
445
}
436
446
None => {
437
447
self . bccx . span_err (
438
- expr . span ,
448
+ assignment_span ,
439
449
format ! ( "cannot assign to {} {}" ,
440
- cmt . mutbl. to_user_str( ) ,
441
- self . bccx. cmt_to_str( & * cmt ) ) . as_slice ( ) ) ;
450
+ assignee_cmt . mutbl. to_user_str( ) ,
451
+ self . bccx. cmt_to_str( & * assignee_cmt ) ) . as_slice ( ) ) ;
442
452
}
443
453
}
444
454
return ;
@@ -495,7 +505,7 @@ impl<'a> CheckLoanCtxt<'a> {
495
505
}
496
506
497
507
fn check_for_aliasable_mutable_writes ( this : & CheckLoanCtxt ,
498
- expr : & ast :: Expr ,
508
+ span : Span ,
499
509
cmt : mc:: cmt ) -> bool {
500
510
//! Safety checks related to writes to aliasable, mutable locations
501
511
@@ -506,7 +516,7 @@ impl<'a> CheckLoanCtxt<'a> {
506
516
mc:: cat_deref( ref b, _, mc:: BorrowedPtr ( ty:: MutBorrow , _) ) => {
507
517
// Statically prohibit writes to `&mut` when aliasable
508
518
509
- check_for_aliasability_violation ( this, expr , b. clone ( ) ) ;
519
+ check_for_aliasability_violation ( this, span , b. clone ( ) ) ;
510
520
}
511
521
512
522
_ => { }
@@ -516,7 +526,7 @@ impl<'a> CheckLoanCtxt<'a> {
516
526
}
517
527
518
528
fn check_for_aliasability_violation ( this : & CheckLoanCtxt ,
519
- expr : & ast :: Expr ,
529
+ span : Span ,
520
530
cmt : mc:: cmt )
521
531
-> bool {
522
532
match cmt. freely_aliasable ( this. tcx ( ) ) {
@@ -528,7 +538,7 @@ impl<'a> CheckLoanCtxt<'a> {
528
538
}
529
539
Some ( cause) => {
530
540
this. bccx . report_aliasability_violation (
531
- expr . span ,
541
+ span,
532
542
MutabilityViolation ,
533
543
cause) ;
534
544
return false ;
@@ -538,13 +548,14 @@ impl<'a> CheckLoanCtxt<'a> {
538
548
539
549
fn check_for_assignment_to_restricted_or_frozen_location (
540
550
this : & CheckLoanCtxt ,
541
- expr : & ast:: Expr ,
542
- cmt : mc:: cmt ) -> bool
551
+ assignment_id : ast:: NodeId ,
552
+ assignment_span : Span ,
553
+ assignee_cmt : mc:: cmt ) -> bool
543
554
{
544
555
//! Check for assignments that violate the terms of an
545
556
//! outstanding loan.
546
557
547
- let loan_path = match opt_loan_path ( & cmt ) {
558
+ let loan_path = match opt_loan_path ( & assignee_cmt ) {
548
559
Some ( lp) => lp,
549
560
None => { return true ; /* no loan path, can't be any loans */ }
550
561
} ;
@@ -579,11 +590,11 @@ impl<'a> CheckLoanCtxt<'a> {
579
590
// `RESTR_MUTATE` restriction whenever the contents of an
580
591
// owned pointer are borrowed, and hence while `v[*]` is not
581
592
// restricted from being written, `v` is.
582
- let cont = this. each_in_scope_restriction ( expr . id ,
593
+ let cont = this. each_in_scope_restriction ( assignment_id ,
583
594
& * loan_path,
584
595
|loan, restr| {
585
596
if restr. set . intersects ( RESTR_MUTATE ) {
586
- this. report_illegal_mutation ( expr , & * loan_path, loan) ;
597
+ this. report_illegal_mutation ( assignment_span , & * loan_path, loan) ;
587
598
false
588
599
} else {
589
600
true
@@ -656,9 +667,9 @@ impl<'a> CheckLoanCtxt<'a> {
656
667
} ;
657
668
658
669
// Check for a non-const loan of `loan_path`
659
- let cont = this. each_in_scope_loan ( expr . id , |loan| {
670
+ let cont = this. each_in_scope_loan ( assignment_id , |loan| {
660
671
if loan. loan_path == loan_path {
661
- this. report_illegal_mutation ( expr , & * full_loan_path, loan) ;
672
+ this. report_illegal_mutation ( assignment_span , & * full_loan_path, loan) ;
662
673
false
663
674
} else {
664
675
true
@@ -671,11 +682,11 @@ impl<'a> CheckLoanCtxt<'a> {
671
682
}
672
683
673
684
pub fn report_illegal_mutation ( & self ,
674
- expr : & ast :: Expr ,
685
+ span : Span ,
675
686
loan_path : & LoanPath ,
676
687
loan : & Loan ) {
677
688
self . bccx . span_err (
678
- expr . span ,
689
+ span,
679
690
format ! ( "cannot assign to `{}` because it is borrowed" ,
680
691
self . bccx. loan_path_to_str( loan_path) ) . as_slice ( ) ) ;
681
692
self . bccx . span_note (
@@ -733,7 +744,7 @@ impl<'a> CheckLoanCtxt<'a> {
733
744
match freevar_mode {
734
745
freevars:: CaptureByRef => { }
735
746
freevars:: CaptureByValue => {
736
- check_by_move_capture ( self , closure_id, freevar, & * var_path) ;
747
+ check_by_move_capture ( self , closure_id, freevar. span , & * var_path) ;
737
748
}
738
749
}
739
750
}
@@ -742,14 +753,14 @@ impl<'a> CheckLoanCtxt<'a> {
742
753
743
754
fn check_by_move_capture ( this : & CheckLoanCtxt ,
744
755
closure_id : ast:: NodeId ,
745
- freevar : & freevars :: freevar_entry ,
756
+ freevar_span : Span ,
746
757
move_path : & LoanPath ) {
747
758
let move_err = this. analyze_move_out_from ( closure_id, move_path) ;
748
759
match move_err {
749
760
MoveOk => { }
750
761
MoveWhileBorrowed ( loan_path, loan_span) => {
751
762
this. bccx . span_err (
752
- freevar . span ,
763
+ freevar_span ,
753
764
format ! ( "cannot move `{}` into closure \
754
765
because it is borrowed",
755
766
this. bccx. loan_path_to_str(
@@ -841,7 +852,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
841
852
}
842
853
ast:: ExprAssign ( dest, _) |
843
854
ast:: ExprAssignOp ( _, dest, _) => {
844
- this. check_assignment ( dest) ;
855
+ this. check_assignment_expr ( dest) ;
845
856
}
846
857
ast:: ExprCall ( f, ref args) => {
847
858
this. check_call ( expr, Some ( f) , f. span , args. as_slice ( ) ) ;
@@ -859,7 +870,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
859
870
}
860
871
ast:: ExprInlineAsm ( ref ia) => {
861
872
for & ( _, out) in ia. outputs . iter ( ) {
862
- this. check_assignment ( out) ;
873
+ this. check_assignment_expr ( out) ;
863
874
}
864
875
}
865
876
_ => { }
0 commit comments