Hi
is it possible in Rust to wrap an opaque Future (async block, async fn, multiple concrete Future types) in a concrete Future type?
I need a trait to be dyn compatible but at the same time it should support to be called by async code. Therefore it cannot have async methods or contain generic parameters.
The method itself calls async function/methods which differ between implementations of that trait.
AFAIK by the restrictions of dyn compatibility the trait method must return a concrete type implementing the Future trait. But the issue is, that the wrapped Futures are opaque types and I found no way to pass them to the concrete type without trait objects or generic parameters.
One approach I initially tried was a struct accepting a function pointer retuning a Poll result, but I soon noticed that this can't work since you need to provide a closure capturing the wrapped Future and therefore the closure cannot be coerced to a function pointer.
Is there any known pattern in Rust to achieve this or is it simply impossible without using trait objects currently?
This problem is what the async_trait library is for. It uses Pin<Box<dyn Future>> as the “concrete Future type”, and you can also write this yourself, but async_trait does the transformation for you so that you can use convenient async fn syntax.
This is impossible without using trait objects. Since the trait type is opaque, you can't refer to it directly, and you have to refer to it by trait.
The two ways to use a trait as a real type in Rust are generics (optionally using the impl keyword as syntactic sugar) or trait objects which do dynamic dispatch at compile time.
Unfortunately, as you encountered, you can not use generics in dyn-compatible traits without having to name the type somewhere else, so this approach is currently impossible. That leaves trait objects as the only option.
Each implementation of a future can have a different size depending on the number and of local variables, so it's a physical necessity for there to be some kind of indirection like Box<dyn Trait> to handle the size difference.