Understanding Rust Error E0009: Binding by-move and by-ref
Rust Error E0009 Explained
Rust error E0009 occurs when a pattern binding attempts to mix by-move and by-ref bindings in the same pattern. Since values that do not implement the Copy trait cannot be bound both by-move and by-ref, this error will occur.
Example: Triggering E0009 in Rust
#![allow(unused)]
#![feature(move_ref_pattern)]
fn main() {
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {}, // error: cannot bind by-move and by-ref in the
// same pattern
None => panic!()
}
}
In this example, struct X does not implement the Copy trait, and the match expression tries to bind both by-move (y) and by-ref (ref z). This results in error E0009.
Solution 1: Consistent binding
One solution is to bind the pattern's values the same way, either by-ref or by-move.
By-ref example:
#![allow(unused)]
fn main() {
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((ref y, ref z)) => {},
None => panic!()
}
}
By-move example:
#![allow(unused)]
fn main() {
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, z)) => {},
None => panic!()
}
}
Solution 2: Implement the Copy trait
Another solution is implementing the Copy trait for the X structure. Note that the first solution is usually preferred.
#![allow(unused)]
fn main() {
#[derive(Clone, Copy)]
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {},
None => panic!()
}
}