I'm trying to make an async_trait
where some implementations are generic to types with lifetime parameters:
use async_trait::async_trait;
struct MyLifetimeType<'a> {
s: &'a mut String,
}
#[async_trait]
trait MyTrait<T> {
async fn handle(t: T);
}
struct MyImpl;
#[async_trait]
impl<'a> MyTrait<MyLifetimeType<'a>> for MyImpl {
async fn handle(t: MyLifetimeType<'a>) {
t.s.push_str("hi");
}
}
When I try to compile this, I get
error[E0276]: impl has stricter requirements than trait
--> ...
|
18 | async fn handle(t: T);
| ---------------------- definition of `handle` from trait
...
25 | async fn handle(t: MyLifetimeType<'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'async_trait`
It seems that the issue is related to async_trait
somehow using the lifetime parameter 'a
under the hood. When I get rid of all the async
and async_trait
, the code compiles fine. How can I avoid this extra requirement
error?
For more context, to explain why have handlers implementing MyTrait
that can operate on structs containing mutable pointers: I have a function that obtains RwLockReadGuard
s and RwLockWriteGuard
s for a couple different locks, then passes the contents to a handler. For the write guards, I need some way for the handler to mutate contents, so I pass a mutable pointer.
CodePudding user response:
This is a known issue. The author recommends adding an explicit lifetime bound when that error occurs:
use async_trait::async_trait;
struct MyLifetimeType<'a> {
s: &'a mut String,
}
#[async_trait]
trait MyTrait<T> {
async fn handle(&self, t: T) where T: 'async_trait;
}
struct MyImpl;
#[async_trait]
impl<'a> MyTrait<MyLifetimeType<'a>> for MyImpl {
async fn handle(&self, t: MyLifetimeType<'a>) {
t.s.push_str("hi");
}
}