Hi, I am a newbie. Here's a simplified version of my code:
trait Voice {
fn say();
}
struct Cat;
impl Voice for Cat {
fn say() {
println!("meow!");
}
}
struct Dog;
impl Voice for Dog {
fn say() {
println!("woof!");
}
}
fn call_animal<T: Voice>() {
T::say();
}
enum Animal {
Cat,
Dog,
}
fn main() {
let animal = Animal::Cat;
let name = match animal {
Animal::Cat => "cat",
Animal::Dog => "dog",
};
let func = match animal {
Animal::Cat => call_animal::<Cat>,
Animal::Dog => call_animal::<Dog>,
};
println!("{name} says:");
func();
}
This compiles fine. However, if we replace the main function with the following:
fn main() {
let animal = Animal::Cat;
let (name, func) = match animal {
Animal::Cat => ("cat", call_animal::<Cat>),
Animal::Dog => ("dog", call_animal::<Dog>),
};
println!("{name} says:");
func();
}
it won't compile:
Compiling match-test v0.1.0 (/Users/untech/Documents/code/rust/match-test)
error[E0308]: `match` arms have incompatible types
--> src/main.rs:32:24
|
30 | let (name, func) = match animal {
| ________________________-
31 | | Animal::Cat => ("cat", call_animal::<Cat>),
| | --------------------------- this is found to be of type `(&str, fn() {call_animal::<Cat>})`
32 | | Animal::Dog => ("dog", call_animal::<Dog>),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(&str, fn() {call_animal::<Cat>})`, found `(&str, fn() {call_animal::<Dog>})`
33 | | };
| |_____- `match` arms have incompatible types
|
= note: expected tuple `(&_, fn() {call_animal::<Cat>})`
found tuple `(&'static _, fn() {call_animal::<Dog>})`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `match-test` (bin "match-test") due to 1 previous error
Apparently, the compiler can't infer the common type for two generic functions.
Questions:
- Is this a problem in my code, or a compiler problem?
- If it's a compiler problem, is this a known compiler problem, or should I report it somehow?