I Think I Found a "Bug" In Rust's Error Message For This Situation

Me and my brother have both ran into a situation with match statements that have resulted in a confusing error message from rustc that isn't actually idicative of the real problem. For instance, take this tiny program:

fn main() {
    match 4 {
        4 => "hello",
        _ => unreachable!(),
    }
}

It reports an error:

 --> src/main.rs:4:14
  |
2 | /     match 4 {
3 | |         4 => "hello",
  | |              ------- this is found to be of type `&str`
4 | |         _ => unreachable!(),
  | |              ^^^^^^^^^^^^^^ expected `&str`, found `()`
5 | |     }
  | |_____- `match` arms have incompatible types
  |
  = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

"What! I know I've done this before", I was thinking. Panics return "never" ( ! ), and thus they don't have to have the same type as the other branches. The error didn't make any sense. Then I realized I was missing a semi-colon at the end of the match statement:

fn main() {
    match 4 {
        4 => "hello",
        _ => unreachable!(),
    };
}

Now rust is happy. So the actual problem had nothing to do with branch arms, but actually the fact that main should have "Expected type (), but got type &str".

Looks like a bug to me, you should open an issue on the github repo

2 Likes

I think this error message is not great, but it's not necessarily a bug, either. Here's a possible explanation:

It seems like the compiler first tries to unify panic!() with the return type of the function, which of course succeeds trivially.

Only then it goes on to check the other arm of the match, in which case it finds out that the inferred types don't match.

This means that the type mismatch is there, and it is indeed str-vs-unit, it's just not pointing to the direct cause.

This might potentially be hard to improve depending on the inference heuristics rustc is using for unification.

3 Likes

It could possibly be improved by noticing that the function returns () and suggesting that perhaps a semicolon is missing. That might at least save people some time from chasing down the wrong thing.

4 Likes

The ticket tracking this case is https://github.com/rust-lang/rust/issues/24157

(Funnily enough, it is the 3rd oldest A-diagnostics open bug :sweat_smile:)

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.