Description
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 :)