dyn real_async_trait?
Opened this issue · 2 comments
Is there a way to make a dyn Trait
object out of a type that impls a trait annotated with #[real_async_trait]
?
I'd like to be able to do something like:
#[real_async_trait]
trait Foo {
async fn foo();
}
struct Bar {
maybe_foo: Option<Box<dyn Foo>>,
}
When I try to do this, however, I get an error saying I need to specify the associated type for Foo::foo
.
Well, since every implementation gets its own future types, no real-async-trait
traits are object safe unless you box the futures, which you cannot guarantee every implementation will do. It should in theory be possible to require that the futures be boxed when creating an async trait object and hence be the same size and thereby object safe (like the regular async-trait
crate does), but it's nontrivial and we might have to wait for the language to implement async traits first. Or, we can manually generate code for both an object safe trait and a regular trait, and then implement the regular trait for types which already implement the object safe trait. But AFAIK the only way now to make dyn async traits is to use async-trait
.
We could probably do this by having real_async_trait
generate a bridge trait, although perhaps opt-in with something like #[real_async_trait(dyn)]
. In my example, we'd generate something like this to go with it:
trait DynFoo {
fn foo(&self) -> Box<dyn Future<Output = ()>>;
}
impl<T: Foo> DynFoo for T {
fn foo(&self) -> Box<dyn Future<Output = ()>> {
Box::new(<Self as Foo>::foo(self))
}
}
Although until there's more language support if you need this then using async-trait
is probably the best option.