/// "I'm the superhero of errors"
/// }
///
- /// fn cause(&self) -> Option<&Error> {
+ /// fn cause(&self) -> Option<&dyn Error> {
/// Some(&self.side)
/// }
/// }
#[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::<Self>()
}
}
+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<E> for Box<dyn Error + 'a> {
/// Converts a type of [`Error`] into a box of dyn [`Error`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
///
/// let an_error = AnError;
/// assert!(0 == mem::size_of_val(&an_error));
- /// let a_boxed_error = Box::<Error>::from(an_error);
+ /// let a_boxed_error = Box::<dyn Error>::from(an_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: E) -> Box<dyn Error + 'a> {
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] +
/// [`Send`] + [`Sync`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
///
/// let an_error = AnError;
/// assert!(0 == mem::size_of_val(&an_error));
- /// let a_boxed_error = Box::<Error + Send + Sync>::from(an_error);
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
impl From<String> for Box<dyn Error + Send + Sync> {
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let a_string_error = "a string error".to_string();
- /// let a_boxed_error = Box::<Error + Send + Sync>::from(a_string_error);
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
impl From<String> for Box<dyn Error> {
/// Converts a [`String`] into a box of dyn [`Error`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let a_string_error = "a string error".to_string();
- /// let a_boxed_error = Box::<Error>::from(a_string_error);
+ /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(str_err: String) -> Box<dyn Error> {
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let a_str_error = "a str error";
- /// let a_boxed_error = Box::<Error + Send + Sync>::from(a_str_error);
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
impl From<&str> for Box<dyn Error> {
/// Converts a [`str`] into a box of dyn [`Error`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let a_str_error = "a str error";
- /// let a_boxed_error = Box::<Error>::from(a_str_error);
+ /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: &str) -> Box<dyn Error> {
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
+ /// [`Cow`]: ../borrow/enum.Cow.html
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// use std::borrow::Cow;
///
/// let a_cow_str_error = Cow::from("a str error");
- /// let a_boxed_error = Box::<Error + Send + Sync>::from(a_cow_str_error);
+ /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
/// Converts a [`Cow`] into a box of dyn [`Error`].
///
+ /// [`Cow`]: ../borrow/enum.Cow.html
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// use std::borrow::Cow;
///
/// let a_cow_str_error = Cow::from("a str error");
- /// let a_boxed_error = Box::<Error>::from(a_cow_str_error);
+ /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: Cow<'a, str>) -> Box<dyn Error> {
let t = TypeId::of::<T>();
// 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