I'm trying to find out why this code even compiles. If you use an undefined constant in a match (or: a typo), it will compile and catch-all. Can anyone explain if this is expected behavior and why?
const BEAR: usize = 1;
const LION: usize = 2;
const DUCK: usize = 3;
// This works as expected
fn foo(x: usize) {
match x {
BEAR => println!("[Foo] A Bear!"),
LION => println!("[Foo] A Lion!"),
DUCK => println!("[Foo] A Duck!"),
_ => println!("[Foo] What is this? {}!", x),
}
}
// This is strange
fn bar(x: usize) {
match x {
DODO => println!("[Bar] A Dodo?"), // DODO is not defined anywhere...
BEAR => println!("[Bar] A Bear!"),
LION => println!("[Bar] A Lion!"),
DUCK => println!("[Bar] A Duck!"),
_ => println!("What is this? {}!", x),
}
}
fn main() {
println!("Hello, world!");
foo(BEAR);
foo(LION);
foo(DUCK);
foo(42);
bar(BEAR);
bar(LION);
bar(DUCK);
bar(42);
}
This will print:
Hello, world!
[Foo] A Bear!
[Foo] A Lion!
[Foo] A Duck!
[Foo] What is this? 42!
[Bar] A Dodo?
[Bar] A Dodo?
[Bar] A Dodo?
[Bar] A Dodo?
You could also have written that catch all case in the first match as
n => println!("What is this? {}", n)
Where n would have bound to whatever you got that didn't match a previous case.
The same case now applies to DODO, since it isn't a constant or some specific pattern to match some specific case, the compiler treats it as a general catch-all case where you get whatever was put in there, as long as no previous case matched it. Since DODO happens to be the first case, it matches everything, therefore shadowing the other cases (and that's likely what the compiler warned you about). Try moving the DODO case 1, 2.. line down to see how it behaves.
I hope that clarified this a bit
Because from the compiler's perspective, DODO is no different to dodo or x. It doesn't know you think it's supposed to be a constant. There's no way of fixing this without either requiring "constant = all caps", or making variable binding harder, neither of which seems very likely to ever happen.
error[E0425]: cannot find value `DODO` in this scope
--> src/lib.rs:18:13
|
18 | x if x == DODO => println!("[Bar] A Dodo?"), // DODO is not defined anywhere...
| ^^^^ not found in this scope
error: aborting due to 2 previous errors