I have a generic struct Test
with a default generic type parameter implementing a trait. Here's my code:
pub trait Implementation {
fn test();
}
pub struct FirstImpl;
impl Implementation for FirstImpl {
fn test() {
todo!()
}
}
pub struct SecondImpl;
impl Implementation for SecondImpl {
fn test() {
todo!()
}
}
pub struct Test<I: Implementation = FirstImpl> {
_p: PhantomData<I>
}
impl <I: Implementation> Test <I> {
pub fn new() -> Self {
Self { _p: PhantomData }
}
}
fn main() {
let t = Test::new();
let t2 = Test::<SecondImpl>::new();
}
Result:
error[E0282]: type annotations needed for `Test` --> src/main.rs:35:9 | 35 |let t = Test::new();
| ^ | help: consider giving `t` an explicit type, where the type for type parameter `I` is specified | 35 |let t: Test<I> = Test::new();
| +++++++++
I've specified a default generic type parameter <I: Implementation = FirstImpl>
, so I expect that when I create a Test
instance without specifying the type parameter it will default to FirstImpl
. However, I'm getting a compiler error that asks me to define the generic parameter I
when calling new()
. I thought the default type parameter would be inferred automatically. Am I missing something here?
Why isn't the default generic type parameter being inferred?
Why isn't the default generic type parameter being inferred?
Because you've provided a new, unrelated, generic parameter to the impl
block. As far as Rust is concerned there is no directly link between the <I: Implementation = FirstImpl>
of the struct and the <I: Implementation>
of the impl
block. It's like declaring a function with a default parameter, then calling it with a parameter but refusing to state what that parameter is.
You could leverage the default by having an
impl Test {
pub fn new() -> Self {
Self { _p: PhantomData }
}
}
although obviously the function is non-parametric, so you only get the default.