Variant: Async trait
As proposed in https://github.com/Matthias247/rfcs/pull/1, one way to solve this is to introduce a new future trait with an unsafe poll method:
This would then require "bridging impls" to convert the (now likely deprecated, or at least repurposed) Future trait:
which in turn creates an interesting question, since if we wish to have a single combinator that is usable with either trait, specialization would be required:
Bridging
Introduce "bridge impls" like the following:
Newer runtimes will be built atop the Async
trait, but older code will still work with them, since everything that implements Future
implements Async
.
Combinators
One tricky case has to do with bridging combinators. If you have a combinator like Join
:
This combinator cannot then be used with Async
values. You cannot (today) add a second impl like the following for coherence reasons:
The problem is that this second impl creates multiple routes to implement Async
for Join<A, B>
where A
and B
are futures. These routes are of course equivalent, but the compiler doesn't know that.
Solution A: Don't solve it
We might simply introduce new combinators for the Async
trait. Particularly given the move to scoped threads it is likely that the set of combinators would want to change anyhow.
Solution B: Specialization
Specialization can be used to resolve this, and it would be a great feature for Rust overall. However, specialization has a number of challenges to overcome. Some related articles: