It seems totally valid code which I wasn't expecting. I could understand that: "hello".chars().rev().collect::<_>() should be valid, but empty? If there's no valid reason why someone should write an empty turbofish then maybe it should be turned into a warning given the wrong number of arguments are specified?
Or is it purely for asthetic purposes that people think it looks pretty?
error[E0282]: type annotations needed
--> src/main.rs:5:10
|
5 | dbg!(Foo::<>::default());
| ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the struct `Foo`
Also, rustfmt removes the ::<> in that statement when ran.
From @matt1985's post it does look like <> has the semantics of <..>, if that were valid syntax: infer / use a placeholder parameter for each generic parameter (which is thus not the same as writing no turbofish, which gets to use default type parameters when available).
That being said, I find that behavior (on top of unintuitive) to be inconsistent and cause problems with some macros. Take, for instance, the following crate (of mine):
It works as follows: you #[with]-annotate a function definition, say foo<T>, and it converts that into a with_foo<R, F, T>. Then, at call-site / usage-site, you also #[with]-annotate a foo $(::<…>)? call, and it converts that into a with_foo $(::<_, _, …>)? to make sure the two added type parameters are inferred.
The fact that one can feed an "empty parameter sequence" into a turbofish site to express that all parameters should be inferred means that I now must special-case that pattern too (hence why it is inconsistent: it requires special-casing) to become:
foo $(::<$(…)?>)? -> with_foo $(::<$(_, _, …)?>)?
Granted, it's definitely a manageable inconsistency, but an inconsistency nonetheless. Could this kind of oversight(s) be removed in a future edition?
That being said, it does bring into the table the topic of a syntax to explicitly elide all "remaining" (type?) parameters, which I think could be desirable in general (it could, for instance, make a fn generic_with_anon_type_param<T> (f: impl …) be fed a T at call site: generic_with_anon_type_param<T, ..> without requiring having solved the "can anonymous type parameters be explicitly fed" question).