Help me understand move semantics when destructuring enums.
I have following types:
pub enum Expr {
Number(i32),
Op(Box<Expr>, Opcode, Box<Expr>),
}
pub enum Opcode {
Mul,
Div,
Add,
Sub,
}
And following function:
fn evaluate(expression: Box<Expr>) -> i32 { // Takes ownership of expression
match *expression { // Deref box
Expr::Number(n) => n,
Expr::Op(rv, opcode, lv) => match opcode { // Destructure owned expression via move
// I expect get values rv, opcode, lv owned by this block
Opcode::Mul => evaluate(rv) * evaluate(lv),
Opcode::Div => evaluate(rv) / evaluate(lv),
Opcode::Add => evaluate(rv) + evaluate(lv),
Opcode::Sub => evaluate(rv) - evaluate(lv),
},
}
}
This function doesn't compile with following error:
error[E0382]: use of collaterally moved value: `(expression:ast::Expr::Op).1`
--> src/main.rs:9:22
|
| Expr::Op(rv, opcode, lv) => match opcode {
| -- ^^^^^^ value used here after move
| |
| value moved here
|
= note: move occurs because `(expression:ast::Expr::Op).0` has type `Box<ast::Expr>`, which does not implement the `Copy` trait
error[E0382]: use of collaterally moved value: `(expression:ast::Expr::Op).2`
--> src/main.rs:9:30
|
| Expr::Op(rv, opcode, lv) => match opcode {
| -- ^^ value used here after move
| |
| value moved here
|
= note: move occurs because `(expression:ast::Expr::Op).0` has type `Box<ast::Expr>`, which does not implement the `Copy` trait
I can workaround this issue by passing all expressions via reference. But why cannot I use move semantics to destructure enum?