Default trait type not working for type inference?

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/
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?


As mentioned here, type inference works counterintuitively in this case.

Foo::new() tries to infer all type parameters and it doesn't use type defaults.

You need let f = <Foo>::new(); for your code to compile.

Ah, I didn't see that. What an... odd syntax.

But in any case, this won't work for me, as the example above is but a simple reproduction of my actual use case, where I have many type parameters, and the <Foo>::new() syntax assumes the default for ALL of them (with no inference), so that doesn't really help my case.

Thanks for the heads up, anyway, though!