Identity closure on references

Viewed 78

I have a function that takes a closure. The closure takes a reference and returns any type K:

fn take_closure<T, K>(f: impl FnMut(&T)->K) {/*...*/}

If I call take_closure with an identity function, i.e.

struct S;
fn test() {
    take_closure(|s: &S| s)
}

the compiler complains:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements

I think the problem is that K is one single type, but the closure must work for all lifetimes so that the closure's result must be something like K + '(lifetime of closure parameter).

Specifying that K lives as long as &T does not really help:

fn take_closure<'a, T: 'a + Default, K: 'a>(mut f: impl FnMut(&'a T)->K) {
    let t = Default::default();
    f(&t); // error[E0597]: `t` does not live long enough
}

Thus, I tried higher-rank trait bounds:

fn take_closure<F, T: Default, K>(mut f: F)
    where for<'a> F: FnMut(&'a T)->K // <- (how) can I specify that K: 'a 
{
    let t = Default::default();
    f(&t);
}

#[derive(Default)]
struct S;
fn test() {
    take_closure(|s: &S| s) // error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
}

Is there a way to specify take_closure accordingly? I.e. can I somehow specify that for<'a>, my FnMut(&'a T) produces a K satisfying lifetime 'a?

1 Answers

You can specify when you declare your function that K must not outlive &T:

fn take_closure<'a, T: 'a, K: 'a>(f: impl FnMut(&'a T)->K) {}

struct S;
fn test() {
    take_closure(|s: &S| s)
}
Related