Why can't the type be inferred from the return type here?

Consider this minimal example:

trait Empty {
    const EMPTY: Self;
}

struct MyStruct {
    a: Option<i32>,
    b: Option<i32>,
}

impl Empty for MyStruct {
    const EMPTY: Self = MyStruct { a: None, b: None };
}


fn make_my_struct() -> MyStruct {
    let mut t = Empty::EMPTY;
    t.b = Some(17);
    t
}
error[E0282]: type annotations needed
  --> src/lib.rs:17:5
   |
16 |     let mut t = Empty::EMPTY;
   |         ----- consider giving `t` a type
17 |     t.b = Some(17);
   |     ^ cannot infer type
   |
   = note: type must be known at this point

Why wouldn't t's type be inferrable from the return type of fn make_my_struct() -> MyStruct?

(Rust Playground link)

I think it's because you could have another struct that also implements Empty. Then the compiler wouldn't be able to just decide to coerce to one or another so the return type fits. That's not the case here, but I think the compiler might be using the same logic (not being able to coerce).

I don't know how the compiler actually does typesolving though, so take this with a grain of salt :wink:

It's currently pretty common for the compiler to insist on knowing a type by the "time" it needs to do a field access or method call, even if it's unambiguous when starting "later" and working backwards. This may improve in the future.

You can use MyTable::EMPTY.

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