'Typing a closure that returns an anonymous type borrowing from one of its inputs without heap allocation or trait objects

Let's say that I have the following working code:

use std::collections::VecDeque;

fn modify<S, F>(state: &mut S, func: F)
where
    F: for<'a> Fn(&'a mut S) -> Box<dyn Iterator<Item = &mut u64> + 'a>
{
    let mut prev = 1;
    for _ in 0..3 {
        for item in func(state) {
            let val = *item;
            *item = val * prev;
            prev = val;
        }
    }
}

fn main() {
    let mut state: VecDeque<u64> = vec![1,2,3,4].into();

    modify(&mut state, |s| Box::new(s.iter_mut()));
    assert_eq!(state, [48, 8, 24, 864]);

    modify(&mut state, |s| Box::new(s.iter_mut().take(2)));
    assert_eq!(state, [147456, 7077888, 24, 864]);

    modify(&mut state, |s| Box::new(s.iter_mut().skip(2)));
    assert_eq!(state, [147456, 7077888, 429981696, 10319560704]);
}

modify takes a function that generates an iterator multiple times from a given state variable (in this case, a VecDeque). This function works, but contains an unnecessary heap allocation as well as unneeded polymorphism in the form of a trait object. I'd very much like to do something like this:

use std::collections::VecDeque;

fn modify<'a, S, F, I>(state: &'a mut S, func: F)
where
    F: Fn(&'a mut S) -> I,
    I: Iterator<Item = &'a mut u64>
{
    let mut prev = 1;
    for _ in 0..3 {
        for item in func(state) {
            let val = *item;
            *item = val * prev;
            prev = val;
        }
    }
}

fn main() {
    let mut state: VecDeque<u64> = vec![1,2,3,4].into();

    modify(&mut state, |s| s.iter_mut());
    assert_eq!(state, [48, 8, 24, 864]);

    modify(&mut state, |s| s.iter_mut().take(2));
    assert_eq!(state, [147456, 7077888, 24, 864]);

    modify(&mut state, |s| s.iter_mut().skip(2));
    assert_eq!(state, [147456, 7077888, 429981696, 10319560704]);
}

But I now get this error:

error[E0499]: cannot borrow `*state` as mutable more than once at a time
  --> src/main.rs:10:26
   |
3  | fn modify<'a, S, F, I>(state: &'a mut S, func: F)
   |           -- lifetime `'a` defined here
...
10 |         for item in func(state) {
   |                     -----^^^^^-
   |                     |    |
   |                     |    `*state` was mutably borrowed here in the previous iteration of the loop
   |                     argument requires that `*state` is borrowed for `'a`

For more information about this error, try `rustc --explain E0499`.

And I can't figure out how to wrangle the borrow checker to do what I want. Any clues would be appreciated. Thanks!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source