After thinking about the async fn in traits problem for a while, I've come to the conclusion that the syntax Rust chose for async fn is the wrong one. Specifically, the fact that the returned future type is hidden is quite limiting:
It's quite common to want to bound the Future returned by an async function. Existential types currently leak auto-traits, so an async function might be accidentally Send at first, and made !Send later by changes to the body of the function. We want to be able to require the returned future to be Send or Sync, something that is not possible with the current syntax:
This is especially important when it comes to trait methods, where you might want to require a specific implementation of the trait to be Send in order to be spawned onto a runtime:
How do we express this bound with the current syntax? The async_trait macro chose to add Send requirements by default, allowing you to optout by passing an argument to the macro: