Skip to content

Commit 8bfde2d

Browse files
committed
---
yaml --- r: 27692 b: refs/heads/try c: 22a14dd h: refs/heads/master v: v3
1 parent 0fbd48e commit 8bfde2d

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
5-
refs/heads/try: be2e4ef624acdeb260bc1ba86e9a357b30775baa
5+
refs/heads/try: 22a14dd700338ed26f78143dfad4325566a3f4ed
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df

branches/try/src/rustc/middle/borrowck/check_loans.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,32 @@ impl check_loan_ctxt {
322322
// is not visible from the outside
323323
match self.purity(ex.id) {
324324
none => (),
325-
some(pc) => {
326-
if cmt.lp.is_none() {
325+
some(pc @ pc_cmt(_)) => {
326+
// Subtle: Issue #3162. If we are enforcing purity
327+
// because there is a reference to aliasable, mutable data
328+
// that we require to be immutable, we can't allow writes
329+
// even to data owned by the current stack frame. This is
330+
// because that aliasable data might have been located on
331+
// the current stack frame, we don't know.
332+
match cmt.lp {
333+
some(@lp_local(*)) | some(@lp_arg(*)) => {
334+
// it's ok to mutate a local variable, as it is either
335+
// lent our or not. The problem arises when you have
336+
// some subcomponent that might have been lent out
337+
// through an alias on the condition that you ensure
338+
// purity.
339+
}
340+
none | some(@lp_comp(*)) | some(@lp_deref(*)) => {
327341
self.report_purity_error(
328342
pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt)));
343+
}
344+
}
345+
}
346+
some(pc_pure_fn) => {
347+
if cmt.lp.is_none() {
348+
self.report_purity_error(
349+
pc_pure_fn, ex.span,
350+
at.ing_form(self.bccx.cmt_to_str(cmt)));
329351
}
330352
}
331353
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fn each<T>(x: &[T], op: fn(elem: &T) -> bool) {
2+
uint::range(0, x.len(), |i| op(&x[i]));
3+
}
4+
5+
fn main() {
6+
let x = [{mut a: 0}];
7+
for each(x) |y| {
8+
let z = &y.a; //~ ERROR illegal borrow unless pure
9+
x[0].a = 10; //~ NOTE impure due to assigning to mutable field
10+
log(error, z);
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fn each<T>(x: &[T], op: fn(elem: &T) -> bool) {
2+
uint::range(0, x.len(), |i| op(&x[i]));
3+
}
4+
5+
fn main() {
6+
let x = ~[{mut a: 0}];
7+
for each(x) |y| {
8+
let z = &y.a; //~ ERROR illegal borrow unless pure
9+
x[0].a = 10; //~ NOTE impure due to assigning to mutable field
10+
log(error, z);
11+
}
12+
}

0 commit comments

Comments
 (0)