I have a trait with an associated type:
pub trait Speak {
type Error;
fn speak(&self) -> Result<String, Self::Error>;
}
An implementation of that trait:
#[derive(Default)]
pub struct Dog;
impl Speak for Dog {
type Error = ();
fn speak(&self) -> Result<String, Self::Error> {
Ok("woof".to_string())
}
}
And a function returning an instance of that implementation:
pub fn speaker() -> impl Speak {
Dog::default()
}
I know that in this example I could just use Dog
as the return type, but in my actual code I have to use impl Speak
instead (the above function is in fact generated by a macro).
As I understand it, the impl Trait
notation lets the compiler figure out which concrete type is actually returned, so I would expect the following function to compile correctly because speaker()
returns a Dog
and that Dog::Error
is the type ()
:
fn test() -> Result<String, ()> {
speaker().speak()
}
playground
Instead, I get the following error:
error[E0308]: mismatched types
--> src/lib.rs:21:5
|
20 | fn test() -> Result<String, ()> {
| ------------------ expected `std::result::Result<std::string::String, ()>` because of return type
21 | speaker().speak()
| ^^^^^^^^^^^^^^^^^ expected (), found associated type
|
= note: expected type `std::result::Result<_, ()>`
found type `std::result::Result<_, <impl Speak as Speak>::Error>`
It is as if the compiler could not (at this point) infer the return type of the speaker
function.
Who is missing something something, the compiler or myself?