How do I persuade the Rust compiler that the internal match
expression is fine here, as the outer match
has already restricted the possible types?
enum Op {
LoadX,
LoadY,
Add,
}
fn test(o: Op) {
match o {
Op::LoadX | Op::LoadY => {
// do something common with them for code reuse:
print!("Loading ");
// do something specific to each case:
match o {
// now I know that `o` can only be LoadX | LoadY,
// but how to persuade the compiler?
Op::LoadX => print!("x"), /* LoadX specific */
Op::LoadY => print!("y"), /* LoadY specific */
_ => panic!("shouldn't happen!"),
}
println!("...");
}
Op::Add => println!("Adding"),
}
}
fn main() {
test(Op::LoadX);
test(Op::LoadY);
test(Op::Add);
}
I tried two approaches, but neither seems to work.
Name the or-pattern and then match using that name:
match o { load@(Op::LoadX | Op::LoadY) => { // ... match load { // ... } }
That's not valid Rust syntax.
Name and bind every constructor:
match o { load@Op::LoadX | load@Op::LoadY => { // ... match load { //... } }
That still doesn't satisfy the exhaustiveness check, hence the same error message:
error[E0004]: non-exhaustive patterns: `Add` not covered --> src/main.rs:14:19 | 14 | match load { | ^ pattern `Add` not covered
Is there any idiomatic way of solving this problem or should I just put panic!("shouldn't happen")
all over the place or restructure the code?
o
is immutable. – Hokku