提交 22a14dd7 编写于 作者: N Niko Matsakis

Enforce a stricter notion of purity when borrowing. Fixes #3162.

上级 be2e4ef6
......@@ -322,10 +322,32 @@ fn check_assignment(at: assignment_type, ex: @ast::expr) {
// is not visible from the outside
match self.purity(ex.id) {
none => (),
some(pc) => {
if cmt.lp.is_none() {
some(pc @ pc_cmt(_)) => {
// Subtle: Issue #3162. If we are enforcing purity
// because there is a reference to aliasable, mutable data
// that we require to be immutable, we can't allow writes
// even to data owned by the current stack frame. This is
// because that aliasable data might have been located on
// the current stack frame, we don't know.
match cmt.lp {
some(@lp_local(*)) | some(@lp_arg(*)) => {
// it's ok to mutate a local variable, as it is either
// lent our or not. The problem arises when you have
// some subcomponent that might have been lent out
// through an alias on the condition that you ensure
// purity.
}
none | some(@lp_comp(*)) | some(@lp_deref(*)) => {
self.report_purity_error(
pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt)));
}
}
}
some(pc_pure_fn) => {
if cmt.lp.is_none() {
self.report_purity_error(
pc_pure_fn, ex.span,
at.ing_form(self.bccx.cmt_to_str(cmt)));
}
}
}
......
fn each<T>(x: &[T], op: fn(elem: &T) -> bool) {
uint::range(0, x.len(), |i| op(&x[i]));
}
fn main() {
let x = [{mut a: 0}];
for each(x) |y| {
let z = &y.a; //~ ERROR illegal borrow unless pure
x[0].a = 10; //~ NOTE impure due to assigning to mutable field
log(error, z);
}
}
fn each<T>(x: &[T], op: fn(elem: &T) -> bool) {
uint::range(0, x.len(), |i| op(&x[i]));
}
fn main() {
let x = ~[{mut a: 0}];
for each(x) |y| {
let z = &y.a; //~ ERROR illegal borrow unless pure
x[0].a = 10; //~ NOTE impure due to assigning to mutable field
log(error, z);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册