# Is the empty turbofish just for asthetics?

**URL:** <https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972>\
**Category:** Uncategorized\
**Created:** [February 3, 2021, 7:19am UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972 "2021-02-03T07:19:50Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![gilescope](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gilescope/32/2798_2.png) [@gilescope](https://internals.rust-lang.org/u/gilescope)\
**Post date:** [February 3, 2021, 7:19am UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972/1 "2021-02-03T07:19:50Z")

</div>

Dear turbofish appreciation society,

I appreciate this may be a delicate topic, but is there any use for an empty turbofish?

E.g.

```rust
fn hello_back() -> String {
    "hello".chars().rev().collect::<>()
}

```

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](https://turbo.fish/)?

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 3, 2021, 7:36am UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972/2 "2021-02-03T07:36:26Z")

</div>

Hmm, that's curious.

It's absolutely expected that you can put empty generic parameter lists on non-generic things, like

```rust
fn hello_back<>() -> String<> { "hello".to_string() }

```

because that's helpful for macros and other generated code.

But empty-on-something-that-actually-has-some is not something I knew worked.

---

<div class="post-metadata">

**Author:** ![matt1985](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matt1985/32/4772_2.png) [@matt1985](https://internals.rust-lang.org/u/matt1985)\
**Post date:** [February 3, 2021, 10:10am UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972/3 "2021-02-03T10:10:48Z")

</div>

`::<>` makes the first statement here not compile: [https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4fc7286417d85f51648a65f10382ef0a](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4fc7286417d85f51648a65f10382ef0a)

```rust
#[derive(Debug, Default)]
struct Foo<T = u32, U = u64>(T, U);

fn main(){
    dbg!(Foo::<>::default());
    dbg!(<Foo>::default());
    dbg!(Foo::<()>::default());
}

```

```rust
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.

---

<div class="post-metadata">

**Author:** ![dhm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhm/32/4879_2.png) [@dhm](https://internals.rust-lang.org/u/dhm)\
**Post date:** [February 3, 2021, 2:15pm UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972/4 "2021-02-03T14:15:59Z")

</div>

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):

> **[with\_locals](https://lib.rs/crates/with_locals)**
>
> Function attribute to return references to locals by using CPS

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).

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 3, 2021, 5:41pm UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972/5 "2021-02-03T17:41:00Z")

</div>

> [@dhm](#):
>
> Could this kind of oversight(s) be removed in a future edition?

Yes. This is frontend syntax only, not anything impacting "core rust", so it could be changed across an edition boundary.

If someone were interested in doing that, the first step would be to make a lint warning about it.

(Said without making an official statement on what _should_ happen, though at least a lint about it seems plausible to me.)

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [May 4, 2021, 5:41pm UTC](https://internals.rust-lang.org/t/is-the-empty-turbofish-just-for-asthetics/13972/6 "2021-05-04T17:41:39Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
