Reputation: 28552
I'm playing with Rust and found the following example:
fn main() {
let mut x = [3, 4, 5].to_vec();
x;
println!("{:?}", x);
}
The compiler tells me
18 | let mut x = [3, 4, 5].to_vec();
| ----- move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
...
21 | x;
| - value moved here
22 | println!("{:?}", x);
| ^ value borrowed here after move
It seems the statement x;
caused x
moved to somewhere and it can't be used after that. Where is the move destination and what exactly happend here?
I searched around and can't find any information explaining this. Maybe I'm using the wrong keyword.
Btw, I'm using this version of Rust: rustc 1.41.0-nightly (99b89533d 2019-12-16)
Upvotes: 4
Views: 273
Reputation: 13942
x;
is an expression statement that:
An expression statement is one that evaluates an expression and ignores its result.
The expression here is in turn a place expression which:
Moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is reinitialized.
So after that you can't use it again. In fact, if you compile the following:
fn main() {
let x = vec![42];
x;
}
to MIR:
fn main() -> () {
let mut _0: (); // return place in scope 0 at src/main.rs:1:11: 1:11
let _1: std::vec::Vec<i32>; // "x" in scope 0 at src/main.rs:2:9: 2:10
...
bb1: {
StorageDead(_2); // bb1[0]: scope 0 at <::alloc::macros::vec macros>:2:62: 2:63
StorageLive(_5); // bb1[1]: scope 1 at src/main.rs:3:5: 3:6
_5 = move _1; // bb1[2]: scope 1 at src/main.rs:3:5: 3:6
drop(_5) -> bb2; // bb1[3]: scope 1 at src/main.rs:3:6: 3:7
}
}
You can clearly see it is moved into a temporary variable and that temporary variable is promptly dropped.
Upvotes: 8