Skip to content

Compilation error for lifetimes in associated type used by async-fn-in-trait #102681

Closed

Description

@bryangarza

The following UI test (async-associated-types.rs from #102642) currently does not compile

// edition: 2021

#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]

use std::fmt::Debug;

trait MyTrait<'a, 'b, T> where Self: 'a, T: Debug + Sized + 'b {
    type MyAssoc;

    async fn foo(&'a self, key: &'b T) -> Self::MyAssoc;
}

impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
    type MyAssoc = (&'a U, &'b T);

    async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
        (self, key)
    }
}
//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
//~| ERROR cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements

fn main() {}

I expected to see this happen: successful compilation

Instead, this happened:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> $DIR/async-associated-types.rs:17:43
   |
LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
   |                                           ^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
  --> $DIR/async-associated-types.rs:14:6
   |
LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
   |      ^^
note: ...so that the types are compatible
  --> $DIR/async-associated-types.rs:17:43
   |
LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
   |                                           ^^^^^^^^^^^^^^
   = note: expected `(&'a U, &'b T)`
              found `(&U, &T)`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
  --> $DIR/async-associated-types.rs:17:43
   |
LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
   |                                           ^^^^^^^^^^^^^^
   = note: expected `MyTrait<'static, 'static, T>`
              found `MyTrait<'_, '_, T>`

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
  --> $DIR/async-associated-types.rs:17:43
   |
LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
   |                                           ^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
  --> $DIR/async-associated-types.rs:14:10
   |
LL | impl<'a, 'b, T: Debug + Sized + 'b, U: 'a> MyTrait<'a, 'b, T> for U {
   |          ^^
note: ...so that the types are compatible
  --> $DIR/async-associated-types.rs:17:43
   |
LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
   |                                           ^^^^^^^^^^^^^^
   = note: expected `(&'a U, &'b T)`
              found `(&U, &T)`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
  --> $DIR/async-associated-types.rs:17:43
   |
LL |     async fn foo(&'a self, key: &'b T) -> (&'a U, &'b T) {
   |                                           ^^^^^^^^^^^^^^
   = note: expected `MyTrait<'static, 'static, T>`
              found `MyTrait<'_, '_, T>`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0495`.

Meta

rustc --version --verbose:

rustc 1.66.0-nightly (092255976 2022-10-03)
binary: rustc
commit-hash: 092255976862c1f0121bb4446acd38336a860c4f
commit-date: 2022-10-03
host: x86_64-unknown-linux-gnu
release: 1.66.0-nightly
LLVM version: 15.0.2

Activity

  1. bryangarza commented on Oct 7, 2022

    @bryangarza
    ContributorAuthor

    Dupe of #102682

  2. compiler-errors commented on Oct 24, 2022

    @compiler-errors
    Contributor

    I looked into this a bit more. We should probably be denying associated types in AFITs for now. See the corresponding non-AFIT code:

    #![feature(inherent_associated_types)]
    
    struct Foo<'a>(&'a ());
    
    trait Trait<'a> {
        type Assoc;
    }
    
    impl<'a> Trait<'a> for Foo<'a> {
        type Assoc = ();
    }
    
    impl<'a> Foo<'a> {
        async fn foo() -> <Self as Trait<'a>>::Assoc {}
    }

    Which errors like:

    error[[E0760]](https://doc.rust-lang.org/nightly/error-index.html#E0760): `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
      --> src/lib.rs:12:23
       |
    12 |     async fn foo() -> <Self as Trait<'a>>::Assoc {}
       |                       ^----^^^^^^^^^^^^^^^^^^^^^
       |                        |
       |                        help: consider spelling out the type instead: `Foo<'a>`
    
    error: lifetime may not live long enough
      --> src/lib.rs:12:50
       |
    11 | impl<'a> Foo<'a> {
       |      -- lifetime `'a` defined here
    12 |     async fn foo() -> <Self as Trait<'a>>::Assoc {}
       |                                                  ^^ returning this value requires that `'a` must outlive `'static`
    
    For more information about this error, try `rustc --explain E0760`.
    

    This error exists because of a 'static type hack. #103491 goes into more detail and potentially fixes this, or at least provides a route to fixing this more easily.

  3. cjgillot commented on Nov 27, 2022

    @cjgillot
    Contributor

    The code is now accepted, and the test has been updated.

  4. added a commit that references this issue on Jan 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

C-bugCategory: This is a bug.F-async_fn_in_traitStatic async fn in traits

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions