This error occurs because a borrow in a movable coroutine persists across a yield point. Erroneous code example: ```compile_fail,E0626 # #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; let mut b = #[coroutine] || { let a = &String::new(); // <-- This borrow... yield (); // ...is still in scope here, when the yield occurs. println!("{}", a); }; Pin::new(&mut b).resume(()); ``` Coroutines may be either unmarked, or marked with `static`. If it is unmarked, then the coroutine is considered "movable". At present, it is not permitted to have a yield in a movable coroutine that occurs while a borrow is still in scope. To resolve this error, the coroutine may be marked `static`: ``` # #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; let mut b = #[coroutine] static || { // <-- note the static keyword let a = &String::from("hello, world"); yield (); println!("{}", a); }; let mut b = std::pin::pin!(b); b.as_mut().resume(()); ``` If the coroutine must remain movable, for example to be used as `Unpin` without pinning it on the stack or in an allocation, we can alternatively resolve the previous example by removing the borrow and just storing the type by value: ``` # #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; let mut b = #[coroutine] || { let a = String::from("hello, world"); yield (); println!("{}", a); }; Pin::new(&mut b).resume(()); ``` This is a very simple case, of course. In more complex cases, we may wish to have more than one reference to the value that was borrowed -- in those cases, something like the `Rc` or `Arc` types may be useful. This error also frequently arises with iteration: ```compile_fail,E0626 # #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; let mut b = #[coroutine] || { let v = vec![1,2,3]; for &x in &v { // <-- borrow of `v` is still in scope... yield x; // ...when this yield occurs. } }; Pin::new(&mut b).resume(()); ``` Such cases can sometimes be resolved by iterating "by value" (or using `into_iter()`) to avoid borrowing: ``` # #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; let mut b = #[coroutine] || { let v = vec![1,2,3]; for x in v { // <-- Take ownership of the values instead! yield x; // <-- Now yield is OK. } }; Pin::new(&mut b).resume(()); ``` If taking ownership is not an option, using indices can work too: ``` # #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; let mut b = #[coroutine] || { let v = vec![1,2,3]; let len = v.len(); // (*) for i in 0..len { let x = v[i]; // (*) yield x; // <-- Now yield is OK. } }; Pin::new(&mut b).resume(()); // (*) -- Unfortunately, these temporaries are currently required. // See . ```