Skip to content

AFIT: impl can't add extra lifetime restrictions, unlike non-async #104689

Description

@Dirbaio

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions