Hello! I am new to Rust and trying to figure out how its move semantics work with regards to overwriting moved values. In particular, I wanted to know if it is possible to overwrite a moved reference with a reference with a disjoint lifetime. It appears that this is the case, at least as far a local variables are concerned. The following code behaves as one would expect.
fn main(){
let mut x = 1;
let mut y = 2;
let mut z = &mut x;
let w = z;
x = 3;
z = &mut y;
}
However, if we add tuples to the mix, this no longer appears to be true.
fn main(){
let mut x1 = 1;
let mut x2 = 2;
let mut y = 3;
let mut z = (&mut x1, &mut x2);
let w = z.1;
x2 = 4;
z.1 = &mut y;
}
This produces the error:
error[E0506]: cannot assign to `x2` because it is borrowed
--> <source>:7:4
|
5 | let mut z = (&mut x1, &mut x2);
| ------- `x2` is borrowed here
6 | let w = z.1;
7 | x2 = 4;
| ^^^^^^ `x2` is assigned to here but it was already borrowed
8 | z.1 = &mut y;
| ------------ borrow later used here
In this case, the use of z.1
appears to cause the lifetime to be extended, even though the value with this lifetime has been moved. I am curious as to why this occurs.
From what I have seen so far, it appears that the tuple is assigned a type which is parameterised by the lifetimes of its two components. Is it the case that this lifetime must then last as long as `z' is still being used? That is, only a single lifetime is inferred for the type of the tuple, where as in the variable case, the type can be changed on overwriting.