genawaiter icon indicating copy to clipboard operation
genawaiter copied to clipboard

Is it possible to make a higher-order stack-based producer?

Open mullr opened this issue 4 years ago • 0 comments

I'd like to make a reusable stack-based producer that's parameterized by some value. For example, as a modification of one of the examples from the docs:

use genawaiter::stack::{Co, Gen, Shelf};

pub fn main() {
    let check_numbers_2 = |offset: i32| {
        |co: Co<'_, (), i32>| async move {
            let num = co.yield_(()).await;
            assert_eq!(num, 1 + offset);

            let num = co.yield_(()).await;
            assert_eq!(num, 2 + offset);
        }
    };

    let mut shelf = Shelf::new();
    let mut gen = unsafe { Gen::new(&mut shelf, check_numbers_2(0)) };

    gen.resume_with(0);
    gen.resume_with(1);
    gen.resume_with(2);
}

The trouble with this (I think) is that the stack version of Co has a reference to the Airlock:

error: borrowed data cannot be stored outside of its closure
  --> src/main.rs:5:42
   |
5  |           |co: Co<'_, (), i32>| async move {
   |  _________---------------------____________^
   | |         |
   | |         ...because it cannot outlive this closure
6  | |             let num = co.yield_(()).await;
7  | |             assert_eq!(num, 1 + offset);
8  | |
9  | |             let num = co.yield_(()).await;
10 | |             assert_eq!(num, 2 + offset);
11 | |         }
   | |_________^ cannot be stored outside of its closure
...
15 |       let mut gen = unsafe { Gen::new(&mut shelf, check_numbers_2(0)) };
   |           ------- borrowed data cannot be stored into here...

Is there some other way to go about this, or am I missing some obvious way to plumb the lifetimes through?

mullr avatar May 07 '20 23:05 mullr