3 #![feature(generator_trait, negative_impls)]
5 use std::ops::{Generator, GeneratorState};
6 use std::task::{Poll, Context};
7 use std::future::{Future};
13 #[derive(Debug, Copy, Clone)]
14 pub struct ResumeTy(NonNull<Context<'static>>);
16 unsafe impl Send for ResumeTy {}
18 unsafe impl Sync for ResumeTy {}
20 pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
22 T: Generator<ResumeTy, Yield = ()>,
24 struct GenFuture<T: Generator<ResumeTy, Yield = ()>>(T);
26 // We rely on the fact that async/await futures are immovable in order to create
27 // self-referential borrows in the underlying generator.
28 impl<T: Generator<ResumeTy, Yield = ()>> !Unpin for GenFuture<T> {}
30 impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
31 type Output = T::Return;
32 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
33 // SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection.
34 let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
36 // Resume the generator, turning the `&mut Context` into a `NonNull` raw pointer. The
37 // `.await` lowering will safely cast that back to a `&mut Context`.
38 match gen.resume(ResumeTy(NonNull::from(cx).cast::<Context<'static>>())) {
39 GeneratorState::Yielded(()) => Poll::Pending,
40 GeneratorState::Complete(x) => Poll::Ready(x),