Skip to content

Commit f40b268

Browse files
author
Cameron Zwarich
committed
---
yaml --- r: 152586 b: refs/heads/try2 c: ba203c5 h: refs/heads/master v: v3
1 parent 1ca2554 commit f40b268

File tree

2 files changed

+73
-43
lines changed

2 files changed

+73
-43
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: e018fc36d17685c31d6b31acf17a9a8f2f73f8d9
8+
refs/heads/try2: ba203c5c5de5af9941dc5be4b7c200db69b3c4d4
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/librustc/middle/borrowck/check_loans.rs

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,77 @@ impl<'a> CheckLoanCtxt<'a> {
220220
})
221221
}
222222

223+
fn each_in_scope_loan_affecting_path(&self,
224+
scope_id: ast::NodeId,
225+
loan_path: &LoanPath,
226+
op: |&Loan| -> bool)
227+
-> bool {
228+
//! Iterates through all of the in-scope loans affecting `loan_path`,
229+
//! calling `op`, and ceasing iteration if `false` is returned.
230+
231+
// First, we check for a loan restricting the path P being used. This
232+
// accounts for borrows of P but also borrows of subpaths, like P.a.b.
233+
// Consider the following example:
234+
//
235+
// let x = &mut a.b.c; // Restricts a, a.b, and a.b.c
236+
// let y = a; // Conflicts with restriction
237+
238+
let cont = self.each_in_scope_loan(scope_id, |loan| {
239+
let mut ret = true;
240+
for restr_path in loan.restricted_paths.iter() {
241+
if **restr_path == *loan_path {
242+
if !op(loan) {
243+
ret = false;
244+
break;
245+
}
246+
}
247+
}
248+
ret
249+
});
250+
251+
if !cont {
252+
return false;
253+
}
254+
255+
// Next, we must check for *loans* (not restrictions) on the path P or
256+
// any base path. This rejects examples like the following:
257+
//
258+
// let x = &mut a.b;
259+
// let y = a.b.c;
260+
//
261+
// Limiting this search to *loans* and not *restrictions* means that
262+
// examples like the following continue to work:
263+
//
264+
// let x = &mut a.b;
265+
// let y = a.c;
266+
267+
let mut loan_path = loan_path;
268+
loop {
269+
match *loan_path {
270+
LpVar(_) => {
271+
break;
272+
}
273+
LpExtend(ref lp_base, _, _) => {
274+
loan_path = &**lp_base;
275+
}
276+
}
277+
278+
let cont = self.each_in_scope_loan(scope_id, |loan| {
279+
if *loan.loan_path == *loan_path {
280+
op(loan)
281+
} else {
282+
true
283+
}
284+
});
285+
286+
if !cont {
287+
return false;
288+
}
289+
}
290+
291+
return true;
292+
}
293+
223294
pub fn loans_generated_by(&self, scope_id: ast::NodeId) -> Vec<uint> {
224295
//! Returns a vector of the loans that are generated as
225296
//! we encounter `scope_id`.
@@ -526,14 +597,7 @@ impl<'a> CheckLoanCtxt<'a> {
526597

527598
let mut ret = UseOk;
528599

529-
// First, we check for a restriction on the path P being used. This
530-
// accounts for borrows of P but also borrows of subpaths, like P.a.b.
531-
// Consider the following example:
532-
//
533-
// let x = &mut a.b.c; // Restricts a, a.b, and a.b.c
534-
// let y = a; // Conflicts with restriction
535-
536-
self.each_in_scope_restriction(expr_id, use_path, |loan| {
600+
self.each_in_scope_loan_affecting_path(expr_id, use_path, |loan| {
537601
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
538602
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
539603
false
@@ -542,40 +606,6 @@ impl<'a> CheckLoanCtxt<'a> {
542606
}
543607
});
544608

545-
// Next, we must check for *loans* (not restrictions) on the path P or
546-
// any base path. This rejects examples like the following:
547-
//
548-
// let x = &mut a.b;
549-
// let y = a.b.c;
550-
//
551-
// Limiting this search to *loans* and not *restrictions* means that
552-
// examples like the following continue to work:
553-
//
554-
// let x = &mut a.b;
555-
// let y = a.c;
556-
557-
let mut loan_path = use_path;
558-
loop {
559-
self.each_in_scope_loan(expr_id, |loan| {
560-
if *loan.loan_path == *loan_path &&
561-
!compatible_borrow_kinds(loan.kind, borrow_kind) {
562-
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
563-
false
564-
} else {
565-
true
566-
}
567-
});
568-
569-
match *loan_path {
570-
LpVar(_) => {
571-
break;
572-
}
573-
LpExtend(ref lp_base, _, _) => {
574-
loan_path = &**lp_base;
575-
}
576-
}
577-
}
578-
579609
return ret;
580610
}
581611

0 commit comments

Comments
 (0)