Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Somewhat unclear error message when match arms evaluate to different types #46776

Closed
S0urc3C0de opened this issue Dec 16, 2017 · 2 comments · Fixed by #58267
Closed

Somewhat unclear error message when match arms evaluate to different types #46776

S0urc3C0de opened this issue Dec 16, 2017 · 2 comments · Fixed by #58267
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. WG-diagnostics Working group: Diagnostics

Comments

@S0urc3C0de
Copy link

S0urc3C0de commented Dec 16, 2017

Hi, I just found a minor annoyance in the compiler diagnostics.

Here's the code:

for key in 0..0x10 {
    match Keyboard::assoc_key(key) {
        Some(x) => keyboard.data.insert(x, false),
        _ => {},
    };
}

keyboard.data is a HashMap inside a struct, defined as:

data: HashMap<Keys, bool>

Keyboard::assoc_key is defined as:

fn assoc_key(n: u8) -> Option<Keys>

Keys is just a simple enum type.

The problem with the code above is that HashMap::insert returns an Option and so the match tries to evaluate to that type which is, however, not needed in this case. But it means that the default arm must also evaluate to an Option which it doesn't.
The compiler obviously complains about this:

error[E0308]: match arms have incompatible types
  --> src/keyboard.rs:21:13
   |
21 | /             match Keyboard::assoc_key(key) {
22 | |                 Some(x) => keyboard.data.insert(x, false),
23 | |                 _ => {},
24 | |             };
   | |_____________^ expected enum `std::option::Option`, found ()
   |
   = note: expected type `std::option::Option<bool>`
              found type `()`
note: match arm with an incompatible type
  --> src/keyboard.rs:23:22
   |
23 |                 _ => {},
   |                      ^^

error: aborting due to previous error

This confused me for a while because that was the first time I used a HashMap and I didn't have in mind that HashMap::insert returns something.
I think the compiler should specifically mention why it expects an Option, that is, from where it inferred the type which would have made it more obvious that HashMap::insert returns an Option.
I suppose this is something that typically doesn't happen to someone who is familiar enough with the language but it's confusing for someone who only recently began learning Rust.

I've looked for existing similar issues but found nothing obvious. If this has already been discussed somewhere or is not considered an issue, please close this :)

@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. E-needs-mentor WG-diagnostics Working group: Diagnostics labels Dec 16, 2017
@ritiek
Copy link
Member

ritiek commented Jan 1, 2018

A smaller reproduce (?):

fn main() {
    let my_bool = true;
    match my_bool {
        true => Some(true), // `Some()` returns an `Option`
        false => {},
    };
}

@estebank
Copy link
Contributor

estebank commented Jan 3, 2019

CC #57206, #38234, #24157

Centril added a commit to Centril/rust that referenced this issue Feb 14, 2019
Tweak "incompatible match arms" error

- Point at the body expression of the match arm with the type error.
- Point at the prior match arms explicitly stating the evaluated type.
- Point at the entire match expr in a secondary span, instead of primary.
- For type errors in the first match arm, the cause is outside of the
  match, treat as implicit block error to give a more appropriate error.

Fix rust-lang#46776, fix rust-lang#57206.
CC rust-lang#24157, rust-lang#38234.
Centril added a commit to Centril/rust that referenced this issue Feb 14, 2019
Tweak "incompatible match arms" error

- Point at the body expression of the match arm with the type error.
- Point at the prior match arms explicitly stating the evaluated type.
- Point at the entire match expr in a secondary span, instead of primary.
- For type errors in the first match arm, the cause is outside of the
  match, treat as implicit block error to give a more appropriate error.

Fix rust-lang#46776, fix rust-lang#57206.
CC rust-lang#24157, rust-lang#38234.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants