diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index a64b94b651759..c794fb8220a9e 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -914,6 +914,24 @@ impl, U: ?Sized> CoerceUnsized> for PinBox {} #[unstable(feature = "pin", issue = "49150")] impl Unpin for PinBox {} +#[unstable(feature = "futures_api", issue = "50547")] +impl<'a, F: ?Sized + Future + Unpin> Future for Box { + type Output = F::Output; + + fn poll(mut self: PinMut, cx: &mut Context) -> Poll { + PinMut::new(&mut **self).poll(cx) + } +} + +#[unstable(feature = "futures_api", issue = "50547")] +impl<'a, F: ?Sized + Future> Future for PinBox { + type Output = F::Output; + + fn poll(mut self: PinMut, cx: &mut Context) -> Poll { + self.as_pin_mut().poll(cx) + } +} + #[unstable(feature = "futures_api", issue = "50547")] unsafe impl + Send + 'static> UnsafePoll for PinBox { fn into_raw(self) -> *mut () { diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 242c7d2e70f85..a1139189c9a44 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -80,6 +80,7 @@ #![cfg_attr(test, feature(rand, test))] #![feature(allocator_api)] #![feature(allow_internal_unstable)] +#![feature(arbitrary_self_types)] #![feature(ascii_ctype)] #![feature(box_into_raw_non_null)] #![feature(box_patterns)] diff --git a/src/libcore/future.rs b/src/libcore/future.rs index b4d087f8edb6d..a8c8f69411ea6 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future.rs @@ -15,6 +15,7 @@ //! Asynchronous values. use mem::PinMut; +use marker::Unpin; use task::{self, Poll}; /// A future represents an asychronous computation. @@ -91,3 +92,19 @@ pub trait Future { /// about the behavior of `poll` after a future has completed. fn poll(self: PinMut, cx: &mut task::Context) -> Poll; } + +impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F { + type Output = F::Output; + + fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll { + F::poll(PinMut::new(&mut **self), cx) + } +} + +impl<'a, F: ?Sized + Future> Future for PinMut<'a, F> { + type Output = F::Output; + + fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll { + F::poll((*self).reborrow(), cx) + } +} diff --git a/src/libcore/task.rs b/src/libcore/task.rs index e46a6d41d7acf..bef6d3677d0a3 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -32,6 +32,61 @@ pub enum Poll { Pending, } +impl Poll { + /// Change the ready value of this `Poll` with the closure provided + pub fn map(self, f: F) -> Poll + where F: FnOnce(T) -> U + { + match self { + Poll::Ready(t) => Poll::Ready(f(t)), + Poll::Pending => Poll::Pending, + } + } + + /// Returns whether this is `Poll::Ready` + pub fn is_ready(&self) -> bool { + match *self { + Poll::Ready(_) => true, + Poll::Pending => false, + } + } + + /// Returns whether this is `Poll::Pending` + pub fn is_pending(&self) -> bool { + !self.is_ready() + } +} + +impl Poll> { + /// Change the success value of this `Poll` with the closure provided + pub fn map_ok(self, f: F) -> Poll> + where F: FnOnce(T) -> U + { + match self { + Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))), + Poll::Ready(Err(e)) => Poll::Ready(Err(e)), + Poll::Pending => Poll::Pending, + } + } + + /// Change the error value of this `Poll` with the closure provided + pub fn map_err(self, f: F) -> Poll> + where F: FnOnce(E) -> U + { + match self { + Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)), + Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))), + Poll::Pending => Poll::Pending, + } + } +} + +impl From for Poll { + fn from(t: T) -> Poll { + Poll::Ready(t) + } +} + /// A `Waker` is a handle for waking up a task by notifying its executor that it /// is ready to be run. /// diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7bbc99b83be56..bb23fe5fa918e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -239,6 +239,7 @@ #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] #![feature(align_offset)] +#![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(ascii_ctype)] #![feature(asm)] diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 229034eb7790b..4b5a063ea73aa 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -15,11 +15,14 @@ use any::Any; use cell::UnsafeCell; use fmt; +use future::Future; +use mem::PinMut; use ops::{Deref, DerefMut}; use panicking; use ptr::{Unique, NonNull}; use rc::Rc; use sync::{Arc, Mutex, RwLock, atomic}; +use task::{self, Poll}; use thread::Result; #[stable(feature = "panic_hooks", since = "1.10.0")] @@ -315,6 +318,21 @@ impl fmt::Debug for AssertUnwindSafe { } } +#[unstable(feature = "futures_api", issue = "50547")] +impl<'a, F: Future> Future for AssertUnwindSafe { + type Output = F::Output; + + fn poll(mut self: PinMut, cx: &mut task::Context) -> Poll { + unsafe { + let pinned_field = PinMut::new_unchecked( + &mut PinMut::get_mut(self.reborrow()).0 + ); + + pinned_field.poll(cx) + } + } +} + /// Invokes a closure, capturing the cause of an unwinding panic if one occurs. /// /// This function will return `Ok` with the closure's result if the closure