genericsrusthigher-rank-types

How to use Higher Rank Trait Bounds with anonymous closure in return type


Is it possible to return FnMut closure that takes reference and return reference with same lifetime as it takes?

fn fun(buf: &mut [f32], mut idx: usize) -> impl FnMut(&[i16]) -> &[i16] {
    |input| {
        buf[idx] = input[0] as f32;
        idx += 1;
        &input[1..]
    }
}

I've tried things like impl for<'a> FnMut(&'a [i16]) -> &'a [i16]) and it gives

error[E0482]: lifetime of return value does not outlive the function call
 --> src/main.rs:1:44
  |
1 | fn fun(buf: &mut [f32], mut idx: usize) -> impl for<'a> FnMut(&'a [i16]) -> &'a [i16] {
  |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: the return value is only valid for the anonymous lifetime defined on the function body at 1:13
 --> src/main.rs:1:13
  |
1 | fn fun(buf: &mut [f32], mut idx: usize) -> impl for<'a> FnMut(&'a [i16]) -> &'a [i16] {
  |             ^^^^^^^^^^

Solution

  • So:

    fn fun<'buf>(buf: &'buf mut [f32], mut idx: usize) -> impl FnMut(&[i16]) -> &[i16] + 'buf {
        move |input| {
            buf[idx] = input[0] as f32;
            idx += 1;
            &input[1..]
        }
    }