and `*LV` is a pointer dereference. There is no auto-deref or other
niceties. This means that if you have a type like:
-```text
+```rust
struct S { f: uint }
```
Now, imagine we had a program like this:
-```text
+```rust
struct Foo { f: uint, g: uint }
...
'a: {
- let mut x: Box<Foo> = ...;
- let y = &mut (*x).f;
- x = ...;
+ let mut x: Box<Foo> = ...;
+ let y = &mut (*x).f;
+ x = ...;
}
```
of the `&Ty` pointer. In simple cases, this clause is redundant, since
the `LIFETIME()` function will already enforce the required rule:
-```
+```rust
fn foo(point: &'a Point) -> &'static f32 {
&point.x // Error
}
but also by the basic `LIFETIME()` check. However, in more advanced
examples involving multiple nested pointers, clause (1) is needed:
-```
+```rust
fn foo(point: &'a &'b mut Point) -> &'b f32 {
&point.x // Error
}
As a final twist, consider the case of two nested *immutable*
pointers, rather than a mutable pointer within an immutable one:
-```
+```rust
fn foo(point: &'a &'b Point) -> &'b f32 {
&point.x // OK
}
create a borrowed pointer that outlives the memory it points at. So
`LIFETIME` prevents a function like this:
-```
+```rust
fn get_1<'a>() -> &'a int {
let x = 1;
&x
mutate it. This distinction is important for type checking functions
like this one:
-```
+```rust
fn inc_and_get<'a>(p: &'a mut Point) -> &'a int {
p.x += 1;
&p.x
Here is a concrete example of a bug this rule prevents:
-```
+```rust
// Test region-reborrow-from-shorter-mut-ref.rs:
fn copy_pointer<'a,'b,T>(x: &'a mut &'b mut T) -> &'b mut T {
&mut **p // ERROR due to clause (1)
and access it via that new name, thus bypassing the restrictions on
the old name. Here is an example:
-```
+```rust
// src/test/compile-fail/borrowck-move-mut-base-ptr.rs
fn foo(t0: &mut int) {
let p: &int = &*t0; // Freezes `*t0`
scenarios. The most obvious is that the mutable borrow itself becomes
another path to access the same data, as shown here:
-```
+```rust
// src/test/compile-fail/borrowck-mut-borrow-of-mut-base-ptr.rs
fn foo<'a>(mut t0: &'a mut int,
mut t1: &'a mut int) {
Another danger with an `&mut` pointer is that we could swap the `t0`
value away to create a new path:
-```
+```rust
// src/test/compile-fail/borrowck-swap-mut-base-ptr.rs
fn foo<'a>(mut t0: &'a mut int,
mut t1: &'a mut int) {
referent is claimed, even freezing the base pointer can be dangerous,
as shown in the following example:
-```
+```rust
// src/test/compile-fail/borrowck-borrow-of-mut-base-ptr.rs
fn foo<'a>(mut t0: &'a mut int,
mut t1: &'a mut int) {
However, it is not always unsafe to freeze the base pointer. In
particular, if the referent is frozen, there is no harm in it:
-```
+```rust
// src/test/run-pass/borrowck-borrow-of-mut-base-ptr-safe.rs
fn foo<'a>(mut t0: &'a mut int,
mut t1: &'a mut int) {
already frozen. In particular, we cannot assign to `*t0` through the
new alias `t2`, as demonstrated in this test case:
-```
+```rust
// src/test/run-pass/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
fn foo(t0: & &mut int) {
let t1 = t0;
Let's look at a simple example:
-```
+```rust
fn foo(a: Box<int>) {
let b: Box<int>; // Gen bit 0.