diff options
| author | Cameron Zwarich <zwarich@mozilla.com> | 2014-06-13 20:48:10 -0700 |
|---|---|---|
| committer | Cameron Zwarich <zwarich@mozilla.com> | 2014-06-13 20:48:10 -0700 |
| commit | 6fc788916c297d6e03464b80f12ba0e62fccccac (patch) | |
| tree | f7dbcc8a483136c2ca6c95cbbd7dbe15df4d9ca8 | |
| parent | 5878b5edb0036312ffee12fc730e69d57df31a66 (diff) | |
| download | rust-6fc788916c297d6e03464b80f12ba0e62fccccac.tar.gz rust-6fc788916c297d6e03464b80f12ba0e62fccccac.zip | |
Reorganize code in check_loans
Move analyze_restrictions_on_use and check_if_path_is_moved so that all of the code related to assignments is in a contiguous block at the end of the file.
| -rw-r--r-- | src/librustc/middle/borrowck/check_loans.rs | 186 |
1 files changed, 93 insertions, 93 deletions
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 2392db63019..11144118047 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -523,6 +523,99 @@ impl<'a> CheckLoanCtxt<'a> { } } + pub fn analyze_restrictions_on_use(&self, + expr_id: ast::NodeId, + use_path: &LoanPath, + borrow_kind: ty::BorrowKind) + -> UseError { + debug!("analyze_restrictions_on_use(expr_id={:?}, use_path={})", + self.tcx().map.node_to_str(expr_id), + use_path.repr(self.tcx())); + + let mut ret = UseOk; + + // First, we check for a restriction on the path P being used. This + // accounts for borrows of P but also borrows of subpaths, like P.a.b. + // Consider the following example: + // + // let x = &mut a.b.c; // Restricts a, a.b, and a.b.c + // let y = a; // Conflicts with restriction + + self.each_in_scope_restriction(expr_id, use_path, |loan, _restr| { + if incompatible(loan.kind, borrow_kind) { + ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); + false + } else { + true + } + }); + + // Next, we must check for *loans* (not restrictions) on the path P or + // any base path. This rejects examples like the following: + // + // let x = &mut a.b; + // let y = a.b.c; + // + // Limiting this search to *loans* and not *restrictions* means that + // examples like the following continue to work: + // + // let x = &mut a.b; + // let y = a.c; + + let mut loan_path = use_path; + loop { + self.each_in_scope_loan(expr_id, |loan| { + if *loan.loan_path == *loan_path && + incompatible(loan.kind, borrow_kind) { + ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); + false + } else { + true + } + }); + + match *loan_path { + LpVar(_) => { + break; + } + LpExtend(ref lp_base, _, _) => { + loan_path = &**lp_base; + } + } + } + + return ret; + + fn incompatible(borrow_kind1: ty::BorrowKind, + borrow_kind2: ty::BorrowKind) + -> bool { + borrow_kind1 != ty::ImmBorrow || borrow_kind2 != ty::ImmBorrow + } + } + + fn check_if_path_is_moved(&self, + id: ast::NodeId, + span: Span, + use_kind: MovedValueUseKind, + lp: &Rc<LoanPath>) { + /*! + * Reports an error if `expr` (which should be a path) + * is using a moved/uninitialized value + */ + + debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})", + id, use_kind, lp.repr(self.bccx.tcx)); + self.move_data.each_move_of(id, lp, |move, moved_lp| { + self.bccx.report_use_of_moved_value( + span, + use_kind, + &**lp, + move, + moved_lp); + false + }); + } + fn check_if_assigned_path_is_moved(&self, id: ast::NodeId, span: Span, @@ -564,29 +657,6 @@ impl<'a> CheckLoanCtxt<'a> { } } - fn check_if_path_is_moved(&self, - id: ast::NodeId, - span: Span, - use_kind: MovedValueUseKind, - lp: &Rc<LoanPath>) { - /*! - * Reports an error if `expr` (which should be a path) - * is using a moved/uninitialized value - */ - - debug!("check_if_path_is_moved(id={:?}, use_kind={:?}, lp={})", - id, use_kind, lp.repr(self.bccx.tcx)); - self.move_data.each_move_of(id, lp, |move, moved_lp| { - self.bccx.report_use_of_moved_value( - span, - use_kind, - &**lp, - move, - moved_lp); - false - }); - } - fn check_assignment(&self, assignment_id: ast::NodeId, assignment_span: Span, @@ -885,74 +955,4 @@ impl<'a> CheckLoanCtxt<'a> { format!("borrow of `{}` occurs here", self.bccx.loan_path_to_str(loan_path)).as_slice()); } - - pub fn analyze_restrictions_on_use(&self, - expr_id: ast::NodeId, - use_path: &LoanPath, - borrow_kind: ty::BorrowKind) - -> UseError { - debug!("analyze_restrictions_on_use(expr_id={:?}, use_path={})", - self.tcx().map.node_to_str(expr_id), - use_path.repr(self.tcx())); - - let mut ret = UseOk; - - // First, we check for a restriction on the path P being used. This - // accounts for borrows of P but also borrows of subpaths, like P.a.b. - // Consider the following example: - // - // let x = &mut a.b.c; // Restricts a, a.b, and a.b.c - // let y = a; // Conflicts with restriction - - self.each_in_scope_restriction(expr_id, use_path, |loan, _restr| { - if incompatible(loan.kind, borrow_kind) { - ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); - false - } else { - true - } - }); - - // Next, we must check for *loans* (not restrictions) on the path P or - // any base path. This rejects examples like the following: - // - // let x = &mut a.b; - // let y = a.b.c; - // - // Limiting this search to *loans* and not *restrictions* means that - // examples like the following continue to work: - // - // let x = &mut a.b; - // let y = a.c; - - let mut loan_path = use_path; - loop { - self.each_in_scope_loan(expr_id, |loan| { - if *loan.loan_path == *loan_path && - incompatible(loan.kind, borrow_kind) { - ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span); - false - } else { - true - } - }); - - match *loan_path { - LpVar(_) => { - break; - } - LpExtend(ref lp_base, _, _) => { - loan_path = &**lp_base; - } - } - } - - return ret; - - fn incompatible(borrow_kind1: ty::BorrowKind, - borrow_kind2: ty::BorrowKind) - -> bool { - borrow_kind1 != ty::ImmBorrow || borrow_kind2 != ty::ImmBorrow - } - } } |
