diff --git a/compiler/rustc_error_codes/src/error_codes/E0626.md b/compiler/rustc_error_codes/src/error_codes/E0626.md index 28d543350ff..71c1f811aa7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0626.md +++ b/compiler/rustc_error_codes/src/error_codes/E0626.md @@ -1,4 +1,4 @@ -This error occurs because a borrow in a coroutine persists across a +This error occurs because a borrow in a movable coroutine persists across a yield point. Erroneous code example: @@ -15,19 +15,35 @@ let mut b = #[coroutine] || { Pin::new(&mut b).resume(()); ``` -At present, it is not permitted to have a yield that occurs while a -borrow is still in scope. To resolve this error, the borrow must -either be "contained" to a smaller scope that does not overlap the -yield or else eliminated in another way. So, for example, we might -resolve the previous example by removing the borrow and just storing -the integer by value: +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 = 3; + let a = String::from("hello, world"); yield (); println!("{}", a); };