Skip to content

Commit 37c769a

Browse files
author
Cameron Zwarich
committed
---
yaml --- r: 116723 b: refs/heads/snap-stage3 c: 45a1b97 h: refs/heads/master i: 116721: 92577d1 116719: 1df9534 v: v3
1 parent 7cbef85 commit 37c769a

File tree

4 files changed

+52
-31
lines changed

4 files changed

+52
-31
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: bee4e6adac17f87b1cdc26ab69f8c0f5d82575a3
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 8c0e1ce6c9410f4d928923ee93e7b5a4674ae2ed
4+
refs/heads/snap-stage3: 45a1b977643456ceacfc81183e2d5743f7c61ce9
55
refs/heads/try: 009d898a9422ac04c1aa60c0e9aff3abc5fa4672
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/borrowck/check_loans.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -871,33 +871,55 @@ impl<'a> CheckLoanCtxt<'a> {
871871
self.tcx().map.node_to_str(expr_id),
872872
move_path.repr(self.tcx()));
873873

874-
// We must check every element of a move path. See
875-
// `borrowck-move-subcomponent.rs` for a test case.
876-
877874
let mut ret = MoveOk;
875+
876+
// First, we check for a restriction on the path P being used. This
877+
// accounts for borrows of P but also borrows of subpaths, like P.a.b.
878+
// Consider the following example:
879+
//
880+
// let x = &mut a.b.c; // Restricts a, a.b, and a.b.c
881+
// let y = a; // Conflicts with restriction
882+
883+
self.each_in_scope_restriction(expr_id, move_path, |loan, _restr| {
884+
// Any restriction prevents moves.
885+
ret = MoveWhileBorrowed(loan.loan_path.clone(), loan.span);
886+
false
887+
});
888+
889+
// Next, we must check for *loans* (not restrictions) on the path P or
890+
// any base path. This rejects examples like the following:
891+
//
892+
// let x = &mut a.b;
893+
// let y = a.b.c;
894+
//
895+
// Limiting this search to *loans* and not *restrictions* means that
896+
// examples like the following continue to work:
897+
//
898+
// let x = &mut a.b;
899+
// let y = a.c;
900+
878901
let mut loan_path = move_path;
879902
loop {
880-
// check for a conflicting loan:
881-
self.each_in_scope_restriction(expr_id, loan_path, |loan, _| {
903+
self.each_in_scope_loan(expr_id, |loan| {
882904
// Any restriction prevents moves.
883-
ret = MoveWhileBorrowed(loan.loan_path.clone(), loan.span);
884-
false
905+
if *loan.loan_path == *loan_path {
906+
ret = MoveWhileBorrowed(loan.loan_path.clone(), loan.span);
907+
false
908+
} else {
909+
true
910+
}
885911
});
886912

887-
if ret != MoveOk {
888-
return ret
889-
}
890-
891913
match *loan_path {
892914
LpVar(_) => {
893-
ret = MoveOk;
894915
break;
895916
}
896917
LpExtend(ref lp_base, _, _) => {
897918
loan_path = &**lp_base;
898919
}
899920
}
900921
}
901-
ret
922+
923+
return ret;
902924
}
903925
}

branches/snap-stage3/src/test/compile-fail/borrowck-field-sensitivity.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,6 @@ fn fu_move_after_fu_move() {
8484

8585
// The following functions aren't yet accepted, but they should be.
8686

87-
fn move_after_borrow_correct() {
88-
let x = A { a: 1, b: box 2 };
89-
let p = &x.a;
90-
drop(x.b); //~ ERROR cannot move out of `x.b` because it is borrowed
91-
drop(*p);
92-
}
93-
94-
fn fu_move_after_borrow_correct() {
95-
let x = A { a: 1, b: box 2 };
96-
let p = &x.a;
97-
let _y = A { a: 3, .. x }; //~ ERROR cannot move out of `x.b` because it is borrowed
98-
drop(*p);
99-
}
100-
10187
fn copy_after_field_assign_after_uninit() {
10288
let mut x: A;
10389
x.a = 1;
@@ -132,9 +118,6 @@ fn main() {
132118
fu_move_after_move();
133119
fu_move_after_fu_move();
134120

135-
move_after_borrow_correct();
136-
fu_move_after_borrow_correct();
137-
138121
copy_after_field_assign_after_uninit();
139122
borrow_after_field_assign_after_uninit();
140123
move_after_field_assign_after_uninit();

branches/snap-stage3/src/test/run-pass/borrowck-field-sensitivity.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ fn borrow_after_fu_move() {
7373
drop(*p);
7474
}
7575

76+
fn move_after_borrow() {
77+
let x = A { a: 1, b: box 2 };
78+
let p = &x.a;
79+
drop(x.b);
80+
drop(*p);
81+
}
82+
83+
fn fu_move_after_borrow() {
84+
let x = A { a: 1, b: box 2 };
85+
let p = &x.a;
86+
let _y = A { a: 3, .. x };
87+
drop(*p);
88+
}
89+
7690
fn mut_borrow_after_mut_borrow() {
7791
let mut x = A { a: 1, b: box 2 };
7892
let p = &mut x.a;
@@ -225,6 +239,8 @@ fn main() {
225239

226240
borrow_after_move();
227241
borrow_after_fu_move();
242+
move_after_borrow();
243+
fu_move_after_borrow();
228244
mut_borrow_after_mut_borrow();
229245

230246
move_after_move();

0 commit comments

Comments
 (0)