@@ -795,6 +795,63 @@ impl Error {
795795 }
796796 }
797797
798+ /// Attempt to downgrade the inner error to `E` if any.
799+ ///
800+ /// If this [`Error`] was constructed via [`new`] then this function will
801+ /// attempt to perform downgrade on it, otherwise it will return [`Err`].
802+ ///
803+ /// If downgrade succeeds, it will return [`Ok`], otherwise it will also
804+ /// return [`Err`].
805+ ///
806+ /// [`new`]: Error::new
807+ ///
808+ /// # Examples
809+ ///
810+ /// ```
811+ /// #![feature(io_error_try_downcast_inner)]
812+ ///
813+ /// use std::fmt;
814+ /// use std::io;
815+ /// use std::error::Error;
816+ ///
817+ /// #[derive(Debug)]
818+ /// enum E {
819+ /// Io(io::Error),
820+ /// SomeOtherVariant,
821+ /// }
822+ ///
823+ /// impl fmt::Display for E {
824+ /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
825+ /// todo!()
826+ /// }
827+ /// }
828+ /// impl Error for E {}
829+ ///
830+ /// impl From<io::Error> for E {
831+ /// fn from(err: io::Error) -> E {
832+ /// err.try_downcast_inner::<E>()
833+ /// .map(|b| *b)
834+ /// .unwrap_or_else(E::Io)
835+ /// }
836+ /// }
837+ /// ```
838+ #[ unstable( feature = "io_error_try_downcast_inner" , issue = "none" ) ]
839+ pub fn try_downcast_inner < E > ( self ) -> result:: Result < Box < E > , Self >
840+ where
841+ E : error:: Error + Send + Sync + ' static ,
842+ {
843+ match self . repr . into_data ( ) {
844+ ErrorData :: Custom ( b) if b. error . is :: < E > ( ) => {
845+ let res = ( * b) . error . downcast :: < E > ( ) ;
846+
847+ // Safety: b.error.is::<E>() returns true,
848+ // which means that res must be Ok(e).
849+ Ok ( unsafe { res. unwrap_unchecked ( ) } )
850+ }
851+ repr_data => Err ( Self { repr : Repr :: new ( repr_data) } ) ,
852+ }
853+ }
854+
798855 /// Returns the corresponding [`ErrorKind`] for this error.
799856 ///
800857 /// # Examples
0 commit comments