#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
+use std::pin::Pin;
fn main() {
let mut generator = || {
return "foo"
};
- match unsafe { generator.resume() } {
+ match Pin::new(&mut generator).resume() {
GeneratorState::Yielded(1) => {}
_ => panic!("unexpected value from resume"),
}
- match unsafe { generator.resume() } {
+ match Pin::new(&mut generator).resume() {
GeneratorState::Complete("foo") => {}
_ => panic!("unexpected value from resume"),
}
#![feature(generators, generator_trait)]
use std::ops::Generator;
+use std::pin::Pin;
fn main() {
let mut generator = || {
};
println!("1");
- unsafe { generator.resume() };
+ Pin::new(&mut generator).resume();
println!("3");
- unsafe { generator.resume() };
+ Pin::new(&mut generator).resume();
println!("5");
}
```
The `Generator` trait in `std::ops` currently looks like:
```
-# #![feature(generator_trait)]
+# #![feature(arbitrary_self_types, generator_trait)]
# use std::ops::GeneratorState;
+# use std::pin::Pin;
pub trait Generator {
type Yield;
type Return;
- unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
+ fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>;
}
```
generators also depend on variables live across suspension points. This means
that although the ambient environment may be `Send` or `Sync`, the generator
itself may not be due to internal variables live across `yield` points being
- not-`Send` or not-`Sync`. Note that generators, like closures, do
+ not-`Send` or not-`Sync`. Note that generators do
not implement traits like `Copy` or `Clone` automatically.
* Whenever a generator is dropped it will drop all captured environment
#![feature(generators, generator_trait)]
use std::ops::Generator;
+use std::pin::Pin;
fn main() {
let ret = "foo";
return ret
};
- unsafe { generator.resume() };
- unsafe { generator.resume() };
+ Pin::new(&mut generator).resume();
+ Pin::new(&mut generator).resume();
}
```
This generator literal will compile down to something similar to:
```rust
-#![feature(generators, generator_trait)]
+#![feature(arbitrary_self_types, generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
+use std::pin::Pin;
fn main() {
let ret = "foo";
type Yield = i32;
type Return = &'static str;
- unsafe fn resume(&mut self) -> GeneratorState<i32, &'static str> {
+ fn resume(mut self: Pin<&mut Self>) -> GeneratorState<i32, &'static str> {
use std::mem;
- match mem::replace(self, __Generator::Done) {
+ match mem::replace(&mut *self, __Generator::Done) {
__Generator::Start(s) => {
*self = __Generator::Yield1(s);
GeneratorState::Yielded(1)
__Generator::Start(ret)
};
- unsafe { generator.resume() };
- unsafe { generator.resume() };
+ Pin::new(&mut generator).resume();
+ Pin::new(&mut generator).resume();
}
```