@@ -523,6 +523,99 @@ impl<'a> CheckLoanCtxt<'a> {
523523 }
524524 }
525525
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+
526619 fn check_if_assigned_path_is_moved ( & self ,
527620 id : ast:: NodeId ,
528621 span : Span ,
@@ -564,29 +657,6 @@ impl<'a> CheckLoanCtxt<'a> {
564657 }
565658 }
566659
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-
590660 fn check_assignment ( & self ,
591661 assignment_id : ast:: NodeId ,
592662 assignment_span : Span ,
@@ -885,74 +955,4 @@ impl<'a> CheckLoanCtxt<'a> {
885955 format ! ( "borrow of `{}` occurs here" ,
886956 self . bccx. loan_path_to_str( loan_path) ) . as_slice ( ) ) ;
887957 }
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- }
958958}
0 commit comments