Elided or placeholdered generic lifetimes are not properly respected in trait implementation
- Dominant language
- Rust
- Stars
- 2.2k
- Forks
- 101
- PR merge metrics
- No merged PRs in 30d
Description
Consider the following, where the lifetime for `&` is elided in the trait implementation and a placeholder is used for the generic in the trait:
```rust
#[async_trait::async_trait]
trait Foo<'a>: Sized {
async fn f(bar: &'a usize) -> Self;
}
#[async_trait::async_trait]
impl Foo<'_> for usize {
async fn f(bar: &usize) -> Self {
10
}
}
```
This generates the following implementation:
```rust
impl Foo<'_> for usize {
fn f<'y, 'life0>(bar: &'life0 usize) -> BoxFuture<'y, Self>
where 'life0: 'y, Self: 'y
{
async fn __f(bar: &usize) -> usize { 10 }
Box::pin(__f::<>(bar))
}
}
```
This, of course, does not match the generated trait definition which has only a single lifetime generic in `f`. The "correct" implementation would look like:
```rust
impl<'f> Foo<'f> for usize {
fn f<'y>(bar: &'f usize) -> BoxFuture<'y, Self>
where 'f: 'y, Self: 'y
{
async fn __f(bar: &usize) -> usize { 10 }
Box::pin(__f::<>(bar))
}
}
```
This, of course, would require `async-trait` to know that the placeholdered generic lifetime in the trait corresponds to the elided lifetime in the implementation. In general, it's clear that `async-trait` can't do this as it doesn't have type information nor access to the AST of the definition.
I believe that `async-trait` should likely error when trait generics are placeholdered. At least then the user gets a nice error message as opposed to incorrect code being generated.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.