about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2018-07-26 09:18:40 -0600
committerGitHub <noreply@github.com>2018-07-26 09:18:40 -0600
commit858adfe21dead8b0b2df16a5fc3ac4e8759a9c4e (patch)
tree93aacde4d81dcd07f0c1644f1bfb435b03f740e6 /src/libcore
parent091a10e0eb5a86ace454b23c7ed2f1aaefb5b969 (diff)
parentbce8a91f34e63a4ed87a6d6351bf67a82306afbd (diff)
downloadrust-858adfe21dead8b0b2df16a5fc3ac4e8759a9c4e.tar.gz
rust-858adfe21dead8b0b2df16a5fc3ac4e8759a9c4e.zip
Rollup merge of #52721 - cramertj:try-poll, r=aturon
std::ops::Try impl for std::task::Poll

I originally left out the `Try` impl for `Poll` because I was curious if we needed it, and @MajorBreakfast and I had discussed the potential for it to introduce confusion about exactly what control-flow was happening at different points. However, after porting a pretty significant chunk of Fuchsia over to futures 0.3, I discovered that I was *constantly* having to do repetitive matching on `Poll<Result<...>>` or `Poll<Option<Result<...>>>` in order to propagate errors correctly. `try_poll` (propagate `Poll::Ready(Err(..))`s) helped in some places, but it was far more common to need some form of conversion between `Result`, `Poll<Result<...>>`, and `Poll<Option<Result<...>>>`. The `Try` trait conveniently provides all of these conversions in addition to a more concise syntax (`?`), so I'd like to experiment with using these instead.

cc @seanmonstar

r? @aturon

Note: this change means that far more futures 0.1 code can work without significant changes since it papers over the fact that `Result` is no longer at the top-level when using `Stream` and `Future` (since it's now `Poll<Result<...>>` or `Poll<Option<Result<...>>>` instead of `Result<Poll<..>>` and `Result<Poll<Option<...>>>`).
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/task/poll.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs
index 10c954f0e80..fb027efc6dc 100644
--- a/src/libcore/task/poll.rs
+++ b/src/libcore/task/poll.rs
@@ -12,6 +12,9 @@
             reason = "futures in libcore are unstable",
             issue = "50547")]
 
+use ops::Try;
+use result::Result;
+
 /// Indicates whether a value is available or if the current task has been
 /// scheduled to receive a wakeup instead.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
@@ -39,6 +42,7 @@ impl<T> Poll<T> {
     }
 
     /// Returns whether this is `Poll::Ready`
+    #[inline]
     pub fn is_ready(&self) -> bool {
         match *self {
             Poll::Ready(_) => true,
@@ -47,6 +51,7 @@ impl<T> Poll<T> {
     }
 
     /// Returns whether this is `Poll::Pending`
+    #[inline]
     pub fn is_pending(&self) -> bool {
         !self.is_ready()
     }
@@ -81,3 +86,52 @@ impl<T> From<T> for Poll<T> {
         Poll::Ready(t)
     }
 }
+
+impl<T, E> Try for Poll<Result<T, E>> {
+    type Ok = Poll<T>;
+    type Error = E;
+
+    #[inline]
+    fn into_result(self) -> Result<Self::Ok, Self::Error> {
+        match self {
+            Poll::Ready(Ok(x)) => Ok(Poll::Ready(x)),
+            Poll::Ready(Err(e)) => Err(e),
+            Poll::Pending => Ok(Poll::Pending),
+        }
+    }
+
+    #[inline]
+    fn from_error(e: Self::Error) -> Self {
+        Poll::Ready(Err(e))
+    }
+
+    #[inline]
+    fn from_ok(x: Self::Ok) -> Self {
+        x.map(Ok)
+    }
+}
+
+impl<T, E> Try for Poll<Option<Result<T, E>>> {
+    type Ok = Poll<Option<T>>;
+    type Error = E;
+
+    #[inline]
+    fn into_result(self) -> Result<Self::Ok, Self::Error> {
+        match self {
+            Poll::Ready(Some(Ok(x))) => Ok(Poll::Ready(Some(x))),
+            Poll::Ready(Some(Err(e))) => Err(e),
+            Poll::Ready(None) => Ok(Poll::Ready(None)),
+            Poll::Pending => Ok(Poll::Pending),
+        }
+    }
+
+    #[inline]
+    fn from_error(e: Self::Error) -> Self {
+        Poll::Ready(Some(Err(e)))
+    }
+
+    #[inline]
+    fn from_ok(x: Self::Ok) -> Self {
+        x.map(|x| x.map(Ok))
+    }
+}