diff options
| author | bors <bors@rust-lang.org> | 2019-11-15 09:37:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-15 09:37:24 +0000 |
| commit | ce36ab2b064c2aa716084d79717c64cc04bb6532 (patch) | |
| tree | 77f5ba79a6eda736ab42329b9294a8e4c91fe259 /src/libstd | |
| parent | 9e8c4e6fb1c952048fb823e59f4c9c6487bf9a58 (diff) | |
| parent | a173353daa657d90fff06e6223f48ee383bf9d13 (diff) | |
| download | rust-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.rs | 92 | ||||
| -rw-r--r-- | src/libstd/future.rs | 45 |
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()) } } |
