This code compiles:
#[derive(Debug, Default)]
struct Example;
impl Example {
fn some_method(&self) {}
}
fn reproduction() -> Example {
let example = Default::default();
// example.some_method();
example
}
If the commented line is added back, it will cause an error:
error[E0282]: type annotations needed
--> src/lib.rs:10:5
|
9 | let example = Default::default();
| ------- consider giving `example` a type
10 | example.some_method();
| ^^^^^^^ cannot infer type
|
= note: type must be known at this point
Why does adding this method call cause type inference to fail?
I've seen these two questions:
- How does Rust's type inference work across multiple statements?
- How does Rust infer resultant types from From::<>::from()?
From them, I know that Rust uses a (modified) version of Hindley-Milner. The latter question has an answer that describes Rust's type inference as a system of equations. Another answer explicitly states that "Type information in Rust can flow backwards".
Using this knowledge applied to this situation, we have:
example
is type?E
?E
must have a method calledsome_method
?E
is returned- The return type is
Example
Working backward, it's easy for a human to see that ?E
must be Example
. Where is the gap between what I can see and what the compiler can see?
-Z chalk
(nightly) and same result. – zrzka