about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-11 20:14:39 +0000
committerbors <bors@rust-lang.org>2018-06-11 20:14:39 +0000
commit1d4dbf488a4364413e7b9611866b7a5c75ce566f (patch)
treede372b0f4be645ac0087448bffc272d09a807878
parent0b7c9e756e8bee2efd4f6929c79f9e3ed9115689 (diff)
parentfb507cadf32e1eacccc07c1c3511636fd6378f7b (diff)
downloadrust-1d4dbf488a4364413e7b9611866b7a5c75ce566f.tar.gz
rust-1d4dbf488a4364413e7b9611866b7a5c75ce566f.zip
Auto merge of #51442 - tinaun:more-future-impls, r=cramertj
[futures] add a few blanket impls to std

these were defined in the futures crate, but with the core definitions moving to std these would need to move too.
-rw-r--r--src/liballoc/boxed.rs18
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/libcore/future.rs17
-rw-r--r--src/libcore/task.rs55
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/panic.rs18
6 files changed, 110 insertions, 0 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index a64b94b6517..c794fb8220a 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -915,6 +915,24 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
 impl<T: ?Sized> Unpin for PinBox<T> {}
 
 #[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        PinMut::new(&mut **self).poll(cx)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: ?Sized + Future> Future for PinBox<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        self.as_pin_mut().poll(cx)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
 unsafe impl<F: Future<Output = ()> + Send + 'static> UnsafePoll for PinBox<F> {
     fn into_raw(self) -> *mut () {
         PinBox::into_raw(self) as *mut ()
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 242c7d2e70f..a1139189c9a 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 b4d087f8edb..a8c8f69411e 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<Self>, cx: &mut task::Context) -> Poll<Self::Output>;
 }
+
+impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        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<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        F::poll((*self).reborrow(), cx)
+    }
+}
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index e46a6d41d7a..bef6d3677d0 100644
--- a/src/libcore/task.rs
+++ b/src/libcore/task.rs
@@ -32,6 +32,61 @@ pub enum Poll<T> {
     Pending,
 }
 
+impl<T> Poll<T> {
+    /// Change the ready value of this `Poll` with the closure provided
+    pub fn map<U, F>(self, f: F) -> Poll<U>
+        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<T, E> Poll<Result<T, E>> {
+    /// Change the success value of this `Poll` with the closure provided
+    pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
+        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<U, F>(self, f: F) -> Poll<Result<T, U>>
+        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<T> From<T> for Poll<T> {
+    fn from(t: T) -> Poll<T> {
+        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 4bf52224ae6..144977460b6 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 229034eb779..4b5a063ea73 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<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
     }
 }
 
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: Future> Future for AssertUnwindSafe<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        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