How do I name the type of a method with lifetime where clauses?

Following code won't compile because I don't know what the fn signature should be.

use std::future::Future;

pub trait Call {
    fn call<'result, 'this: 'result>(&'this self) -> Box<dyn Future<Output = ()> + 'result> {
        Box::new(async {})
    }
}

struct A;

impl Call for A {}

fn main() {
    let _: fn(&A) -> Box<dyn Future<Output = ()>> = A::call;
}

If I change the code like this it compiles with HRTB:

use std::future::Future;

pub trait Call {
    fn call<'this>(&'this self) -> Box<dyn Future<Output = ()> + 'this> {
        Box::new(async {})
    }
}

struct A;

impl Call for A {}

fn main() {
    let _: for<'this> fn(&'this A) -> Box<dyn Future<Output = ()> + 'this> = A::call;
}

However the upper one is generated by async_trait so it's not easy to change the signature.

The issue is that lifetimes here are early-bound.

You can fix that by introducing a wrapper function:

// Or just
// fn call(this: &A) -> Box<dyn Future<Output = ()> + '_> {
fn call<'this>(this: &'this A) -> Box<dyn Future<Output = ()> + 'this> {
    A::call(this)
}

fn main() {
    let _: fn(&A) -> Box<dyn Future<Output = ()> + '_> = call;
}
1 Like

Cool! Let me try this in my real project.

It works!