fn foo() -> impl Trait {
means "this function returns something that implements the Trait trait, but I'm not gonna tell you what that concrete type is."
This is primarily useful in two cases: first, in an effort for static dispatch, some types can get really long. For example, imagine you wanted to return an iterator of some kind, like this:
foo.iter().map(|x| x + 1).filter(|x| x % 2 == 0)
the type of this is something like
Filter<Map<Iter<'_, {integer}>, [closure@<anon>:2:27: 2:36]>, [closure@<anon>:2:45: 2:59]>
which is pretty gross. First of all, you'll notice the type `Filter<Map<Iter`, as you keep adapting the iterator, you get more types. With iterators it's normally not huge, but if you're using Tokio or Diesel, it can get very bad. Here's a type error I ran into recently with Diesel
https://pbs.twimg.com/media/C6l_OwSXAAA_Fmo.jpg:largeSo, we could write
fn foo() -> impl Iterator<Item=i32> {
and be done, no matter how many adapters we use. In current Rust, you can do this:
fn foo() -> Box<Iterator<Item=i32>> {
but now you've introduced a heap allocation and dynamic dispatch; impl Trait has no allocations and statically dispatches.
The second bit is also present in that type, which is this bit
[closure@<anon>:2:27: 2:36]
Closures have an anonymous type in Rust, and so you cannot write a function that returns a closure without using a Box like above. impl Trait will fix that, by letting you write
fn foo() -> impl Fn(i32) -> i32 {
or whatever the type of the closure is.