I was puzzled by the following behavior: could someone explain what is going on?
Consider the code:
struct Point {
cx : u32,
}
fn main() {
let mut p1 = Point { cx: 100 };
let p2 = p1;
p1.cx = 5000;
// println!("p1.x = {}", p1.cx); // disallowed as p1.cx is "moved" ... ok
println!("p2.x = {}", p2.cx); // ==> prints 100 (!)
}
Specifically, I was puzzled that:
p1.cx
is allowed even though the move has occurred, p2.x
is not in fact the updated 5000, but the old 100
.I was expecting the new value as there is no copy-trait (hence the move),
so was expecting there is just a single cell whose updated value (5000
)
should be printed.
However, I must be missing something. Any tips? Thanks in advance!
This is now forbidden.
It used to be allowed. However this was an error in the old borrow checker, and it has been made a warning then an error with the introduction of the new borrow checker (NLL).
For example, with rustc 1.39.0
and the 2015 edition you get the following warning:
warning[E0382]: assign to part of moved value: `p1`
--> a.rs:8:5
|
6 | let mut p1 = Point { cx: 100 };
| ------ move occurs because `p1` has type `Point`, which does not implement the `Copy` trait
7 | let p2 = p1;
| -- value moved here
8 | p1.cx = 5000;
| ^^^^^^^^^^^^ value partially assigned here after move
|
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
= note: for more information, try `rustc --explain E0729`
rustc 1.40.0
turned it into an error:
error[E0382]: assign to part of moved value: `p1`
--> src/main.rs:7:5
|
5 | let mut p1 = Point { cx: 100 };
| ------ move occurs because `p1` has type `Point`, which does not implement the `Copy` trait
6 | let p2 = p1;
| -- value moved here
7 | p1.cx = 5000;
| ^^^^^^^^^^^^ value partially assigned here after move
error: aborting due to previous error
Note also that this was an error with the 2018 edition for a longer time (possibly since the creation of the edition).
See also:
E0729
As previously announced, any previous NLL warnings in the 2015 edition are now hard errors.