about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-15 09:37:24 +0000
committerbors <bors@rust-lang.org>2019-11-15 09:37:24 +0000
commitce36ab2b064c2aa716084d79717c64cc04bb6532 (patch)
tree77f5ba79a6eda736ab42329b9294a8e4c91fe259 /src/libstd
parent9e8c4e6fb1c952048fb823e59f4c9c6487bf9a58 (diff)
parenta173353daa657d90fff06e6223f48ee383bf9d13 (diff)
downloadrust-ce36ab2b064c2aa716084d79717c64cc04bb6532.tar.gz
rust-ce36ab2b064c2aa716084d79717c64cc04bb6532.zip
Auto merge of #66438 - JohnTitor:rollup-qpv3wia, r=JohnTitor
Rollup of 12 pull requests

Successful merges:

 - #65557 (rename Error::iter_chain() and remove Error::iter_sources())
 - #66013 (Avoid hashing the key twice in `get_query()`.)
 - #66306 (Remove cannot mutate statics in initializer of another static error)
 - #66338 (Update mdbook.)
 - #66388 (Do not ICE on recovery from unmet associated type bound obligation)
 - #66390 (Fix ICE when trying to suggest `Type<>` instead of `Type()`)
 - #66391 (Do not ICE in `if` without `else` in `async fn`)
 - #66398 (Remove some stack frames from `.async` calls)
 - #66410 (miri: helper methods for max values of machine's usize/isize)
 - #66418 (Link to tracking issue in HIR const-check error code description)
 - #66419 (Don't warn labels beginning with `_` on unused_labels lint)
 - #66428 (Cleanup unused function)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/error.rs92
-rw-r--r--src/libstd/future.rs45
2 files changed, 24 insertions, 113 deletions
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 6b9a35fccc4..df24b6635f4 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -725,6 +725,9 @@ impl dyn Error {
     /// Returns an iterator starting with the current error and continuing with
     /// recursively calling [`source`].
     ///
+    /// If you want to omit the current error and only use its sources,
+    /// use `skip(1)`.
+    ///
     /// # Examples
     ///
     /// ```
@@ -763,7 +766,7 @@ impl dyn Error {
     /// // let err : Box<Error> = b.into(); // or
     /// let err = &b as &(dyn Error);
     ///
-    /// let mut iter = err.iter_chain();
+    /// let mut iter = err.chain();
     ///
     /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
     /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
@@ -774,98 +777,27 @@ impl dyn Error {
     /// [`source`]: trait.Error.html#method.source
     #[unstable(feature = "error_iter", issue = "58520")]
     #[inline]
-    pub fn iter_chain(&self) -> ErrorIter<'_> {
-        ErrorIter {
+    pub fn chain(&self) -> Chain<'_> {
+        Chain {
             current: Some(self),
         }
     }
-
-    /// Returns an iterator starting with the [`source`] of this error
-    /// and continuing with recursively calling [`source`].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(error_iter)]
-    /// use std::error::Error;
-    /// use std::fmt;
-    ///
-    /// #[derive(Debug)]
-    /// struct A;
-    ///
-    /// #[derive(Debug)]
-    /// struct B(Option<Box<dyn Error + 'static>>);
-    ///
-    /// #[derive(Debug)]
-    /// struct C(Option<Box<dyn Error + 'static>>);
-    ///
-    /// impl fmt::Display for A {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "A")
-    ///     }
-    /// }
-    ///
-    /// impl fmt::Display for B {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "B")
-    ///     }
-    /// }
-    ///
-    /// impl fmt::Display for C {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "C")
-    ///     }
-    /// }
-    ///
-    /// impl Error for A {}
-    ///
-    /// impl Error for B {
-    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
-    ///         self.0.as_ref().map(|e| e.as_ref())
-    ///     }
-    /// }
-    ///
-    /// impl Error for C {
-    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
-    ///         self.0.as_ref().map(|e| e.as_ref())
-    ///     }
-    /// }
-    ///
-    /// let b = B(Some(Box::new(A)));
-    /// let c = C(Some(Box::new(b)));
-    ///
-    /// // let err : Box<Error> = c.into(); // or
-    /// let err = &c as &(dyn Error);
-    ///
-    /// let mut iter = err.iter_sources();
-    ///
-    /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
-    /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
-    /// assert!(iter.next().is_none());
-    /// assert!(iter.next().is_none());
-    /// ```
-    ///
-    /// [`source`]: trait.Error.html#method.source
-    #[inline]
-    #[unstable(feature = "error_iter", issue = "58520")]
-    pub fn iter_sources(&self) -> ErrorIter<'_> {
-        ErrorIter {
-            current: self.source(),
-        }
-    }
 }
 
-/// An iterator over [`Error`]
+/// An iterator over an [`Error`] and its sources.
+///
+/// If you want to omit the initial error and only process
+/// its sources, use `skip(1)`.
 ///
 /// [`Error`]: trait.Error.html
 #[unstable(feature = "error_iter", issue = "58520")]
 #[derive(Copy, Clone, Debug)]
-pub struct ErrorIter<'a> {
+pub struct Chain<'a> {
     current: Option<&'a (dyn Error + 'static)>,
 }
 
 #[unstable(feature = "error_iter", issue = "58520")]
-impl<'a> Iterator for ErrorIter<'a> {
+impl<'a> Iterator for Chain<'a> {
     type Item = &'a (dyn Error + 'static);
 
     fn next(&mut self) -> Option<Self::Item> {
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index c65f71fb1a4..6de3f1d545b 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -40,10 +40,11 @@ impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         // Safe because we're !Unpin + !Drop mapping to a ?Unpin value
         let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
-        set_task_context(cx, || match gen.resume() {
+        let _guard = unsafe { set_task_context(cx) };
+        match gen.resume() {
             GeneratorState::Yielded(()) => Poll::Pending,
             GeneratorState::Complete(x) => Poll::Ready(x),
-        })
+        }
     }
 }
 
@@ -61,35 +62,23 @@ impl Drop for SetOnDrop {
     }
 }
 
-#[doc(hidden)]
-#[unstable(feature = "gen_future", issue = "50547")]
-/// Sets the thread-local task context used by async/await futures.
-pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
-where
-    F: FnOnce() -> R
-{
+// Safety: the returned guard must drop before `cx` is dropped and before
+// any previous guard is dropped.
+unsafe fn set_task_context(cx: &mut Context<'_>) -> SetOnDrop {
     // transmute the context's lifetime to 'static so we can store it.
-    let cx = unsafe {
-        core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx)
-    };
+    let cx = core::mem::transmute::<&mut Context<'_>, &mut Context<'static>>(cx);
     let old_cx = TLS_CX.with(|tls_cx| {
         tls_cx.replace(Some(NonNull::from(cx)))
     });
-    let _reset = SetOnDrop(old_cx);
-    f()
+    SetOnDrop(old_cx)
 }
 
 #[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
-/// Retrieves the thread-local task context used by async/await futures.
-///
-/// This function acquires exclusive access to the task context.
-///
-/// Panics if no context has been set or if the context has already been
-/// retrieved by a surrounding call to get_task_context.
-pub fn get_task_context<F, R>(f: F) -> R
+/// Polls a future in the current thread-local task waker.
+pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
 where
-    F: FnOnce(&mut Context<'_>) -> R
+    F: Future
 {
     let cx_ptr = TLS_CX.with(|tls_cx| {
         // Clear the entry so that nested `get_task_waker` calls
@@ -108,15 +97,5 @@ where
     //
     // The pointer that was inserted came from an `&mut Context<'_>`,
     // so it is safe to treat as mutable.
-    unsafe { f(cx_ptr.as_mut()) }
-}
-
-#[doc(hidden)]
-#[unstable(feature = "gen_future", issue = "50547")]
-/// Polls a future in the current thread-local task waker.
-pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
-where
-    F: Future
-{
-    get_task_context(|cx| F::poll(f, cx))
+    unsafe { F::poll(f, cx_ptr.as_mut()) }
 }