From 015aa8d49a9e222869fe098d0e65e89a0c1a3664 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sun, 25 Mar 2018 12:37:52 +0200 Subject: [PATCH] Update for latest generators changes As of https://github.com/rust-lang/rust/pull/49194 it's now unsafe to resume a generator, but safe to create an immovable generator. Fixes #74 --- futures-await-async-macro/src/lib.rs | 2 +- src/__rt/future.rs | 5 ++++- src/__rt/pinned_future.rs | 4 +++- src/__rt/pinned_stream.rs | 4 +++- src/__rt/stream.rs | 5 ++++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/futures-await-async-macro/src/lib.rs b/futures-await-async-macro/src/lib.rs index 640f4f4..91aa07d 100644 --- a/futures-await-async-macro/src/lib.rs +++ b/futures-await-async-macro/src/lib.rs @@ -206,7 +206,7 @@ where F: FnOnce(&Type, &[&Lifetime]) -> proc_macro2::TokenStream let gen_function = respan(gen_function.into(), &output_span); let body_inner = if pinned { quote_cs! { - #gen_function (#[allow(unused_unsafe)] unsafe { static move || -> #output #gen_body }) + #gen_function (static move || -> #output #gen_body) } } else { quote_cs! { diff --git a/src/__rt/future.rs b/src/__rt/future.rs index 1ebd745..b52ae45 100644 --- a/src/__rt/future.rs +++ b/src/__rt/future.rs @@ -36,7 +36,10 @@ impl Future for GenFuture fn poll(&mut self, ctx: &mut task::Context) -> Poll { CTX.with(|cell| { let _r = Reset::new(ctx, cell); - match self.0.resume() { + // Because we are controlling the creation of our underlying + // generator, we know that this is definitely a movable generator + // so calling resume is always safe. + match unsafe { self.0.resume() } { GeneratorState::Yielded(Async::Pending) => Ok(Async::Pending), GeneratorState::Yielded(Async::Ready(mu)) diff --git a/src/__rt/pinned_future.rs b/src/__rt/pinned_future.rs index 9897369..e69ad02 100644 --- a/src/__rt/pinned_future.rs +++ b/src/__rt/pinned_future.rs @@ -31,7 +31,9 @@ impl StableFuture for GenStableFuture CTX.with(|cell| { let _r = Reset::new(ctx, cell); let this: &mut Self = unsafe { Pin::get_mut(&mut self) }; - match this.0.resume() { + // This is an immovable generator, but since we're only accessing + // it via a Pin this is safe. + match unsafe { this.0.resume() } { GeneratorState::Yielded(Async::Pending) => Ok(Async::Pending), GeneratorState::Yielded(Async::Ready(mu)) diff --git a/src/__rt/pinned_stream.rs b/src/__rt/pinned_stream.rs index 5eb4b43..f5c55a6 100644 --- a/src/__rt/pinned_stream.rs +++ b/src/__rt/pinned_stream.rs @@ -43,7 +43,9 @@ impl StableStream for GenStableStream let _r = Reset::new(ctx, cell); let this: &mut Self = unsafe { Pin::get_mut(&mut self) }; if this.done { return Ok(Async::Ready(None)) } - match this.gen.resume() { + // This is an immovable generator, but since we're only accessing + // it via a Pin this is safe. + match unsafe { this.gen.resume() } { GeneratorState::Yielded(Async::Ready(e)) => { Ok(Async::Ready(Some(e))) } diff --git a/src/__rt/stream.rs b/src/__rt/stream.rs index 0bb807e..b404a29 100644 --- a/src/__rt/stream.rs +++ b/src/__rt/stream.rs @@ -38,7 +38,10 @@ impl Stream for GenStream CTX.with(|cell| { let _r = Reset::new(ctx, cell); if self.done { return Ok(Async::Ready(None)) } - match self.gen.resume() { + // Because we are controlling the creation of our underlying + // generator, we know that this is definitely a movable generator + // so calling resume is always safe. + match unsafe { self.gen.resume() } { GeneratorState::Yielded(Async::Ready(e)) => { Ok(Async::Ready(Some(e))) }