X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibstd%2Ferror.rs;h=5cc7dcdae1fcd5917db45d4210891758b3041df4;hb=eebe62aaa1e31151269d19ec71248215a40f6417;hp=7cb830e751a77653295b4bcb0f6f6e8d9bb8d48c;hpb=90952171ac624eb02f65ce5c6838d319755c13c7;p=rust.git diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 7cb830e751a..5cc7dcdae1f 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -94,7 +94,7 @@ fn description(&self) -> &str { /// "I'm the superhero of errors" /// } /// - /// fn cause(&self) -> Option<&Error> { + /// fn cause(&self) -> Option<&dyn Error> { /// Some(&self.side) /// } /// } @@ -201,15 +201,25 @@ fn source(&self) -> Option<&(dyn Error + 'static)> { None } #[unstable(feature = "error_type_id", reason = "this is memory unsafe to override in user code", issue = "60784")] - fn type_id(&self) -> TypeId where Self: 'static { + fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static { TypeId::of::() } } +mod private { + // This is a hack to prevent `type_id` from being overridden by `Error` + // implementations, since that can enable unsound downcasting. + #[unstable(feature = "error_type_id", issue = "60784")] + #[derive(Debug)] + pub struct Internal; +} + #[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`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -234,7 +244,7 @@ impl<'a, E: Error + 'a> From for Box { /// /// let an_error = AnError; /// assert!(0 == mem::size_of_val(&an_error)); - /// let a_boxed_error = Box::::from(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 { @@ -247,6 +257,8 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box From for Box::from(an_error); + /// let a_boxed_error = Box::::from(an_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` @@ -288,6 +300,8 @@ fn from(err: E) -> Box { impl From for Box { /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -295,12 +309,11 @@ impl From for Box { /// use std::mem; /// /// let a_string_error = "a string error".to_string(); - /// let a_boxed_error = Box::::from(a_string_error); + /// let a_boxed_error = Box::::from(a_string_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(err: String) -> Box { - #[derive(Debug)] struct StringError(String); impl Error for StringError { @@ -313,6 +326,13 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } + // 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)) } } @@ -321,6 +341,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl From for Box { /// Converts a [`String`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -328,7 +350,7 @@ impl From for Box { /// use std::mem; /// /// let a_string_error = "a string error".to_string(); - /// let a_boxed_error = Box::::from(a_string_error); + /// 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 { @@ -342,6 +364,8 @@ fn from(str_err: String) -> Box { impl<'a> From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -349,7 +373,7 @@ impl<'a> From<&str> for Box { /// use std::mem; /// /// let a_str_error = "a str error"; - /// let a_boxed_error = Box::::from(a_str_error); + /// let a_boxed_error = Box::::from(a_str_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` @@ -362,6 +386,8 @@ fn from(err: &str) -> Box { impl From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`]. /// + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -369,7 +395,7 @@ impl From<&str> for Box { /// use std::mem; /// /// let a_str_error = "a str error"; - /// let a_boxed_error = Box::::from(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 { @@ -381,6 +407,9 @@ fn from(err: &str) -> Box { impl<'a, 'b> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// + /// [`Cow`]: ../borrow/enum.Cow.html + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -389,7 +418,7 @@ impl<'a, 'b> From> for Box { /// use std::borrow::Cow; /// /// let a_cow_str_error = Cow::from("a str error"); - /// let a_boxed_error = Box::::from(a_cow_str_error); + /// let a_boxed_error = Box::::from(a_cow_str_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` @@ -402,6 +431,9 @@ fn from(err: Cow<'b, str>) -> Box { impl<'a> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`]. /// + /// [`Cow`]: ../borrow/enum.Cow.html + /// [`Error`]: ../error/trait.Error.html + /// /// # Examples /// /// ``` @@ -410,7 +442,7 @@ impl<'a> From> for Box { /// use std::borrow::Cow; /// /// let a_cow_str_error = Cow::from("a str error"); - /// let a_boxed_error = Box::::from(a_cow_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 { @@ -575,7 +607,7 @@ pub fn is(&self) -> bool { let t = TypeId::of::(); // Get TypeId of the type in the trait object - let boxed = self.type_id(); + let boxed = self.type_id(private::Internal); // Compare both TypeIds on equality t == boxed