I stumbled upon a strange compile error today, that I have minimized to the following example:
#[derive(Copy, Clone, Debug)]
struct Element {
next: Option<usize>,
}
fn main() {
let array = [Element { next: None }; 16];
let number: usize = 42;
let mut option = None;
match option {
Some(n) => {
// This alone compiles
let bar = array[n];
println!("Number is {:?}", bar);
// The following doesn't compile:
// error[E0282]: type annotations needed
// --> src/main.rs:19:23
// |
// 19 | let foo = array[n].next;
// | ^^^^^^^^^^^^^ cannot infer type for `_`
let foo = array[n].next;
println!("Number is {:?}", foo);
}
None => option = Some(number),
}
println!("{:?}", option);
}
What's strange is that when I add a purposefully wrong type annotation like this:
let bar: bool = array[n];
the compiler correctly recognizes that bool
is the wrong type and even tells me the correct type:
error[E0271]: type mismatch resolving `<usize as std::slice::SliceIndex<[Element]>>::Output == bool`
--> src/main.rs:14:29
|
14 | let bar: bool = array[n];
| ^^^^^^^^ expected struct `Element`, found bool
|
= note: expected type `Element`
found type `bool`
However, as soon as I try to access a field, type inference fails. (Basically it knows that array[n]
is of type Element
, but later cannot infer the type of array[n].next
.)
(If I move the None
arm of the match
up to the beginning, type inference succeeds...)
Is this expected behaviour?