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.
This commit is contained in:
parent
5878b5edb0
commit
6fc788916c
1 changed files with 93 additions and 93 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue