Skip to content

meaning of impl Fn() -> impl Trait (and potentially impl Foo<Output = impl Bar> #15

Open
@nikomatsakis

Description

@nikomatsakis

Motivation

As of 2023-04-10, the compiler permits impl Foo<Output = impl Bar> but not impl Fn() -> impl Bar. There have been proposals to permit impl Trait in the latter position -- but what should it mean?

Details

This issue exists to catalog the various options.

  • In argument position:
    • fn something(f: impl Fn() -> impl Debug) could be equivalent to fn something<A,E>(f: A) where A: Fn() -> E, E: Debug, but this cannot accommodate higher-ranked signatures like impl Fn(&u32) -> impl Debug + '_.
    • fn something(f: impl Fn() -> impl Debug) could also be equivalent to fn something<A>(f: A) where A: Fn() -> _, A::Output: Debug (this is not legal syntax today, the -> _ is meant to mean "returns some type not specified). This would accommodate said signatures.
    • The same is relevant to impl Foo<Output = impl Bar>; for example to permit writing something like impl for<'a> Foo<Output<'a> = impl Bar + 'a> (not currently possible). Can we transition from current behavior to this? Not entirely backwards compatible, perhaps, but likely achievable. (Today, impl for<'a> Foo<Output<'a> = impl Bar> would assert that Output value is not dependent on 'a because the impl Bar desugars to a generic parameter outside the scope of the for.)
      cannot.
  • In return position:
    • fn something() -> impl Fn() -> impl Debug could be equivalent to type A: Fn() -> B; type B: Debug; fn something() -> A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions