diff --git a/src/librustc/middle/borrowck/doc.rs b/src/librustc/middle/borrowck/doc.rs index f95547ea933d..38e93cd39fad 100644 --- a/src/librustc/middle/borrowck/doc.rs +++ b/src/librustc/middle/borrowck/doc.rs @@ -790,7 +790,15 @@ particular, if the referent is frozen, there is no harm in it: In this case, creating the alias `t2` of `t0` is safe because the only thing `t2` can be used for is to further freeze `*t0`, which is -already frozen. +already frozen. In particular, we cannot assign to `*t0` through the +new alias `t2`, as demonstrated in this test case: + + // src/test/run-pass/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs + fn foo(t0: & &mut int) { + let t1 = t0; + let p: &int = &**t0; + **t1 = 22; //~ ERROR cannot assign + } This distinction is reflected in the rules. When doing an `&mut` borrow -- as in the first example -- the set `ACTIONS` will be @@ -805,6 +813,8 @@ the referent implies that it cannot be claimed or mutated but permits others to freeze. Hence when these restrictions are propagated back to the base path, it will still be considered freezable. + + **FIXME #10520: Restrictions against mutating the base pointer.** When an `&mut` pointer is frozen or claimed, we currently pass along the restriction against MUTATE to the base pointer. I do not believe this diff --git a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs index 843b5436d842..f72dacc2d813 100644 --- a/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs +++ b/src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs @@ -1,3 +1,13 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + // Test that attempt to reborrow an `&mut` pointer in an aliasable // location yields an error. // @@ -7,7 +17,7 @@ use std::util::swap; fn foo(t0: & &mut int) { let t1 = t0; - let p: &int = &**t0; //~ ERROR cannot borrow an `&mut` in a `&` pointer + let p: &int = &**t0; **t1 = 22; //~ ERROR cannot assign } diff --git a/src/test/compile-fail/borrowck-borrow-of-mut-base-ptr.rs b/src/test/compile-fail/borrowck-borrow-of-mut-base-ptr.rs index fd6fda22be21..3f67952fa8ef 100644 --- a/src/test/compile-fail/borrowck-borrow-of-mut-base-ptr.rs +++ b/src/test/compile-fail/borrowck-borrow-of-mut-base-ptr.rs @@ -19,7 +19,7 @@ fn foo<'a>(mut t0: &'a mut int, mut t1: &'a mut int) { let p: &mut int = &mut *t0; // Claims `*t0` let mut t2 = &t0; //~ ERROR cannot borrow `t0` - let q: &int = &*t2; // Freezes `*t0` but not through `*p` + let q: &int = &**t2; // Freezes `*t0` but not through `*p` *p += 1; // violates type of `*q` }