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
.
A function fn g() -> impl Trait3
means
There is a concrete type
V
which implementsTrait3
that is the return type ofg
or in math terms
∃ V: Trait3.
fn f() -> V
A function fn h<T: Trait1>(t: T)
means
For any type
T
that implementsTrait1
there exists a function calledh
that takes an argument of typeT
or
∀ T: Trait1.
fn h(T)
A function fn i(u: impl Trait2)
means
For any type
U
that implementsTrait2
there exists a function calledi
that takes an argument of typeU
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.
A function fn f<T: Trait1>(t: T, u: impl Trait2) -> impl Trait3
means
For any type
T
that implementsTrait1
and for any typeU
that implementsTrait2
there is a concrete typeV
which implementsTrait3
that is the return type off
or
∀ T: Trait1.
∀ U: Trait2.
∃ V: Trait3.
fn f(T, U) -> V
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 implementsTrait4
that is the return type ofj
andk
or
∃ W: Trait4.
fn j() -> W,
fn k() -> W