GAT: lifetime is inconsistently

I'm getting weird error messages by combining GATs with Async fn Here is an example:

#![feature(generic_associated_types)]
use core::future::{ready, Future};
use core::pin::Pin;

type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

pub trait ExampleTrait: Send + Sync {
    type F<'a>: Future<Output = ()> + Send
    where
        Self: 'a;

    fn example(&self) -> Self::F<'_>;
}

pub struct OtherStruct<ET: ExampleTrait> {
    pub et: ET,
}

pub trait ATrait {
    fn func<'a, ET: ExampleTrait>(&'a self, _os: &'a OtherStruct<ET>) -> BoxFuture<'a, ()> {
        Box::pin(ready(()))
    }
}

struct CallExample {}

impl CallExample {
    pub async fn call_example<ET: ExampleTrait>(&self, os: &OtherStruct<ET>) {
        os.et.example().await;
    }
}

struct AStruct {
    a: CallExample,
}

impl ATrait for AStruct {
    fn func<'a, ET: ExampleTrait>(&'a self, os: &'a OtherStruct<ET>) -> BoxFuture<'a, ()> {
        Box::pin(self.a.call_example(os))
    }
}

fn main() {}

playground

cargo 1.60.0-nightly (25fcb13 2022-02-01)
I get the following error message:

error[E0311]: the parameter type `ET` may not live long enough
  --> src/main.rs:39:9
   |
38 |     fn func<'a, ET: ExampleTrait>(&'a self, os: &'a OtherStruct<ET>) -> BoxFuture<'a, ()> {
   |                 --- help: consider adding an explicit lifetime bound...: `ET: 'a +`
39 |         Box::pin(self.a.call_example(os))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `ET` will meet its required lifetime bounds
1 Like

Here is another similar example:

#![feature(generic_associated_types)]

use core::future::Future;
use std::pin::Pin;

type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

trait ATrait: Sync + Send {
    type T<'a>: Future<Output = ()> + Send + 'a
    where
        Self: 'a;

    fn f(&self) -> Self::T<'_>;
}

fn func1<'a, A: ATrait>(a: &'a A) -> BoxFuture<'a, ()> {
    Box::pin(a.f()) // it works
}

async fn func2<'a, A: ATrait>(a: &'a A) {
    a.f().await // it works
}

fn func3<'a, A: ATrait>(a: &'a A) -> BoxFuture<'a, ()> {
    Box::pin(async { a.f().await }) // error
}

playground

error:

error[E0311]: the parameter type `ET` may not live long enough
  --> src/main.rs:39:9
   |
38 |     fn func<'a, ET: ExampleTrait>(&'a self, os: &'a OtherStruct<ET>) -> BoxFuture<'a, ()> {
   |                 --- help: consider adding an explicit lifetime bound...: `ET: 'a +`
39 |         Box::pin(self.a.call_example(os))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `ET` will meet its required lifetime bounds

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.