diff --git a/Cargo.toml b/Cargo.toml index 44dad81..836e5c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,5 +24,6 @@ futures-await-await-macro = { path = "futures-await-await-macro", version = "0.1 futures = "0.1" [dev-dependencies] +futures-cpupool = "0.1" tokio-core = "0.1" tokio-io = "0.1" diff --git a/futures-await-async-macro/src/lib.rs b/futures-await-async-macro/src/lib.rs index 5406ed2..65b9c92 100644 --- a/futures-await-async-macro/src/lib.rs +++ b/futures-await-async-macro/src/lib.rs @@ -225,26 +225,31 @@ where F: FnOnce(&Type) -> proc_macro2::TokenStream #[proc_macro_attribute] pub fn async(attribute: TokenStream, function: TokenStream) -> TokenStream { // Handle arguments to the #[async] attribute, if any - let attribute = attribute.to_string(); - let boxed = if attribute == "( boxed )" { - true - } else if attribute == "" { - false - } else { - panic!("the #[async] attribute currently only takes `boxed` as an arg"); + let (boxed, send) = match &attribute.to_string() as &str { + "( boxed )" => (true, false), + "( boxed_send )" => (true, true), + "" => (false, false), + _ => panic!("the #[async] attribute currently only takes `boxed` as an arg"), }; async_inner(boxed, function, quote_cs! { ::futures::__rt::gen }, |output| { // TODO: can we lift the restriction that `futures` must be at the root of // the crate? let output_span = first_last(&output); - let return_ty = if boxed { + let return_ty = if boxed && !send { quote_cs! { ::futures::__rt::std::boxed::Box<::futures::Future< Item = ::Ok, Error = ::Err, >> } + } else if boxed && send { + quote_cs! { + ::futures::__rt::std::boxed::Box<::futures::Future< + Item = ::Ok, + Error = ::Err, + > + Send> + } } else { // Dunno why this is buggy, hits weird typecheck errors in tests // diff --git a/tests/smoke.rs b/tests/smoke.rs index 5453016..a9d7c55 100644 --- a/tests/smoke.rs +++ b/tests/smoke.rs @@ -6,10 +6,12 @@ #![feature(proc_macro, conservative_impl_trait, generators)] extern crate futures_await as futures; +extern crate futures_cpupool; use std::io; use futures::prelude::*; +use futures_cpupool::CpuPool; #[async] fn foo() -> Result { @@ -58,6 +60,11 @@ fn _foo8(a: i32, b: i32) -> Result { return Ok(a + b) } +#[async(boxed_send)] +fn _foo9() -> Result<(), ()> { + Ok(()) +} + #[async] fn _bar() -> Result { await!(foo()) @@ -234,3 +241,9 @@ fn poll_stream_after_error() { assert_eq!(s.poll(), Err(())); assert_eq!(s.poll(), Ok(Async::Ready(None))); } + +#[test] +fn run_boxed_future_in_cpu_pool() { + let pool = CpuPool::new_num_cpus(); + pool.spawn(_foo9()).wait().unwrap(); +}