Callback lifetime in a generic context (for<'a> F: FnOnce(&'a X) -> Y + 'a)

I would like to have a function that takes a callback, and the callback takes and returns a reference. The problem is, the reference is going to be created inside my function, so I can't declare the lifetime on the function itself.

For a callback that returns a concrete type I can use for<'a> F: FnOnce(&'a X) -> Something<'a>, but the for<'a> syntax doesn't seem to work with generic types. I've tried for<'a> F: FnOnce(&'a X) -> U + 'a and for<'a> F: FnOnce(&'a X) -> U, U: 'a, but neither of them has the meaning I want.

Here's a minimal test case (playground link).

struct ReferenceHolder<'a> {
    pub x: &'a u32,
}

trait NumberMaker {
    fn make(self) -> u32;
}

impl<'a> NumberMaker for ReferenceHolder<'a> {
    fn make(self) -> u32 {
        *self.x
    }
}

fn something_owning_value_by_reference<X, F>(x: X, f: F) -> u32
where
    for<'a> F: FnOnce(&'a X) -> ReferenceHolder<'a>,
{
    f(&x).make()
}

fn something_owning_value_by_reference_generic<X, F, R>(x: X, f: F) -> u32
where
    for<'a> F: FnOnce(&'a X) -> R,
    R: NumberMaker
{
    f(&x).make()
}

fn main() {
    let test = 42u32;
    // this works with concrete type
    println!("{}", something_owning_value_by_reference(test, |x| ReferenceHolder{x: x}));
    // this fails with generic type
    println!("{}", something_owning_value_by_reference_generic(test, |x| ReferenceHolder{x: x}));
}

The actual problem is about async fn callback using the reference, and the generic type is impl Future that needs to reflect that.

This is not possible for the same reason that GAT is needed when returning borrows from traits.

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.