Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #80 from Nemo157/update-generators
Browse files Browse the repository at this point in the history
Update to use std pin feature and work with latest rust nightly
  • Loading branch information
boats committed Mar 25, 2018
2 parents 3983f56 + 302d294 commit 9557b87
Show file tree
Hide file tree
Showing 28 changed files with 69 additions and 50 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ sudo: false

script:
- cargo test
- cargo clean
- cargo test --manifest-path testcrate/Cargo.toml

notifications:
Expand Down
4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ members = ["testcrate"]
[dependencies]
futures-await-async-macro = { path = "futures-await-async-macro", version = "0.2.0-alpha" }
futures-await-await-macro = { path = "futures-await-await-macro", version = "0.2.0-alpha" }
futures = "0.2.0-alpha"
futures-stable = "0.2.0-alpha"
pin-api = "0.1.1"
futures = { git = "https://github.com/rust-lang-nursery/futures-rs.git", features = ["nightly"] }
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,22 @@ Otherwise there's a few primary "APIs" provided by this crate:

### Nightly features

Right now this crate requires two nightly features to be used, and practically
requires three features to be used to its fullest extent. These three features
Right now this crate requires three nightly features to be used, and practically
requires four features to be used to its fullest extent. These four features
are:

* `#![feature(generators)]` - this is an experimental language feature that has
yet to be stabilized but is the foundation for the implementation of
async/await. The implemented [landed recently][genpr] and progress on
async/await. The implementation [landed a while ago][genpr] and progress on
stabilization can be found on its [tracking issue][gentrack].

* `#![feature(pin)]` - this is another experimental language feature that works
together with `generators` to provide support for immovable self-referential
generators, without this `async` functions cannot have borrows that exist
across the yield points used inside `await!`. The implementation [landed very
recently][pinpr] and progress on stabilization can be found on its [tracking
issue][pintrack].

* `#![feature(proc_macro)]` - this has also been dubbed "Macros 2.0" and is how
the `#[async]` attribute is defined in this crate and not the compiler itself.
We then also take advantage of other macros 2.0 features like importing macros
Expand All @@ -357,6 +364,8 @@ are:
type of future. This feature is tracked at [#34511] and [#42183].

[gentrack]: https://github.com/rust-lang/rust/issues/43122
[pinpr]: https://github.com/rust-lang/rust/pull/49058
[pintrack]: https://github.com/rust-lang/rust/issues/49150
[#38356]: https://github.com/rust-lang/rust/issues/38356
[#35896]: https://github.com/rust-lang/rust/issues/35896
[#34511]: https://github.com/rust-lang/rust/issues/34511
Expand Down
16 changes: 8 additions & 8 deletions futures-await-async-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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! {
Expand Down Expand Up @@ -252,14 +252,14 @@ pub fn async(attribute: TokenStream, function: TokenStream) -> TokenStream {
let output_span = first_last(&output);
let return_ty = if boxed && !send {
quote_cs! {
::futures::__rt::PinBox<::futures::__rt::Future<
::futures::__rt::boxed::PinBox<::futures::__rt::Future<
Item = <! as ::futures::__rt::IsResult>::Ok,
Error = <! as ::futures::__rt::IsResult>::Err,
>>
}
} else if boxed && send {
quote_cs! {
::futures::__rt::PinBox<::futures::__rt::Future<
::futures::__rt::boxed::PinBox<::futures::__rt::Future<
Item = <! as ::futures::__rt::IsResult>::Ok,
Error = <! as ::futures::__rt::IsResult>::Err,
> + Send>
Expand Down Expand Up @@ -293,14 +293,14 @@ pub fn async_move(attribute: TokenStream, function: TokenStream) -> TokenStream
::futures::__rt::std::boxed::Box<::futures::__rt::Future<
Item = <! as ::futures::__rt::IsResult>::Ok,
Error = <! as ::futures::__rt::IsResult>::Err,
> + ::futures::__rt::pin_api::Unpin + #(#lifetimes +)*>
> + ::futures::__rt::std::marker::Unpin + #(#lifetimes +)*>
}
} else if boxed && send {
quote_cs! {
::futures::__rt::std::boxed::Box<::futures::__rt::Future<
Item = <! as ::futures::__rt::IsResult>::Ok,
Error = <! as ::futures::__rt::IsResult>::Err,
> + ::futures::__rt::pin_api::Unpin + Send + #(#lifetimes +)*>
> + ::futures::__rt::std::marker::Unpin + Send + #(#lifetimes +)*>
}
} else {
// Dunno why this is buggy, hits weird typecheck errors in tests
Expand Down Expand Up @@ -359,7 +359,7 @@ pub fn async_stream(attribute: TokenStream, function: TokenStream) -> TokenStrea
let output_span = first_last(&output);
let return_ty = if boxed {
quote_cs! {
::futures::__rt::PinBox<::futures::__rt::Stream<
::futures::__rt::boxed::PinBox<::futures::__rt::Stream<
Item = !,
Error = <! as ::futures::__rt::IsResult>::Err,
> + #(#lifetimes +)*>
Expand Down Expand Up @@ -416,7 +416,7 @@ pub fn async_stream_move(attribute: TokenStream, function: TokenStream) -> Token
::futures::__rt::std::boxed::Box<::futures::__rt::Stream<
Item = !,
Error = <! as ::futures::__rt::IsResult>::Err,
> + ::futures::__rt::pin_api::Unpin + #(#lifetimes +)*>
> + ::futures::__rt::std::marker::Unpin + #(#lifetimes +)*>
}
} else {
quote_cs! { impl ::futures::__rt::MyStream<!, !> + #(#lifetimes +)* }
Expand Down Expand Up @@ -523,7 +523,7 @@ impl Fold for ExpandAsyncFor {
let #pat = {
let r = {
let pin = unsafe {
::futures::__rt::pin_api::PinMut::new_unchecked(&mut __stream)
::futures::__rt::std::mem::Pin::new_unchecked(&mut __stream)
};
::futures::__rt::in_ctx(|ctx| ::futures::__rt::StableStream::poll_next(pin, ctx))
};
Expand Down
2 changes: 1 addition & 1 deletion futures-await-await-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ macro_rules! await {
loop {
let poll = {
let pin = unsafe {
::futures::__rt::pin_api::PinMut::new_unchecked(&mut future)
::futures::__rt::std::mem::Pin::new_unchecked(&mut future)
};
::futures::__rt::in_ctx(|ctx| ::futures::__rt::StableFuture::poll(pin, ctx))
};
Expand Down
5 changes: 4 additions & 1 deletion src/__rt/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ impl<T> Future for GenFuture<T>
fn poll(&mut self, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error> {
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))
Expand Down
3 changes: 1 addition & 2 deletions src/__rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ pub use self::pinned_future::*;
pub use self::pinned_stream::*;

pub use futures::prelude::{Async, Future, Stream};
pub use stable::{StableFuture, StableStream};
pub use futures::stable::{StableFuture, StableStream};

pub extern crate std;
pub extern crate pin_api;

pub use std::ops::Generator;

Expand Down
14 changes: 8 additions & 6 deletions src/__rt/pinned_future.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::marker::Unpin;
use std::mem::Pin;
use std::ops::{Generator, GeneratorState};

use __rt::pin_api::{PinMut, Unpin};

use super::{IsResult, Reset, CTX};

use futures::Never;
use stable::StableFuture;
use futures::stable::StableFuture;
use task;
use prelude::{Poll, Async};

Expand All @@ -27,11 +27,13 @@ impl<T> StableFuture for GenStableFuture<T>
type Item = <T::Return as IsResult>::Ok;
type Error = <T::Return as IsResult>::Err;

fn poll(mut self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error> {
fn poll(mut self: Pin<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error> {
CTX.with(|cell| {
let _r = Reset::new(ctx, cell);
let this: &mut Self = unsafe { PinMut::get_mut(&mut self) };
match this.0.resume() {
let this: &mut Self = unsafe { Pin::get_mut(&mut self) };
// 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))
Expand Down
14 changes: 8 additions & 6 deletions src/__rt/pinned_stream.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::mem::Pin;
use std::ops::{Generator, GeneratorState};
use std::marker::PhantomData;
use std::marker::{PhantomData, Unpin};

use __rt::pin_api::{PinMut, Unpin};
use futures::task;
use futures::prelude::{Poll, Async};
use stable::StableStream;
use futures::stable::StableStream;

use super::{CTX, Reset, IsResult};

Expand Down Expand Up @@ -38,12 +38,14 @@ impl<U, T> StableStream for GenStableStream<U, T>
type Item = U;
type Error = <T::Return as IsResult>::Err;

fn poll_next(mut self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
fn poll_next(mut self: Pin<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
CTX.with(|cell| {
let _r = Reset::new(ctx, cell);
let this: &mut Self = unsafe { PinMut::get_mut(&mut self) };
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)))
}
Expand Down
5 changes: 4 additions & 1 deletion src/__rt/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ impl<U, T> Stream for GenStream<U, T>
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)))
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
#![feature(on_unimplemented)]
#![feature(arbitrary_self_types)]
#![feature(optin_builtin_traits)]
#![feature(pin)]

extern crate futures_await_async_macro as async_macro;
extern crate futures_await_await_macro as await_macro;
extern crate futures;
pub extern crate futures_stable as stable;

pub use futures::*;

Expand Down
2 changes: 1 addition & 1 deletion testcrate/ui/bad-return-type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
4 changes: 2 additions & 2 deletions testcrate/ui/bad-return-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,5 @@ error[E0308]: mismatched types

error: aborting due to 7 previous errors

You've got a few errors: E0308, E0907
If you want more information on an error, try using "rustc --explain E0308"
Some errors occurred: E0308, E0907.
For more information about an error, try `rustc --explain E0308`.
2 changes: 1 addition & 1 deletion testcrate/ui/forget-ok.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 1 addition & 1 deletion testcrate/ui/forget-ok.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ error[E0308]: mismatched types

error: aborting due to 2 previous errors

If you want more information on this error, try using "rustc --explain E0308"
For more information about this error, try `rustc --explain E0308`.
2 changes: 1 addition & 1 deletion testcrate/ui/missing-item.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(warnings)]
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 2 additions & 0 deletions testcrate/ui/missing-item.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ error: custom attribute panicked
|
= help: message: #[async_stream] requires item type to be specified

error: aborting due to previous error

2 changes: 1 addition & 1 deletion testcrate/ui/move-captured-variable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 1 addition & 1 deletion testcrate/ui/move-captured-variable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ error[E0507]: cannot move out of captured outer variable in an `FnMut` closure

error: aborting due to previous error

If you want more information on this error, try using "rustc --explain E0507"
For more information about this error, try `rustc --explain E0507`.
2 changes: 1 addition & 1 deletion testcrate/ui/not-a-result.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 1 addition & 1 deletion testcrate/ui/not-a-result.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ error[E0277]: the trait bound `u32: futures::__rt::IsResult` is not satisfied

error: aborting due to 6 previous errors

If you want more information on this error, try using "rustc --explain E0277"
For more information about this error, try `rustc --explain E0277`.
2 changes: 1 addition & 1 deletion testcrate/ui/type_error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 1 addition & 1 deletion testcrate/ui/type_error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ error[E0308]: mismatched types

error: aborting due to previous error

If you want more information on this error, try using "rustc --explain E0308"
For more information about this error, try `rustc --explain E0308`.
2 changes: 1 addition & 1 deletion testcrate/ui/unresolved-type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down
4 changes: 2 additions & 2 deletions testcrate/ui/unresolved-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ note: the type is part of the generator because of this `yield`

error: aborting due to 3 previous errors

You've got a few errors: E0412, E0907
If you want more information on an error, try using "rustc --explain E0412"
Some errors occurred: E0412, E0907.
For more information about an error, try `rustc --explain E0412`.
2 changes: 1 addition & 1 deletion tests/elisions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators, underscore_lifetimes)]
#![feature(proc_macro, conservative_impl_trait, generators, underscore_lifetimes, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 1 addition & 1 deletion tests/pinned.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, conservative_impl_trait, generators, underscore_lifetimes)]
#![feature(proc_macro, conservative_impl_trait, generators, underscore_lifetimes, pin)]

extern crate futures_await as futures;

Expand Down
2 changes: 1 addition & 1 deletion tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! This is mostly a test f r this repository itself, not necessarily serving
//! much more purpose than that.

#![feature(proc_macro, conservative_impl_trait, generators)]
#![feature(proc_macro, conservative_impl_trait, generators, pin)]

extern crate futures_await as futures;

Expand Down

0 comments on commit 9557b87

Please sign in to comment.