X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=library%2Fstd%2Fsrc%2Ferror.rs;h=05f8fd8de327f2afa0444b858d3ca35085e79252;hb=0f5d3ba30f33116a610e5f9f2bb60f3ce120a167;hp=e45059595362f00c7fc348a2e87b50f691ee3d76;hpb=92b702e90d4f38f1d8b492915c7caa6d2902beb7;p=rust.git diff --git a/library/std/src/error.rs b/library/std/src/error.rs index e4505959536..05f8fd8de32 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -4,242 +4,12 @@ #[cfg(test)] mod tests; -#[cfg(bootstrap)] -use core::array; -#[cfg(bootstrap)] -use core::convert::Infallible; - -#[cfg(bootstrap)] -use crate::alloc::{AllocError, LayoutError}; -#[cfg(bootstrap)] -use crate::any::Demand; -#[cfg(bootstrap)] -use crate::any::{Provider, TypeId}; use crate::backtrace::Backtrace; -#[cfg(bootstrap)] -use crate::borrow::Cow; -#[cfg(bootstrap)] -use crate::cell; -#[cfg(bootstrap)] -use crate::char; -#[cfg(bootstrap)] -use crate::fmt::Debug; -#[cfg(bootstrap)] -use crate::fmt::Display; use crate::fmt::{self, Write}; -#[cfg(bootstrap)] -use crate::io; -#[cfg(bootstrap)] -use crate::mem::transmute; -#[cfg(bootstrap)] -use crate::num; -#[cfg(bootstrap)] -use crate::str; -#[cfg(bootstrap)] -use crate::string; -#[cfg(bootstrap)] -use crate::sync::Arc; -#[cfg(bootstrap)] -use crate::time; -#[cfg(not(bootstrap))] #[stable(feature = "rust1", since = "1.0.0")] pub use core::error::Error; -/// `Error` is a trait representing the basic expectations for error values, -/// i.e., values of type `E` in [`Result`]. -/// -/// Errors must describe themselves through the [`Display`] and [`Debug`] -/// traits. Error messages are typically concise lowercase sentences without -/// trailing punctuation: -/// -/// ``` -/// let err = "NaN".parse::().unwrap_err(); -/// assert_eq!(err.to_string(), "invalid digit found in string"); -/// ``` -/// -/// Errors may provide cause information. [`Error::source()`] is generally -/// used when errors cross "abstraction boundaries". If one module must report -/// an error that is caused by an error from a lower-level module, it can allow -/// accessing that error via [`Error::source()`]. This makes it possible for the -/// high-level module to provide its own errors while also revealing some of the -/// implementation for debugging. -#[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Error")] -#[cfg(bootstrap)] -pub trait Error: Debug + Display { - /// The lower-level source of this error, if any. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::fmt; - /// - /// #[derive(Debug)] - /// struct SuperError { - /// source: SuperErrorSideKick, - /// } - /// - /// impl fmt::Display for SuperError { - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f, "SuperError is here!") - /// } - /// } - /// - /// impl Error for SuperError { - /// fn source(&self) -> Option<&(dyn Error + 'static)> { - /// Some(&self.source) - /// } - /// } - /// - /// #[derive(Debug)] - /// struct SuperErrorSideKick; - /// - /// impl fmt::Display for SuperErrorSideKick { - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f, "SuperErrorSideKick is here!") - /// } - /// } - /// - /// impl Error for SuperErrorSideKick {} - /// - /// fn get_super_error() -> Result<(), SuperError> { - /// Err(SuperError { source: SuperErrorSideKick }) - /// } - /// - /// fn main() { - /// match get_super_error() { - /// Err(e) => { - /// println!("Error: {e}"); - /// println!("Caused by: {}", e.source().unwrap()); - /// } - /// _ => println!("No error"), - /// } - /// } - /// ``` - #[stable(feature = "error_source", since = "1.30.0")] - fn source(&self) -> Option<&(dyn Error + 'static)> { - None - } - - /// Gets the `TypeId` of `self`. - #[doc(hidden)] - #[unstable( - feature = "error_type_id", - reason = "this is memory-unsafe to override in user code", - issue = "60784" - )] - fn type_id(&self, _: private::Internal) -> TypeId - where - Self: 'static, - { - TypeId::of::() - } - - /// ``` - /// if let Err(e) = "xc".parse::() { - /// // Print `e` itself, no need for description(). - /// eprintln!("Error: {e}"); - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")] - fn description(&self) -> &str { - "description() is deprecated; use Display" - } - - #[stable(feature = "rust1", since = "1.0.0")] - #[deprecated( - since = "1.33.0", - note = "replaced by Error::source, which can support downcasting" - )] - #[allow(missing_docs)] - fn cause(&self) -> Option<&dyn Error> { - self.source() - } - - /// Provides type based access to context intended for error reports. - /// - /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract - /// references to member variables from `dyn Error` trait objects. - /// - /// # Example - /// - /// ```rust - /// #![feature(provide_any)] - /// #![feature(error_generic_member_access)] - /// use core::fmt; - /// use core::any::Demand; - /// - /// #[derive(Debug)] - /// struct MyBacktrace { - /// // ... - /// } - /// - /// impl MyBacktrace { - /// fn new() -> MyBacktrace { - /// // ... - /// # MyBacktrace {} - /// } - /// } - /// - /// #[derive(Debug)] - /// struct SourceError { - /// // ... - /// } - /// - /// impl fmt::Display for SourceError { - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f, "Example Source Error") - /// } - /// } - /// - /// impl std::error::Error for SourceError {} - /// - /// #[derive(Debug)] - /// struct Error { - /// source: SourceError, - /// backtrace: MyBacktrace, - /// } - /// - /// impl fmt::Display for Error { - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f, "Example Error") - /// } - /// } - /// - /// impl std::error::Error for Error { - /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - /// demand - /// .provide_ref::(&self.backtrace) - /// .provide_ref::(&self.source); - /// } - /// } - /// - /// fn main() { - /// let backtrace = MyBacktrace::new(); - /// let source = SourceError {}; - /// let error = Error { source, backtrace }; - /// let dyn_error = &error as &dyn std::error::Error; - /// let backtrace_ref = dyn_error.request_ref::().unwrap(); - /// - /// assert!(core::ptr::eq(&error.backtrace, backtrace_ref)); - /// } - /// ``` - #[unstable(feature = "error_generic_member_access", issue = "99301")] - #[allow(unused_variables)] - fn provide<'a>(&'a self, demand: &mut Demand<'a>) {} -} - -#[cfg(bootstrap)] -#[unstable(feature = "error_generic_member_access", issue = "99301")] -impl<'b> Provider for dyn Error + 'b { - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - self.provide(demand) - } -} - mod private { // This is a hack to prevent `type_id` from being overridden by `Error` // implementations, since that can enable unsound downcasting. @@ -248,799 +18,6 @@ mod private { pub struct Internal; } -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + 'a> From for Box { - /// Converts a type of [`Error`] into a box of dyn [`Error`]. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::fmt; - /// use std::mem; - /// - /// #[derive(Debug)] - /// struct AnError; - /// - /// impl fmt::Display for AnError { - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f, "An error") - /// } - /// } - /// - /// impl Error for AnError {} - /// - /// let an_error = AnError; - /// assert!(0 == mem::size_of_val(&an_error)); - /// let a_boxed_error = Box::::from(an_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - fn from(err: E) -> Box { - Box::new(err) - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + Send + Sync + 'a> From for Box { - /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of - /// dyn [`Error`] + [`Send`] + [`Sync`]. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::fmt; - /// use std::mem; - /// - /// #[derive(Debug)] - /// struct AnError; - /// - /// impl fmt::Display for AnError { - /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f, "An error") - /// } - /// } - /// - /// impl Error for AnError {} - /// - /// unsafe impl Send for AnError {} - /// - /// unsafe impl Sync for AnError {} - /// - /// let an_error = AnError; - /// assert!(0 == mem::size_of_val(&an_error)); - /// let a_boxed_error = Box::::from(an_error); - /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - fn from(err: E) -> Box { - Box::new(err) - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl From for Box { - /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::mem; - /// - /// let a_string_error = "a string error".to_string(); - /// let a_boxed_error = Box::::from(a_string_error); - /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - #[inline] - fn from(err: String) -> Box { - struct StringError(String); - - impl Error for StringError { - #[allow(deprecated)] - fn description(&self) -> &str { - &self.0 - } - } - - impl Display for StringError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - Display::fmt(&self.0, f) - } - } - - // Purposefully skip printing "StringError(..)" - impl Debug for StringError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - Debug::fmt(&self.0, f) - } - } - - Box::new(StringError(err)) - } -} - -#[cfg(bootstrap)] -#[stable(feature = "string_box_error", since = "1.6.0")] -impl From for Box { - /// Converts a [`String`] into a box of dyn [`Error`]. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::mem; - /// - /// let a_string_error = "a string error".to_string(); - /// let a_boxed_error = Box::::from(a_string_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - fn from(str_err: String) -> Box { - let err1: Box = From::from(str_err); - let err2: Box = err1; - err2 - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> From<&str> for Box { - /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. - /// - /// [`str`]: prim@str - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::mem; - /// - /// let a_str_error = "a str error"; - /// let a_boxed_error = Box::::from(a_str_error); - /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - #[inline] - fn from(err: &str) -> Box { - From::from(String::from(err)) - } -} - -#[cfg(bootstrap)] -#[stable(feature = "string_box_error", since = "1.6.0")] -impl From<&str> for Box { - /// Converts a [`str`] into a box of dyn [`Error`]. - /// - /// [`str`]: prim@str - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::mem; - /// - /// let a_str_error = "a str error"; - /// let a_boxed_error = Box::::from(a_str_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - fn from(err: &str) -> Box { - From::from(String::from(err)) - } -} - -#[cfg(bootstrap)] -#[stable(feature = "cow_box_error", since = "1.22.0")] -impl<'a, 'b> From> for Box { - /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::mem; - /// use std::borrow::Cow; - /// - /// let a_cow_str_error = Cow::from("a str error"); - /// let a_boxed_error = Box::::from(a_cow_str_error); - /// assert!( - /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - fn from(err: Cow<'b, str>) -> Box { - From::from(String::from(err)) - } -} - -#[cfg(bootstrap)] -#[stable(feature = "cow_box_error", since = "1.22.0")] -impl<'a> From> for Box { - /// Converts a [`Cow`] into a box of dyn [`Error`]. - /// - /// # Examples - /// - /// ``` - /// use std::error::Error; - /// use std::mem; - /// use std::borrow::Cow; - /// - /// let a_cow_str_error = Cow::from("a str error"); - /// let a_boxed_error = Box::::from(a_cow_str_error); - /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) - /// ``` - fn from(err: Cow<'a, str>) -> Box { - From::from(String::from(err)) - } -} - -#[cfg(bootstrap)] -#[unstable(feature = "never_type", issue = "35121")] -impl Error for ! {} - -#[cfg(bootstrap)] -#[unstable( - feature = "allocator_api", - reason = "the precise API and guarantees it provides may be tweaked.", - issue = "32838" -)] -impl Error for AllocError {} - -#[cfg(bootstrap)] -#[stable(feature = "alloc_layout", since = "1.28.0")] -impl Error for LayoutError {} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for str::ParseBoolError { - #[allow(deprecated)] - fn description(&self) -> &str { - "failed to parse bool" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for str::Utf8Error { - #[allow(deprecated)] - fn description(&self) -> &str { - "invalid utf-8: corrupt contents" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for num::ParseIntError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - -#[cfg(bootstrap)] -#[stable(feature = "try_from", since = "1.34.0")] -impl Error for num::TryFromIntError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - -#[cfg(bootstrap)] -#[stable(feature = "try_from", since = "1.34.0")] -impl Error for array::TryFromSliceError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for num::ParseFloatError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for string::FromUtf8Error { - #[allow(deprecated)] - fn description(&self) -> &str { - "invalid utf-8" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for string::FromUtf16Error { - #[allow(deprecated)] - fn description(&self) -> &str { - "invalid utf-16" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "str_parse_error2", since = "1.8.0")] -impl Error for Infallible { - fn description(&self) -> &str { - match *self {} - } -} - -#[cfg(bootstrap)] -#[stable(feature = "decode_utf16", since = "1.9.0")] -impl Error for char::DecodeUtf16Error { - #[allow(deprecated)] - fn description(&self) -> &str { - "unpaired surrogate found" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "u8_from_char", since = "1.59.0")] -impl Error for char::TryFromCharError {} - -#[cfg(bootstrap)] -#[unstable(feature = "map_try_insert", issue = "82766")] -impl<'a, K: Debug + Ord, V: Debug> Error - for crate::collections::btree_map::OccupiedError<'a, K, V> -{ - #[allow(deprecated)] - fn description(&self) -> &str { - "key already exists" - } -} - -#[cfg(bootstrap)] -#[unstable(feature = "map_try_insert", issue = "82766")] -impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedError<'a, K, V> { - #[allow(deprecated)] - fn description(&self) -> &str { - "key already exists" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "box_error", since = "1.8.0")] -impl Error for Box { - #[allow(deprecated, deprecated_in_future)] - fn description(&self) -> &str { - Error::description(&**self) - } - - #[allow(deprecated)] - fn cause(&self) -> Option<&dyn Error> { - Error::cause(&**self) - } - - fn source(&self) -> Option<&(dyn Error + 'static)> { - Error::source(&**self) - } -} - -#[cfg(bootstrap)] -#[unstable(feature = "thin_box", issue = "92791")] -impl crate::error::Error for crate::boxed::ThinBox { - fn source(&self) -> Option<&(dyn crate::error::Error + 'static)> { - use core::ops::Deref; - self.deref().source() - } -} - -#[cfg(bootstrap)] -#[stable(feature = "error_by_ref", since = "1.51.0")] -impl<'a, T: Error + ?Sized> Error for &'a T { - #[allow(deprecated, deprecated_in_future)] - fn description(&self) -> &str { - Error::description(&**self) - } - - #[allow(deprecated)] - fn cause(&self) -> Option<&dyn Error> { - Error::cause(&**self) - } - - fn source(&self) -> Option<&(dyn Error + 'static)> { - Error::source(&**self) - } - - fn provide<'b>(&'b self, demand: &mut Demand<'b>) { - Error::provide(&**self, demand); - } -} - -#[cfg(bootstrap)] -#[stable(feature = "arc_error", since = "1.52.0")] -impl Error for Arc { - #[allow(deprecated, deprecated_in_future)] - fn description(&self) -> &str { - Error::description(&**self) - } - - #[allow(deprecated)] - fn cause(&self) -> Option<&dyn Error> { - Error::cause(&**self) - } - - fn source(&self) -> Option<&(dyn Error + 'static)> { - Error::source(&**self) - } - - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - Error::provide(&**self, demand); - } -} - -#[cfg(bootstrap)] -#[stable(feature = "fmt_error", since = "1.11.0")] -impl Error for fmt::Error { - #[allow(deprecated)] - fn description(&self) -> &str { - "an error occurred when formatting an argument" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "try_borrow", since = "1.13.0")] -impl Error for cell::BorrowError { - #[allow(deprecated)] - fn description(&self) -> &str { - "already mutably borrowed" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "try_borrow", since = "1.13.0")] -impl Error for cell::BorrowMutError { - #[allow(deprecated)] - fn description(&self) -> &str { - "already borrowed" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "try_from", since = "1.34.0")] -impl Error for char::CharTryFromError { - #[allow(deprecated)] - fn description(&self) -> &str { - "converted integer out of range for `char`" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "char_from_str", since = "1.20.0")] -impl Error for char::ParseCharError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - -#[cfg(bootstrap)] -#[stable(feature = "try_reserve", since = "1.57.0")] -impl Error for alloc::collections::TryReserveError {} - -#[cfg(bootstrap)] -#[unstable(feature = "duration_checked_float", issue = "83400")] -impl Error for time::FromFloatSecsError {} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl Error for alloc::ffi::NulError { - #[allow(deprecated)] - fn description(&self) -> &str { - "nul byte found in data" - } -} - -#[cfg(bootstrap)] -#[stable(feature = "rust1", since = "1.0.0")] -impl From for io::Error { - /// Converts a [`alloc::ffi::NulError`] into a [`io::Error`]. - fn from(_: alloc::ffi::NulError) -> io::Error { - io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte") - } -} - -#[cfg(bootstrap)] -#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] -impl Error for core::ffi::FromBytesWithNulError { - #[allow(deprecated)] - fn description(&self) -> &str { - self.__description() - } -} - -#[cfg(bootstrap)] -#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] -impl Error for core::ffi::FromBytesUntilNulError {} - -#[cfg(bootstrap)] -#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] -impl Error for alloc::ffi::FromVecWithNulError {} - -#[cfg(bootstrap)] -#[stable(feature = "cstring_into", since = "1.7.0")] -impl Error for alloc::ffi::IntoStringError { - #[allow(deprecated)] - fn description(&self) -> &str { - "C string contained non-utf8 bytes" - } - - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(self.__source()) - } -} - -#[cfg(bootstrap)] -impl<'a> dyn Error + 'a { - /// Request a reference of type `T` as context about this error. - #[unstable(feature = "error_generic_member_access", issue = "99301")] - pub fn request_ref(&'a self) -> Option<&'a T> { - core::any::request_ref(self) - } - - /// Request a value of type `T` as context about this error. - #[unstable(feature = "error_generic_member_access", issue = "99301")] - pub fn request_value(&'a self) -> Option { - core::any::request_value(self) - } -} - -// Copied from `any.rs`. -#[cfg(bootstrap)] -impl dyn Error + 'static { - /// Returns `true` if the inner type is the same as `T`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn is(&self) -> bool { - // Get `TypeId` of the type this function is instantiated with. - let t = TypeId::of::(); - - // Get `TypeId` of the type in the trait object (`self`). - let concrete = self.type_id(private::Internal); - - // Compare both `TypeId`s on equality. - t == concrete - } - - /// Returns some reference to the inner value if it is of type `T`, or - /// `None` if it isn't. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn downcast_ref(&self) -> Option<&T> { - if self.is::() { - unsafe { Some(&*(self as *const dyn Error as *const T)) } - } else { - None - } - } - - /// Returns some mutable reference to the inner value if it is of type `T`, or - /// `None` if it isn't. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn downcast_mut(&mut self) -> Option<&mut T> { - if self.is::() { - unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) } - } else { - None - } - } -} - -#[cfg(bootstrap)] -impl dyn Error + 'static + Send { - /// Forwards to the method defined on the type `dyn Error`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn is(&self) -> bool { - ::is::(self) - } - - /// Forwards to the method defined on the type `dyn Error`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn downcast_ref(&self) -> Option<&T> { - ::downcast_ref::(self) - } - - /// Forwards to the method defined on the type `dyn Error`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn downcast_mut(&mut self) -> Option<&mut T> { - ::downcast_mut::(self) - } - - /// Request a reference of type `T` as context about this error. - #[unstable(feature = "error_generic_member_access", issue = "99301")] - pub fn request_ref(&self) -> Option<&T> { - ::request_ref(self) - } - - /// Request a value of type `T` as context about this error. - #[unstable(feature = "error_generic_member_access", issue = "99301")] - pub fn request_value(&self) -> Option { - ::request_value(self) - } -} - -#[cfg(bootstrap)] -impl dyn Error + 'static + Send + Sync { - /// Forwards to the method defined on the type `dyn Error`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn is(&self) -> bool { - ::is::(self) - } - - /// Forwards to the method defined on the type `dyn Error`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn downcast_ref(&self) -> Option<&T> { - ::downcast_ref::(self) - } - - /// Forwards to the method defined on the type `dyn Error`. - #[stable(feature = "error_downcast", since = "1.3.0")] - #[inline] - pub fn downcast_mut(&mut self) -> Option<&mut T> { - ::downcast_mut::(self) - } - - /// Request a reference of type `T` as context about this error. - #[unstable(feature = "error_generic_member_access", issue = "99301")] - pub fn request_ref(&self) -> Option<&T> { - ::request_ref(self) - } - - /// Request a value of type `T` as context about this error. - #[unstable(feature = "error_generic_member_access", issue = "99301")] - pub fn request_value(&self) -> Option { - ::request_value(self) - } -} - -#[cfg(bootstrap)] -impl dyn Error { - #[inline] - #[stable(feature = "error_downcast", since = "1.3.0")] - /// Attempts to downcast the box to a concrete type. - pub fn downcast(self: Box) -> Result, Box> { - if self.is::() { - unsafe { - let raw: *mut dyn Error = Box::into_raw(self); - Ok(Box::from_raw(raw as *mut T)) - } - } else { - Err(self) - } - } - - /// Returns an iterator starting with the current error and continuing with - /// recursively calling [`Error::source`]. - /// - /// If you want to omit the current error and only use its sources, - /// use `skip(1)`. - /// - /// # Examples - /// - /// ``` - /// #![feature(error_iter)] - /// use std::error::Error; - /// use std::fmt; - /// - /// #[derive(Debug)] - /// struct A; - /// - /// #[derive(Debug)] - /// struct B(Option>); - /// - /// 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 = b.into(); // or - /// let err = &b as &(dyn Error); - /// - /// let mut iter = err.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()); - /// ``` - #[unstable(feature = "error_iter", issue = "58520")] - #[inline] - pub fn sources(&self) -> Sources<'_> { - // You may think this method would be better in the Error trait, and you'd be right. - // Unfortunately that doesn't work, not because of the object safety rules but because we - // save a reference to self in Sources below as a trait object. If this method was - // declared in Error, then self would have the type &T where T is some concrete type which - // implements Error. We would need to coerce self to have type &dyn Error, but that requires - // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error - // since that would forbid Error trait objects, and we can't put that bound on the method - // because that means the method can't be called on trait objects (we'd also need the - // 'static bound, but that isn't allowed because methods with bounds on Self other than - // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible. - - Sources { current: Some(self) } - } -} - -/// An iterator over an [`Error`] and its sources. -/// -/// If you want to omit the initial error and only process -/// its sources, use `skip(1)`. -#[unstable(feature = "error_iter", issue = "58520")] -#[derive(Clone, Debug)] -#[cfg(bootstrap)] -pub struct Sources<'a> { - current: Option<&'a (dyn Error + 'static)>, -} - -#[cfg(bootstrap)] -#[unstable(feature = "error_iter", issue = "58520")] -impl<'a> Iterator for Sources<'a> { - type Item = &'a (dyn Error + 'static); - - fn next(&mut self) -> Option { - let current = self.current; - self.current = self.current.and_then(Error::source); - current - } -} - -#[cfg(bootstrap)] -impl dyn Error + Send { - #[inline] - #[stable(feature = "error_downcast", since = "1.3.0")] - /// Attempts to downcast the box to a concrete type. - pub fn downcast(self: Box) -> Result, Box> { - let err: Box = self; - ::downcast(err).map_err(|s| unsafe { - // Reapply the `Send` marker. - transmute::, Box>(s) - }) - } -} - -#[cfg(bootstrap)] -impl dyn Error + Send + Sync { - #[inline] - #[stable(feature = "error_downcast", since = "1.3.0")] - /// Attempts to downcast the box to a concrete type. - pub fn downcast(self: Box) -> Result, Box> { - let err: Box = self; - ::downcast(err).map_err(|s| unsafe { - // Reapply the `Send + Sync` marker. - transmute::, Box>(s) - }) - } -} - /// An error reporter that prints an error and its sources. /// /// Report also exposes configuration options for formatting the error sources, either entirely on a