diff --git a/futures-core/src/future/mod.rs b/futures-core/src/future.rs similarity index 50% rename from futures-core/src/future/mod.rs rename to futures-core/src/future.rs index d705a91179..5ce47bf242 100644 --- a/futures-core/src/future/mod.rs +++ b/futures-core/src/future.rs @@ -1,27 +1,9 @@ //! Futures. use crate::task::{self, Poll}; -use core::marker::Unpin; use core::mem::PinMut; -pub use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj}; - -mod option; -pub use self::option::FutureOption; - -#[cfg(feature = "either")] -mod either; - -/// Will probably merge with futures_util::FutureExt -pub trait CoreFutureExt: Future { - /// A convenience for calling `Future::poll` on `Unpin` future types. - fn poll_unpin(&mut self, cx: &mut task::Context) -> Poll - where Self: Unpin + Sized - { - PinMut::new(self).poll(cx) - } -} -impl CoreFutureExt for T where T: Future {} +pub use core::future::{Future, FutureObj, LocalFutureObj, UnsafeFutureObj}; /// A convenience for futures that return `Result` values that includes /// a variety of adapters tailored to such futures. @@ -54,24 +36,3 @@ impl TryFuture for F self.poll(cx) } } - -/// A future that is immediately ready with a value -#[derive(Debug, Clone)] -#[must_use = "futures do nothing unless polled"] -pub struct ReadyFuture(Option); - -impl Unpin for ReadyFuture {} - -impl Future for ReadyFuture { - type Output = T; - - #[inline] - fn poll(mut self: PinMut, _cx: &mut task::Context) -> Poll { - Poll::Ready(self.0.take().unwrap()) - } -} - -/// Create a future that is immediately ready with a value. -pub fn ready(t: T) -> ReadyFuture { - ReadyFuture(Some(t)) -} diff --git a/futures-core/src/future/either.rs b/futures-core/src/future/either.rs deleted file mode 100644 index 0104b794fa..0000000000 --- a/futures-core/src/future/either.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::stream::{Stream}; -use crate::task::{self, Poll}; -use core::mem::PinMut; -use either::Either; - -// impl Future for Either -// where A: Future, -// B: Future -// { -// type Output = A::Output; - -// fn poll(self: PinMut, cx: &mut task::Context) -> Poll { -// unsafe { -// match PinMut::get_mut(self) { -// Either::Left(a) => PinMut::new_unchecked(a).poll(cx), -// Either::Right(b) => PinMut::new_unchecked(b).poll(cx), -// } -// } -// } -// } - -impl Stream for Either - where A: Stream, - B: Stream -{ - type Item = A::Item; - - fn poll_next(self: PinMut, cx: &mut task::Context) -> Poll> { - unsafe { - match PinMut::get_mut_unchecked(self) { - Either::Left(a) => PinMut::new_unchecked(a).poll_next(cx), - Either::Right(b) => PinMut::new_unchecked(b).poll_next(cx), - } - } - } -} diff --git a/futures-core/src/future/option.rs b/futures-core/src/future/option.rs deleted file mode 100644 index 93d71a639b..0000000000 --- a/futures-core/src/future/option.rs +++ /dev/null @@ -1,35 +0,0 @@ -//! Definition of the `Option` (optional step) combinator - -use crate::future::Future; -use crate::task::{self, Poll}; -use core::mem::PinMut; - -/// A future representing a value which may or may not be present. -/// -/// Created by the `IntoFuture` implementation for `std::option::Option`. -#[derive(Debug, Clone)] -#[must_use = "futures do nothing unless polled"] -pub struct FutureOption { - option: Option, -} - -impl FutureOption { - unsafe_pinned!(option: Option); -} - -impl Future for FutureOption { - type Output = Option; - - fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll { - match self.option().as_pin_mut() { - Some(x) => x.poll(cx).map(Some), - None => Poll::Ready(None), - } - } -} - -impl From> for FutureOption { - fn from(option: Option) -> Self { - FutureOption { option } - } -} diff --git a/futures-core/src/lib.rs b/futures-core/src/lib.rs index 924dcbeb4c..136ca069d1 100644 --- a/futures-core/src/lib.rs +++ b/futures-core/src/lib.rs @@ -11,19 +11,13 @@ #![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] -#[macro_use] #[cfg(feature = "std")] extern crate std; + #[cfg(feature = "either")] extern crate either; -#[doc(hidden)] -pub mod core_reexport { - pub use core::{mem, future, task}; -} - #[doc(hidden)] pub use crate::future::Future; -#[doc(hidden)] pub use crate::future::CoreFutureExt; #[doc(hidden)] pub use crate::future::TryFuture; #[doc(hidden)] pub use crate::stream::Stream; @@ -38,9 +32,6 @@ macro_rules! if_std { )*) } -#[macro_use] -mod macros; - pub mod future; pub mod stream; diff --git a/futures-core/src/macros/poll.rs b/futures-core/src/macros/poll.rs deleted file mode 100644 index fcc97cd4de..0000000000 --- a/futures-core/src/macros/poll.rs +++ /dev/null @@ -1,40 +0,0 @@ -/// Extracts the successful type of a `Poll>`. -/// -/// This macro bakes in propagation of `Pending` and `Err` signals by returning early. -#[macro_export] -macro_rules! try_ready { - ($x:expr) => { - match $x { - $crate::task::Poll::Ready(Ok(x)) => x, - $crate::task::Poll::Ready(Err(e)) => return $crate::task::Poll::Ready(Err(e.into())), - $crate::task::Poll::Pending => return $crate::task::Poll::Pending, - } - } -} - - -/// Extracts `Poll` from `Poll>`. -/// -/// This macro bakes in propagation of `Err` signals by returning early. -/// This macro bakes in propagation of `Pending` and `Err` signals by returning early. -#[macro_export] -macro_rules! try_poll { - ($x:expr) => { - match $x { - $crate::task::Poll::Ready(Ok(x)) => $crate::task::Poll::Ready(x), - $crate::task::Poll::Ready(Err(e)) => return $crate::task::Poll::Ready(Err(e.into())), - $crate::task::Poll::Pending => $crate::task::Poll::Pending, - } - } -} - -/// Extracts the successful type of a `Poll`. -/// -/// This macro bakes in propagation of `Pending` signals by returning early. -#[macro_export] -macro_rules! ready { - ($e:expr) => (match $e { - $crate::task::Poll::Ready(t) => t, - $crate::task::Poll::Pending => return $crate::task::Poll::Pending, - }) -} diff --git a/futures-core/src/stream/mod.rs b/futures-core/src/stream.rs similarity index 90% rename from futures-core/src/stream/mod.rs rename to futures-core/src/stream.rs index 5846e389c9..7f638ebde8 100644 --- a/futures-core/src/stream/mod.rs +++ b/futures-core/src/stream.rs @@ -4,6 +4,9 @@ use crate::task::{self, Poll}; use core::marker::Unpin; use core::mem::PinMut; +#[cfg(feature = "either")] +use either::Either; + /// A stream of values produced asynchronously. /// /// If `Future` is an asynchronous version of `T`, then `Stream Stream for PinMut<'a, S> { } } +#[cfg(feature = "either")] +impl Stream for Either + where A: Stream, + B: Stream +{ + type Item = A::Item; + + fn poll_next(self: PinMut, cx: &mut task::Context) -> Poll> { + unsafe { + match PinMut::get_mut_unchecked(self) { + Either::Left(a) => PinMut::new_unchecked(a).poll_next(cx), + Either::Right(b) => PinMut::new_unchecked(b).poll_next(cx), + } + } + } +} + /// A convenience for streams that return `Result` values that includes /// a variety of adapters tailored to such futures. pub trait TryStream { diff --git a/futures-core/src/task.rs b/futures-core/src/task.rs new file mode 100644 index 0000000000..6c10a68e61 --- /dev/null +++ b/futures-core/src/task.rs @@ -0,0 +1,11 @@ +//! Task notification. + +pub use core::task::{ + Context, Poll, Executor, + Waker, LocalWaker, UnsafeWake, + SpawnErrorKind, SpawnObjError, SpawnLocalObjError, +}; + +if_std! { + pub use std::task::{Wake, local_waker, local_waker_from_nonlocal}; +} diff --git a/futures-core/src/task/mod.rs b/futures-core/src/task/mod.rs deleted file mode 100644 index e04f30b7ae..0000000000 --- a/futures-core/src/task/mod.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Task notification. - -pub use core::task::{ - Context, Executor, Poll, - Waker, LocalWaker, UnsafeWake, - SpawnErrorKind, SpawnObjError, SpawnLocalObjError, -}; -pub use core::future::FutureObj; - -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] -mod atomic_waker; -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] -pub use self::atomic_waker::AtomicWaker; - -if_std! { - use crate::future::Future; - use std::boxed::PinBox; - - pub use std::task::{Wake, local_waker, local_waker_from_nonlocal}; - - /// Extension trait for `Context`, adding methods that require allocation. - pub trait ContextExt { - /// Spawn a future onto the default executor. - /// - /// # Panics - /// - /// This method will panic if the default executor is unable to spawn. - /// - /// To handle executor errors, use `Context::executor()` on instead. - fn spawn(&mut self, f: F) where F: Future + 'static + Send; - } - - impl<'a> ContextExt for Context<'a> { - fn spawn(&mut self, f: F) where F: Future + 'static + Send { - self.executor() - .spawn_obj(FutureObj::new(PinBox::new(f))).unwrap() - } - } -} diff --git a/futures-executor/src/lib.rs b/futures-executor/src/lib.rs index f9f4b57b64..ddca3ac05f 100644 --- a/futures-executor/src/lib.rs +++ b/futures-executor/src/lib.rs @@ -13,8 +13,9 @@ #[macro_use] extern crate std; -#[cfg_attr(feature = "std", macro_use)] -extern crate futures_core; +#[cfg(feature = "std")] +#[macro_use] +extern crate futures_util; macro_rules! if_std { ($($i:item)*) => ($( diff --git a/futures-executor/src/spawn.rs b/futures-executor/src/spawn.rs index 37facef158..9b0b442a48 100644 --- a/futures-executor/src/spawn.rs +++ b/futures-executor/src/spawn.rs @@ -1,8 +1,8 @@ -use futures_core::future::{Future, CoreFutureExt}; -use futures_core::task::{self, Poll, ContextExt}; +use futures_core::future::Future; +use futures_core::task::{self, Poll}; use futures_channel::oneshot::{channel, Sender, Receiver}; -use futures_util::FutureExt; - +use futures_util::future::FutureExt; +use futures_util::task::ContextExt; use std::thread; use std::sync::Arc; use std::sync::atomic::Ordering; diff --git a/futures-executor/src/thread_pool.rs b/futures-executor/src/thread_pool.rs index 4f9d2a34dd..aa1015b98f 100644 --- a/futures-executor/src/thread_pool.rs +++ b/futures-executor/src/thread_pool.rs @@ -1,19 +1,17 @@ -use std::prelude::v1::*; - +use crate::enter; +use crate::unpark_mutex::UnparkMutex; +use futures_core::future::{Future, FutureObj}; +use futures_core::task::{self, Poll, Wake, Executor, SpawnObjError}; +use futures_util::future::FutureExt; +use num_cpus; use std::io; +use std::prelude::v1::*; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc; use std::thread; use std::fmt; -use futures_core::future::{Future, FutureObj, CoreFutureExt}; -use futures_core::task::{self, Poll, Wake, Executor, SpawnObjError}; - -use crate::enter; -use num_cpus; -use crate::unpark_mutex::UnparkMutex; - /// A general-purpose thread pool for scheduling asynchronous tasks. /// /// The thread pool multiplexes any number of tasks onto a fixed number of diff --git a/futures-util/src/future/mod.rs b/futures-util/src/future/mod.rs index 3c99ad170d..1015481e7a 100644 --- a/futures-util/src/future/mod.rs +++ b/futures-util/src/future/mod.rs @@ -3,9 +3,11 @@ //! This module contains a number of functions for working with `Future`s, //! including the `FutureExt` trait which adds methods to `Future` types. +use core::marker::Unpin; +use core::mem::PinMut; use futures_core::future::Future; use futures_core::stream::Stream; -use futures_core::task::Executor; +use futures_core::task::{self, Poll, Executor}; // Primitive futures mod empty; @@ -17,9 +19,15 @@ pub use self::lazy::{lazy, Lazy}; mod maybe_done; pub use self::maybe_done::{maybe_done, MaybeDone}; +mod option; +pub use self::option::{OptionFuture}; + mod poll_fn; pub use self::poll_fn::{poll_fn, PollFn}; +mod ready; +pub use self::ready::{ready, Ready}; + // Combinators mod flatten; pub use self::flatten::Flatten; @@ -506,14 +514,14 @@ pub trait FutureExt: Future { /// ```rust /// # extern crate futures; /// use futures::prelude::*; - /// use futures::future::{self, ReadyFuture}; + /// use futures::future::{self, Ready}; /// use futures::executor::block_on; /// /// # fn main() { /// let mut future = future::ready(2); /// assert!(block_on(future.catch_unwind()).is_ok()); /// - /// let mut future = future::lazy(|_| -> ReadyFuture { + /// let mut future = future::lazy(|_| -> Ready { /// panic!(); /// future::ready(2) /// }); @@ -606,6 +614,13 @@ pub trait FutureExt: Future { { WithExecutor::new(self, executor) } + + /// A convenience for calling `Future::poll` on `Unpin` future types. + fn poll_unpin(&mut self, cx: &mut task::Context) -> Poll + where Self: Unpin + Sized + { + PinMut::new(self).poll(cx) + } } // Just a helper function to ensure the futures we're returning all have the diff --git a/futures-util/src/future/option.rs b/futures-util/src/future/option.rs new file mode 100644 index 0000000000..e0c8f444e2 --- /dev/null +++ b/futures-util/src/future/option.rs @@ -0,0 +1,46 @@ +//! Definition of the `Option` (optional step) combinator + +use futures_core::future::Future; +use futures_core::task::{self, Poll}; +use core::mem::PinMut; + +/// A future representing a value which may or may not be present. +/// +/// Created by the `From` implementation for `std::option::Option`. +/// +/// ``` +/// # extern crate futures; +/// use futures::prelude::*; +/// use futures::future::OptionFuture; +/// +/// let fut: OptionFuture<_> = Some(123).into(); +/// ``` +#[derive(Debug, Clone)] +#[must_use = "futures do nothing unless polled"] +pub struct OptionFuture { + option: Option, +} + +impl OptionFuture { + unsafe_pinned!(option: Option); +} + +impl Future for OptionFuture { + type Output = Option; + + fn poll( + mut self: PinMut, + cx: &mut task::Context + ) -> Poll { + match self.option().as_pin_mut() { + Some(x) => x.poll(cx).map(Some), + None => Poll::Ready(None), + } + } +} + +impl From> for OptionFuture { + fn from(option: Option) -> Self { + OptionFuture { option } + } +} diff --git a/futures-util/src/future/ready.rs b/futures-util/src/future/ready.rs new file mode 100644 index 0000000000..dbae7beb4c --- /dev/null +++ b/futures-util/src/future/ready.rs @@ -0,0 +1,25 @@ +use core::marker::Unpin; +use core::mem::PinMut; +use futures_core::future::Future; +use futures_core::task::{self, Poll}; + +/// A future that is immediately ready with a value +#[derive(Debug, Clone)] +#[must_use = "futures do nothing unless polled"] +pub struct Ready(Option); + +impl Unpin for Ready {} + +impl Future for Ready { + type Output = T; + + #[inline] + fn poll(mut self: PinMut, _cx: &mut task::Context) -> Poll { + Poll::Ready(self.0.take().unwrap()) + } +} + +/// Create a future that is immediately ready with a value. +pub fn ready(t: T) -> Ready { + Ready(Some(t)) +} diff --git a/futures-util/src/lib.rs b/futures-util/src/lib.rs index de128c3b17..3f263507b5 100644 --- a/futures-util/src/lib.rs +++ b/futures-util/src/lib.rs @@ -10,7 +10,7 @@ #![doc(html_root_url = "https://docs.rs/futures-util/0.3.0-alpha")] #[macro_use] -extern crate futures_core; +mod macros; macro_rules! if_std { ($($i:item)*) => ($( @@ -20,7 +20,9 @@ macro_rules! if_std { } #[doc(hidden)] -pub use futures_core::core_reexport; +pub mod core_reexport { + pub use core::{mem, marker, future, task}; +} macro_rules! delegate_sink { ($field:ident) => { @@ -55,26 +57,29 @@ macro_rules! delegate_sink { } pub mod future; -pub use crate::future::FutureExt; +#[doc(hidden)] pub use crate::future::FutureExt; pub mod try_future; -pub use crate::try_future::TryFutureExt; +#[doc(hidden)] pub use crate::try_future::TryFutureExt; pub mod stream; -pub use crate::stream::StreamExt; +#[doc(hidden)] pub use crate::stream::StreamExt; pub mod try_stream; -pub use crate::try_stream::TryStreamExt; +#[doc(hidden)] pub use crate::try_stream::TryStreamExt; pub mod sink; -pub use crate::sink::SinkExt; +#[doc(hidden)] pub use crate::sink::SinkExt; + +pub mod task; if_std! { // FIXME: currently async/await is only available with std pub mod async_await; pub mod io; - pub use crate::io::{AsyncReadExt, AsyncWriteExt}; + #[doc(hidden)] pub use crate::io::{AsyncReadExt, AsyncWriteExt}; + #[cfg(any(test, feature = "bench"))] pub mod lock; #[cfg(not(any(test, feature = "bench")))] diff --git a/futures-core/src/macros/mod.rs b/futures-util/src/macros/mod.rs similarity index 100% rename from futures-core/src/macros/mod.rs rename to futures-util/src/macros/mod.rs diff --git a/futures-core/src/macros/pin.rs b/futures-util/src/macros/pin.rs similarity index 94% rename from futures-core/src/macros/pin.rs rename to futures-util/src/macros/pin.rs index 66c3d261e8..d6b160b4ff 100644 --- a/futures-core/src/macros/pin.rs +++ b/futures-util/src/macros/pin.rs @@ -7,7 +7,7 @@ /// /// ``` /// # #![feature(pin, arbitrary_self_types)] -/// # #[macro_use] extern crate futures_core; +/// # #[macro_use] extern crate futures; /// # use core::mem::PinMut; /// # use core::marker::Unpin; /// struct Foo { @@ -25,7 +25,7 @@ /// impl Unpin for Foo {}; // Conditional Unpin impl /// ``` /// -/// [`Unpin`]: core::mem::Unpin +/// [`Unpin`]: std::marker::Unpin /// [`drop`]: Drop::drop #[macro_export] macro_rules! unsafe_pinned { @@ -51,7 +51,7 @@ macro_rules! unsafe_pinned { /// /// ``` /// # #![feature(pin, arbitrary_self_types)] -/// # #[macro_use] extern crate futures_core; +/// # #[macro_use] extern crate futures; /// # use core::mem::PinMut; /// # struct Bar; /// struct Foo { @@ -85,7 +85,7 @@ macro_rules! unsafe_unpinned { /// /// ``` /// # #![feature(pin, arbitrary_self_types)] -/// # #[macro_use] extern crate futures_core; +/// # #[macro_use] extern crate futures; /// # use core::mem::PinMut; /// # struct Foo {} /// let foo = Foo { /* ... */ }; diff --git a/futures-util/src/macros/poll.rs b/futures-util/src/macros/poll.rs new file mode 100644 index 0000000000..df5a588661 --- /dev/null +++ b/futures-util/src/macros/poll.rs @@ -0,0 +1,46 @@ +/// Extracts the successful type of a `Poll>`. +/// +/// This macro bakes in propagation of `Pending` and `Err` signals by returning early. +#[macro_export] +macro_rules! try_ready { + ($x:expr) => { + match $x { + $crate::core_reexport::task::Poll::Ready(Ok(x)) => x, + $crate::core_reexport::task::Poll::Ready(Err(e)) => + return $crate::core_reexport::task::Poll::Ready(Err(e.into())), + $crate::core_reexport::task::Poll::Pending => + return $crate::core_reexport::task::Poll::Pending, + } + } +} + + +/// Extracts `Poll` from `Poll>`. +/// +/// This macro bakes in propagation of `Err` signals by returning early. +/// This macro bakes in propagation of `Pending` and `Err` signals by returning early. +#[macro_export] +macro_rules! try_poll { + ($x:expr) => { + match $x { + $crate::core_reexport::task::Poll::Ready(Ok(x)) => + $crate::core_reexport::task::Poll::Ready(x), + $crate::core_reexport::task::Poll::Ready(Err(e)) => + return $crate::core_reexport::task::Poll::Ready(Err(e.into())), + $crate::core_reexport::task::Poll::Pending => + $crate::core_reexport::task::Poll::Pending, + } + } +} + +/// Extracts the successful type of a `Poll`. +/// +/// This macro bakes in propagation of `Pending` signals by returning early. +#[macro_export] +macro_rules! ready { + ($e:expr) => (match $e { + $crate::core_reexport::task::Poll::Ready(t) => t, + $crate::core_reexport::task::Poll::Pending => + return $crate::core_reexport::task::Poll::Pending, + }) +} diff --git a/futures-util/src/stream/futures_unordered/mod.rs b/futures-util/src/stream/futures_unordered/mod.rs index 2e3b55fedb..8ad9d5dd01 100644 --- a/futures-util/src/stream/futures_unordered/mod.rs +++ b/futures-util/src/stream/futures_unordered/mod.rs @@ -1,8 +1,9 @@ //! An unbounded set of futures. +use crate::task::AtomicWaker; use futures_core::future::Future; use futures_core::stream::Stream; -use futures_core::task::{self, Poll, AtomicWaker}; +use futures_core::task::{self, Poll}; use std::cell::UnsafeCell; use std::fmt::{self, Debug}; use std::iter::FromIterator; diff --git a/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs b/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs index b97d046b01..7a2cc7b3f0 100644 --- a/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs +++ b/futures-util/src/stream/futures_unordered/ready_to_run_queue.rs @@ -1,11 +1,10 @@ +use crate::task::AtomicWaker; use std::cell::UnsafeCell; use std::ptr; use std::sync::Arc; use std::sync::atomic::AtomicPtr; use std::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel}; -use futures_core::task::AtomicWaker; - use super::abort::abort; use super::node::Node; diff --git a/futures-core/src/task/atomic_waker.rs b/futures-util/src/task/atomic_waker.rs similarity index 99% rename from futures-core/src/task/atomic_waker.rs rename to futures-util/src/task/atomic_waker.rs index 11a632a250..7c9e00dc76 100755 --- a/futures-core/src/task/atomic_waker.rs +++ b/futures-util/src/task/atomic_waker.rs @@ -2,8 +2,7 @@ use core::fmt; use core::cell::UnsafeCell; use core::sync::atomic::AtomicUsize; use core::sync::atomic::Ordering::{Acquire, Release, AcqRel}; - -use crate::task::Waker; +use futures_core::task::Waker; /// A synchronization primitive for task wakeup. /// @@ -172,7 +171,8 @@ impl AtomicWaker { /// ``` /// # #![feature(pin, arbitrary_self_types, futures_api)] /// # use futures_core::future::Future; - /// # use futures_core::task::{self, Poll, AtomicWaker}; + /// # use futures_core::task::{self, Poll}; + /// # use futures_util::task::AtomicWaker; /// # use std::sync::atomic::AtomicBool; /// # use std::sync::atomic::Ordering::SeqCst; /// # use std::mem::PinMut; diff --git a/futures-util/src/task/context.rs b/futures-util/src/task/context.rs new file mode 100644 index 0000000000..595cd67668 --- /dev/null +++ b/futures-util/src/task/context.rs @@ -0,0 +1,29 @@ +use futures_core::task; + +if_std! { + use futures_core::future::{Future, FutureObj}; + use std::boxed::Box; +} + +/// Extension trait for `Context`, adding methods that require allocation. +pub trait ContextExt { + /// Spawn a future onto the default executor. + /// + /// # Panics + /// + /// This method will panic if the default executor is unable to spawn. + /// + /// To handle executor errors, use `Context::executor()` on instead. + #[cfg(feature = "std")] + fn spawn(&mut self, future: Fut) + where Fut: Future + 'static + Send; +} + +impl<'a> ContextExt for task::Context<'a> { + #[cfg(feature = "std")] + fn spawn(&mut self, future: Fut) + where Fut: Future + 'static + Send + { + self.executor().spawn_obj(FutureObj::new(Box::new(future))).unwrap() + } +} diff --git a/futures-util/src/task/mod.rs b/futures-util/src/task/mod.rs new file mode 100644 index 0000000000..f6e7f79fac --- /dev/null +++ b/futures-util/src/task/mod.rs @@ -0,0 +1,9 @@ +//! Task notification + +mod context; +pub use self::context::ContextExt; + +#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +mod atomic_waker; +#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +pub use self::atomic_waker::AtomicWaker; diff --git a/futures-util/src/try_future/mod.rs b/futures-util/src/try_future/mod.rs index bfabb941cf..77b9c20232 100644 --- a/futures-util/src/try_future/mod.rs +++ b/futures-util/src/try_future/mod.rs @@ -215,7 +215,7 @@ pub trait TryFutureExt: TryFuture { /// ``` /// # extern crate futures; /// use futures::prelude::*; - /// use futures::future::{self, ReadyFuture}; + /// use futures::future::{self, Ready}; /// /// let future_of_1 = future::ready::>(Ok(1)); /// let future_of_4 = future_of_1.and_then(|x| { @@ -223,7 +223,7 @@ pub trait TryFutureExt: TryFuture { /// }); /// /// let future_of_err_1 = future::ready::>(Err(1)); - /// future_of_err_1.and_then(|_| -> ReadyFuture> { + /// future_of_err_1.and_then(|_| -> Ready> { /// panic!("should not be called in case of an error"); /// }); /// ``` @@ -257,7 +257,7 @@ pub trait TryFutureExt: TryFuture { /// ``` /// # extern crate futures; /// use futures::prelude::*; - /// use futures::future::{self, ReadyFuture}; + /// use futures::future::{self, Ready}; /// /// let future_of_err_1 = future::ready::>(Err(1)); /// let future_of_4 = future_of_err_1.or_else(|x| { @@ -265,7 +265,7 @@ pub trait TryFutureExt: TryFuture { /// }); /// /// let future_of_1 = future::ready::>(Ok(1)); - /// future_of_1.or_else(|_| -> ReadyFuture> { + /// future_of_1.or_else(|_| -> Ready> { /// panic!("should not be called in case of success"); /// }); /// ``` diff --git a/futures/src/lib.rs b/futures/src/lib.rs index b0318057fb..774600fee7 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -33,9 +33,9 @@ #![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] #![cfg_attr(feature = "nightly", feature(use_extern_macros))] -#[doc(hidden)] pub use futures_core::core_reexport; +#[doc(hidden)] pub use futures_util::core_reexport; + #[doc(hidden)] pub use futures_core::future::Future; -#[doc(hidden)] pub use futures_core::future::CoreFutureExt; #[doc(hidden)] pub use futures_core::future::TryFuture; #[doc(hidden)] pub use futures_util::future::FutureExt; #[doc(hidden)] pub use futures_util::try_future::TryFutureExt; @@ -155,9 +155,8 @@ pub mod future { //! immediate defined value. pub use futures_core::future::{ - FutureOption, Future, TryFuture, + Future, TryFuture, FutureObj, LocalFutureObj, UnsafeFutureObj, - ready, ReadyFuture, }; pub use futures_util::future::{ @@ -165,6 +164,9 @@ pub mod future { lazy, Lazy, maybe_done, MaybeDone, poll_fn, PollFn, + ready, Ready, + + OptionFuture, FutureExt, FlattenStream, Flatten, Fuse, Inspect, IntoStream, Join, Join3, Join4, @@ -226,7 +228,7 @@ pub mod prelude { //! //! The prelude may grow over time as additional items see ubiquitous use. - pub use futures_core::future::{Future, CoreFutureExt, TryFuture}; + pub use futures_core::future::{Future, TryFuture}; pub use futures_core::stream::{Stream, TryStream}; pub use futures_core::task::{self, Poll}; @@ -341,17 +343,18 @@ pub mod task { //! executors or dealing with synchronization issues around task wakeup. pub use futures_core::task::{ - Context, Poll, Executor, Waker, LocalWaker, UnsafeWake, + Context, Poll, Executor, + Waker, LocalWaker, UnsafeWake, SpawnErrorKind, SpawnObjError, SpawnLocalObjError, }; - #[cfg(feature = "std")] + pub use futures_util::task::ContextExt; + #[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] - pub use futures_core::task::AtomicWaker; + pub use futures_util::task::AtomicWaker; #[cfg(feature = "std")] pub use futures_core::task::{ - local_waker, local_waker_from_nonlocal, - Wake, + Wake, local_waker, local_waker_from_nonlocal }; } diff --git a/futures/src/macros/pin.rs b/futures/src/macros/pin.rs index 66c3d261e8..d6b160b4ff 100644 --- a/futures/src/macros/pin.rs +++ b/futures/src/macros/pin.rs @@ -7,7 +7,7 @@ /// /// ``` /// # #![feature(pin, arbitrary_self_types)] -/// # #[macro_use] extern crate futures_core; +/// # #[macro_use] extern crate futures; /// # use core::mem::PinMut; /// # use core::marker::Unpin; /// struct Foo { @@ -25,7 +25,7 @@ /// impl Unpin for Foo {}; // Conditional Unpin impl /// ``` /// -/// [`Unpin`]: core::mem::Unpin +/// [`Unpin`]: std::marker::Unpin /// [`drop`]: Drop::drop #[macro_export] macro_rules! unsafe_pinned { @@ -51,7 +51,7 @@ macro_rules! unsafe_pinned { /// /// ``` /// # #![feature(pin, arbitrary_self_types)] -/// # #[macro_use] extern crate futures_core; +/// # #[macro_use] extern crate futures; /// # use core::mem::PinMut; /// # struct Bar; /// struct Foo { @@ -85,7 +85,7 @@ macro_rules! unsafe_unpinned { /// /// ``` /// # #![feature(pin, arbitrary_self_types)] -/// # #[macro_use] extern crate futures_core; +/// # #[macro_use] extern crate futures; /// # use core::mem::PinMut; /// # struct Foo {} /// let foo = Foo { /* ... */ }; diff --git a/futures/src/macros/poll.rs b/futures/src/macros/poll.rs index fcc97cd4de..df5a588661 100644 --- a/futures/src/macros/poll.rs +++ b/futures/src/macros/poll.rs @@ -5,9 +5,11 @@ macro_rules! try_ready { ($x:expr) => { match $x { - $crate::task::Poll::Ready(Ok(x)) => x, - $crate::task::Poll::Ready(Err(e)) => return $crate::task::Poll::Ready(Err(e.into())), - $crate::task::Poll::Pending => return $crate::task::Poll::Pending, + $crate::core_reexport::task::Poll::Ready(Ok(x)) => x, + $crate::core_reexport::task::Poll::Ready(Err(e)) => + return $crate::core_reexport::task::Poll::Ready(Err(e.into())), + $crate::core_reexport::task::Poll::Pending => + return $crate::core_reexport::task::Poll::Pending, } } } @@ -21,9 +23,12 @@ macro_rules! try_ready { macro_rules! try_poll { ($x:expr) => { match $x { - $crate::task::Poll::Ready(Ok(x)) => $crate::task::Poll::Ready(x), - $crate::task::Poll::Ready(Err(e)) => return $crate::task::Poll::Ready(Err(e.into())), - $crate::task::Poll::Pending => $crate::task::Poll::Pending, + $crate::core_reexport::task::Poll::Ready(Ok(x)) => + $crate::core_reexport::task::Poll::Ready(x), + $crate::core_reexport::task::Poll::Ready(Err(e)) => + return $crate::core_reexport::task::Poll::Ready(Err(e.into())), + $crate::core_reexport::task::Poll::Pending => + $crate::core_reexport::task::Poll::Pending, } } } @@ -34,7 +39,8 @@ macro_rules! try_poll { #[macro_export] macro_rules! ready { ($e:expr) => (match $e { - $crate::task::Poll::Ready(t) => t, - $crate::task::Poll::Pending => return $crate::task::Poll::Pending, + $crate::core_reexport::task::Poll::Ready(t) => t, + $crate::core_reexport::task::Poll::Pending => + return $crate::core_reexport::task::Poll::Pending, }) }