I stumbled about an behavior of the rust compiler, which i find strange.
I would expect, that i get a compile error for the following code, but i get only warnings:
[derive(Debug)]
enum Test1 {
A,
B
}
#[derive(Debug)]
enum Test2 {
A,
B
}
fn convert_a(t1: Test1) -> Test2 {
match t1 {
A => Test2::A,
B => Test2::B,
}
}
fn convert_b(t1: Test1) -> Test2 {
match t1 {
ARRRRGGG => Test2::A,
B => Test2::B,
}
}
fn main() {
{ // Part 1
let val = Test1::B;
println!("val: {:?}", val);
let val_conv = convert_a(val);
println!("val_conv: {:?}", val_conv);
}
{ // Part 2
let val = Test1::B;
println!("val: {:?}", val);
let val_conv = convert_b(val);
println!("val_conv: {:?}", val_conv);
}
}
The combination of these to warning are interesting:
warning[E0170]: pattern binding `A` is named the same as one of the variants of the type `Test1`
--> src/main.rs:15:9
|
15 | A => Test2::A,
| ^ help: to match on the variant, qualify the path: `Test1::A`
|
= note: `#[warn(bindings_with_variant_name)]` on by default
warning: unreachable pattern
--> src/main.rs:16:9
|
15 | A => Test2::A,
| - matches any value
16 | B => Test2::B,
| ^ unreachable pattern
|
= note: `#[warn(unreachable_patterns)]` on by default
I get the following output from the program:
val: B
val_conv: A
val: B
val_conv: A
I was expecting, that the compiler infers the type of t1 in function convert_a() and than use Test1::A. And from the warning i know, that the compiler is able to do this.
In case of convert_b i would expect an error message from the compiler, that ARRRRGGG is not defined.
The real problem comes in combination with the second warning: This leads to an behavior of the program which i don't expect. Does anyone know, why the compiler is doing this? Is this intended behavior
If, I fix all warning, than everything is fine. But currently, I'm implementing a trait with several methods and test each implemented method, after i implemented it. Since i use the warnings as a kind of remainder, that i have to do something at this point, i did not give the parameter a name which start with an underscore. Therefore I get a lot of warnings currently and didn't saw these warnings. Therefore i spend some time to debug the program, but could not find the reason.
In combination with "#![allow(warnings)]" this is really dangerous.
I'm an C/C++ programmer and I'm currently trying rust since it can also be used for low-level stuff and has similar performance, but with the promise that i can't shoot my self in the foot anymore. In this case, I think the promise is not true.
PS:
# rustc --version
rustc 1.50.0-nightly (1c389ffef 2020-11-24)
Edit: See the post from jdahlstrom for good explanation.