The following two lines:
let x = Box::new(("slefj".to_string(), "a".to_string()));
let (a, b) = *x;
produce the error:
error[E0382]: use of moved value: `x`
--> src/main.rs:3:13
|
3 | let (a, b) = *x;
| - ^ value used here after move
| |
| value moved here
|
= note: move occurs because `x.0` has type `std::string::String`, which does not implement the `Copy` trait
Interestingly, if I do this with an enumeration type with multiple parts, I get a slightly different error:
enum Tree {
Nil,
Pair(Box<Tree>, Box<Tree>),
}
fn main() {
let x = Box::new(Tree::Nil);
match *x {
Tree::Pair(a, b) => Tree::Pair(a, b),
_ => Tree::Nil,
};
}
I get the error:
error[E0382]: use of collaterally moved value: `(x:Tree::Pair).1`
--> src/main.rs:10:23
|
10 | Tree::Pair(a, b) => Tree::Pair(a, b),
| - ^ value used here after move
| |
| value moved here
|
= note: move occurs because `(x:Tree::Pair).0` has type `std::boxed::Box<Tree>`, which does not implement the `Copy` trait
Why does this happen, and how can I easily destruct structures with let
/match
and get ownership of the inner parts? I know I can dereference and name the structure first, but that gets horribly verbose if I'm pattern matching deep into a structure.
You have stumbled on a limitation on destructuring and boxes. Luckily, it's easy to work around these. All you need to do is introduce a new intermediary variable that contains the whole structure, and destructure from that:
let x = Box::new(("slefj".to_string(), "a".to_string()));
let pair = *x;
let (a, b) = pair;
The second example:
let pair = *x;
match pair {
Tree::Pair(a, b) => Tree::Pair(a, b),
_ => Tree::Nil,
};
The good news is that your original code works as-is now that non-lexical lifetimes are enabled by default:
fn main() {
let x = Box::new(("slefj".to_string(), "a".to_string()));
let (a, b) = *x;
}
The borrow checker's capability to track the moves out of the box is enhanced, allowing the code to compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With