#[stable(feature = "error_source", since = "1.30.0")]
fn source(&self) -> Option<&(dyn Error + 'static)> { None }
- /// Get the `TypeId` of `self`
+ /// Gets the `TypeId` of `self`
#[doc(hidden)]
#[stable(feature = "error_type_id", since = "1.34.0")]
fn type_id(&self) -> TypeId where Self: 'static {
// copied from any.rs
impl dyn Error + 'static {
- /// Returns true if the boxed type is the same as `T`
+ /// Returns `true` if the boxed type is the same as `T`
#[stable(feature = "error_downcast", since = "1.3.0")]
#[inline]
pub fn is<T: Error + 'static>(&self) -> bool {
Err(self)
}
}
+
+ /// Returns an iterator starting with the current 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>>);
+ ///
+ /// 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 Error for A {}
+ ///
+ /// impl Error for B {
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
+ /// self.0.as_ref().map(|e| e.as_ref())
+ /// }
+ /// }
+ ///
+ /// let b = B(Some(Box::new(A)));
+ ///
+ /// // let err : Box<Error> = b.into(); // or
+ /// let err = &b as &(dyn Error);
+ ///
+ /// let mut iter = err.iter_chain();
+ ///
+ /// 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
+ #[unstable(feature = "error_iter", issue = "58289")]
+ #[inline]
+ pub fn iter_chain(&self) -> ErrorIter {
+ ErrorIter {
+ 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 = "58289")]
+ pub fn iter_sources(&self) -> ErrorIter {
+ ErrorIter {
+ current: self.source(),
+ }
+ }
+}
+
+/// An iterator over [`Error`]
+///
+/// [`Error`]: trait.Error.html
+#[unstable(feature = "error_iter", issue = "58289")]
+#[derive(Copy, Clone, Debug)]
+pub struct ErrorIter<'a> {
+ current: Option<&'a (dyn Error + 'static)>,
+}
+
+#[unstable(feature = "error_iter", issue = "58289")]
+impl<'a> Iterator for ErrorIter<'a> {
+ type Item = &'a (dyn Error + 'static);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let current = self.current;
+ self.current = self.current.and_then(Error::source);
+ current
+ }
}
impl dyn Error + Send {