Skip to content

Instantly share code, notes, and snippets.

@csmoe
Created March 7, 2019 06:08
Show Gist options
  • Save csmoe/eed64550dba5d80e8fd53f273c3d892f to your computer and use it in GitHub Desktop.
Save csmoe/eed64550dba5d80e8fd53f273c3d892f to your computer and use it in GitHub Desktop.

impl Trait

Is the same syntax for both

  • anonymous generic parameters
  • inferred return types

E.g. in the function fn f<T: Trait1>(t: T, u: impl Trait2) -> impl Trait3 you have one named generic parameter, one anonymous generic parameter and a return type inferred from the function body.

Note that outside the function you will never know what type has been inferred as the return type, all you know is that you can interact with the returned value via the trait Trait3.

Return position impl Trait

A function fn g() -> impl Trait3 means

There is a concrete type V which implements Trait3 that is the return type of g

or in math terms

∃ V: Trait3.
    fn f() -> V

Named generic argument

A function fn h<T: Trait1>(t: T) means

For any type T that implements Trait1 there exists a function called h that takes an argument of type T

or

∀ T: Trait1.
    fn h(T)

Anonymous generic parameter (argument position impl Trait)

A function fn i(u: impl Trait2) means

For any type U that implements Trait2 there exists a function called i that takes an argument of type U

or

∀ U: Trait2.
    fn i(U)

so fn foo<U: Trait2>(u: U) and fn foo(u: impl Trait2) are exactly the same function except in syntax.

All of the above

A function fn f<T: Trait1>(t: T, u: impl Trait2) -> impl Trait3 means

For any type T that implements Trait1 and for any type U that implements Trait2 there is a concrete type V which implements Trait3 that is the return type of f

or

∀ T: Trait1.
    ∀ U: Trait2.
        ∃ V: Trait3.
            fn f(T, U) -> V

Named return position impl Trait or "named existential types"

Not yet in nightly, though there's an open PR: rust-lang/rust#52024

existential type W: Trait4;
fn j() -> W;

is equivalent to fn j() -> impl Trait4. The only difference is that you can have multiple functions return the same W:

existential type W: Trait4;
fn j() -> W;
fn k() -> W;

meaning

There is a concrete type W which implements Trait4 that is the return type of j and k

or

∃ W: Trait4.
    fn j() -> W,
    fn k() -> W
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment