Why can't rust infer the type if struct fields are used?

Consider the following code:

#[derive(Clone, Copy, Debug)]
struct TestStruct
{
    a: u8,
}

fn main()
{
    let v = vec![TestStruct { a: 5 }];

    let mut last_option = None;

    for current_val in v
    {
        if let Some(last) = last_option
        {
            println!("{:?}", last.a);
        }
        last_option = Some(current_val);
    }
}

This compiles, or at least it should. In reality I get the following error message:

error[E0282]: type annotations needed for `Option<T>`
  --> src/main.rs:17:30
   |
11 |     let mut last_option = None;
   |         --------------- consider giving `last_option` the explicit type `Option<T>`, with the type parameters specified
...
17 |             println!("{:?}", last.a);
   |                              ^^^^ cannot infer type
   |
   = note: type must be known at this point

For more information about this error, try `rustc --explain E0282`.

Rust should – I think – be able to figure it out. Even stranger is that if I remove the .a in last.a on line 17 it suddenly works as expected.

What am I missing?

(
Rust version:

rustc 1.57.0-nightly (0eabf25b9 2021-10-06)
binary: rustc
commit-hash: 0eabf25b90396dead0b2a1aaa275af18a1ae6008
commit-date: 2021-10-06
host: x86_64-unknown-linux-gnu
release: 1.57.0-nightly
LLVM version: 13.0.0

)

1 Like

I suspect that rustc is a bit too eager to resolve the .a field before it visited the last_option = Some(current_val); to infer the type of last.

It's a bug then? Not a mistake on my side or a feature of rust?

Not a "bug" per se – there are things that the compiler is smart enough to see through, and there are other cases when its heuristics break down. This is a common limitation of many languages that employ type inference extensively.

2 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.