So, the following code seems like it should work:
use std::marker::PhantomData;
pub struct Foo<X=()> {
_a: PhantomData<X>,
}
impl<X> Foo<X> {
pub fn new() -> Self {
Foo {
_a: PhantomData,
}
}
}
fn main() {
let f = Foo::new();
}
But, I get the error:
Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed for `Foo<X>`
--> src/main.rs:16:13
|
16 | let f = Foo::new();
| - ^^^^^^^^ cannot infer type for `X`
| |
| consider giving `f` the explicit type `Foo<X>`, where the type parameter `X` is specified
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
Why? Shouldn't the type inference see the clearly-marked default type for X and use that when it can't find a clear definition? I get that X can't be discovered from the line let f = Foo::new();
alone, but shouldn't that be where the default type comes into play? Otherwise, I have to have the clunky:
let f: Foo<()> = Foo::new();
when it seems like that should be pretty obvious what was intended (and no other cases seem to make sense, otherwise I would have provided a type, so it doesn't seem like it could be ambiguous).
Edit to add:
I could just specify a type in the new
constructor, which will avoid type inference altogether:
impl<X> Foo<X> {
pub fn new(_: X) -> Self {
then call it as let f = Foo::new(());
This works, but is also quite clunky, and seems to defeat the purpose of a default type anyway.
Any thoughts or corrections on my usage (or understanding) of this feature?
Thanks!