AFIT: impl can't add extra lifetime restrictions, unlike non-async · Issue #104689 · rust-lang/rust (original) (raw)

In a non-async trait, the impl is allowed to add a lifetime param that forces the lifetime of the two args to be the same:

trait Trait { fn write(&mut self, words: &[u8]); }

impl Trait for () { fn write<'a>(&'a mut self, words: &'a [u8]) {} }

However, with async traits it's not:

trait Trait { async fn write(&mut self, words: &[u8]); }

impl Trait for () { async fn write<'a>(&'a mut self, words: &'a [u8]) {} }

It results in this error:

error: `impl` item signature doesn't match `trait` item signature
  --> src/lib.rs:22:59
   |
18 |         async fn write(&mut self, words: &[u8]);
   |         ---------------------------------------- expected `fn(&'1 mut (), &'2 [u8]) -> _`
...
22 |         async fn write<'a>(&'a mut self, words: &'a [u8]) {}
   |                                                           ^ found `fn(&'1 mut (), &'1 [u8]) -> impl Future<Output = ()>`
   |
   = note: expected `fn(&'1 mut (), &'2 [u8]) -> _`
              found `fn(&'1 mut (), &'1 [u8]) -> impl Future<Output = ()>`
   = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
   = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output

I arrived at this code by accident. The obvious fix (removing the lifetime param) should always work. (At least, I can't think of any case where you'd explicitly want it). So I don't think this is a big issue, but the inconsistency feels weird so I thought I'd share.

playground
Nightly version: 1.67.0-nightly (2022-11-20 a28f3c8)
@rustbot label F-async_fn_in_trait