Reputation: 1242
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!
Upvotes: 3
Views: 434
Reputation: 30021
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.
Upvotes: 7