@@ -523,6 +523,99 @@ impl<'a> CheckLoanCtxt<'a> {
523
523
}
524
524
}
525
525
526
+ pub fn analyze_restrictions_on_use ( & self ,
527
+ expr_id : ast:: NodeId ,
528
+ use_path : & LoanPath ,
529
+ borrow_kind : ty:: BorrowKind )
530
+ -> UseError {
531
+ debug ! ( "analyze_restrictions_on_use(expr_id={:?}, use_path={})" ,
532
+ self . tcx( ) . map. node_to_str( expr_id) ,
533
+ use_path. repr( self . tcx( ) ) ) ;
534
+
535
+ let mut ret = UseOk ;
536
+
537
+ // First, we check for a restriction on the path P being used. This
538
+ // accounts for borrows of P but also borrows of subpaths, like P.a.b.
539
+ // Consider the following example:
540
+ //
541
+ // let x = &mut a.b.c; // Restricts a, a.b, and a.b.c
542
+ // let y = a; // Conflicts with restriction
543
+
544
+ self . each_in_scope_restriction ( expr_id, use_path, |loan, _restr| {
545
+ if incompatible ( loan. kind , borrow_kind) {
546
+ ret = UseWhileBorrowed ( loan. loan_path . clone ( ) , loan. span ) ;
547
+ false
548
+ } else {
549
+ true
550
+ }
551
+ } ) ;
552
+
553
+ // Next, we must check for *loans* (not restrictions) on the path P or
554
+ // any base path. This rejects examples like the following:
555
+ //
556
+ // let x = &mut a.b;
557
+ // let y = a.b.c;
558
+ //
559
+ // Limiting this search to *loans* and not *restrictions* means that
560
+ // examples like the following continue to work:
561
+ //
562
+ // let x = &mut a.b;
563
+ // let y = a.c;
564
+
565
+ let mut loan_path = use_path;
566
+ loop {
567
+ self . each_in_scope_loan ( expr_id, |loan| {
568
+ if * loan. loan_path == * loan_path &&
569
+ incompatible ( loan. kind , borrow_kind) {
570
+ ret = UseWhileBorrowed ( loan. loan_path . clone ( ) , loan. span ) ;
571
+ false
572
+ } else {
573
+ true
574
+ }
575
+ } ) ;
576
+
577
+ match * loan_path {
578
+ LpVar ( _) => {
579
+ break ;
580
+ }
581
+ LpExtend ( ref lp_base, _, _) => {
582
+ loan_path = & * * lp_base;
583
+ }
584
+ }
585
+ }
586
+
587
+ return ret;
588
+
589
+ fn incompatible ( borrow_kind1 : ty:: BorrowKind ,
590
+ borrow_kind2 : ty:: BorrowKind )
591
+ -> bool {
592
+ borrow_kind1 != ty:: ImmBorrow || borrow_kind2 != ty:: ImmBorrow
593
+ }
594
+ }
595
+
596
+ fn check_if_path_is_moved ( & self ,
597
+ id : ast:: NodeId ,
598
+ span : Span ,
599
+ use_kind : MovedValueUseKind ,
600
+ lp : & Rc < LoanPath > ) {
601
+ /*!
602
+ * Reports an error if `expr` (which should be a path)
603
+ * is using a moved/uninitialized value
604
+ */
605
+
606
+ debug ! ( "check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})" ,
607
+ id, use_kind, lp. repr( self . bccx. tcx) ) ;
608
+ self . move_data . each_move_of ( id, lp, |move, moved_lp| {
609
+ self . bccx . report_use_of_moved_value (
610
+ span,
611
+ use_kind,
612
+ & * * lp,
613
+ move ,
614
+ moved_lp) ;
615
+ false
616
+ } ) ;
617
+ }
618
+
526
619
fn check_if_assigned_path_is_moved ( & self ,
527
620
id : ast:: NodeId ,
528
621
span : Span ,
@@ -564,29 +657,6 @@ impl<'a> CheckLoanCtxt<'a> {
564
657
}
565
658
}
566
659
567
- fn check_if_path_is_moved ( & self ,
568
- id : ast:: NodeId ,
569
- span : Span ,
570
- use_kind : MovedValueUseKind ,
571
- lp : & Rc < LoanPath > ) {
572
- /*!
573
- * Reports an error if `expr` (which should be a path)
574
- * is using a moved/uninitialized value
575
- */
576
-
577
- debug ! ( "check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})" ,
578
- id, use_kind, lp. repr( self . bccx. tcx) ) ;
579
- self . move_data . each_move_of ( id, lp, |move, moved_lp| {
580
- self . bccx . report_use_of_moved_value (
581
- span,
582
- use_kind,
583
- & * * lp,
584
- move ,
585
- moved_lp) ;
586
- false
587
- } ) ;
588
- }
589
-
590
660
fn check_assignment ( & self ,
591
661
assignment_id : ast:: NodeId ,
592
662
assignment_span : Span ,
@@ -885,74 +955,4 @@ impl<'a> CheckLoanCtxt<'a> {
885
955
format ! ( "borrow of `{}` occurs here" ,
886
956
self . bccx. loan_path_to_str( loan_path) ) . as_slice ( ) ) ;
887
957
}
888
-
889
- pub fn analyze_restrictions_on_use ( & self ,
890
- expr_id : ast:: NodeId ,
891
- use_path : & LoanPath ,
892
- borrow_kind : ty:: BorrowKind )
893
- -> UseError {
894
- debug ! ( "analyze_restrictions_on_use(expr_id={:?}, use_path={})" ,
895
- self . tcx( ) . map. node_to_str( expr_id) ,
896
- use_path. repr( self . tcx( ) ) ) ;
897
-
898
- let mut ret = UseOk ;
899
-
900
- // First, we check for a restriction on the path P being used. This
901
- // accounts for borrows of P but also borrows of subpaths, like P.a.b.
902
- // Consider the following example:
903
- //
904
- // let x = &mut a.b.c; // Restricts a, a.b, and a.b.c
905
- // let y = a; // Conflicts with restriction
906
-
907
- self . each_in_scope_restriction ( expr_id, use_path, |loan, _restr| {
908
- if incompatible ( loan. kind , borrow_kind) {
909
- ret = UseWhileBorrowed ( loan. loan_path . clone ( ) , loan. span ) ;
910
- false
911
- } else {
912
- true
913
- }
914
- } ) ;
915
-
916
- // Next, we must check for *loans* (not restrictions) on the path P or
917
- // any base path. This rejects examples like the following:
918
- //
919
- // let x = &mut a.b;
920
- // let y = a.b.c;
921
- //
922
- // Limiting this search to *loans* and not *restrictions* means that
923
- // examples like the following continue to work:
924
- //
925
- // let x = &mut a.b;
926
- // let y = a.c;
927
-
928
- let mut loan_path = use_path;
929
- loop {
930
- self . each_in_scope_loan ( expr_id, |loan| {
931
- if * loan. loan_path == * loan_path &&
932
- incompatible ( loan. kind , borrow_kind) {
933
- ret = UseWhileBorrowed ( loan. loan_path . clone ( ) , loan. span ) ;
934
- false
935
- } else {
936
- true
937
- }
938
- } ) ;
939
-
940
- match * loan_path {
941
- LpVar ( _) => {
942
- break ;
943
- }
944
- LpExtend ( ref lp_base, _, _) => {
945
- loan_path = & * * lp_base;
946
- }
947
- }
948
- }
949
-
950
- return ret;
951
-
952
- fn incompatible ( borrow_kind1 : ty:: BorrowKind ,
953
- borrow_kind2 : ty:: BorrowKind )
954
- -> bool {
955
- borrow_kind1 != ty:: ImmBorrow || borrow_kind2 != ty:: ImmBorrow
956
- }
957
- }
958
958
}
0 commit comments