From 421fafd18673f23393d7eeb2d490213e85ea912c Mon Sep 17 00:00:00 2001 From: David Koloski Date: Sun, 11 Aug 2024 01:14:09 -0400 Subject: [PATCH] Add StdError impls for core and alloc errors --- src/lib.rs | 43 ++--------------- src/std_error.rs | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 40 deletions(-) create mode 100644 src/std_error.rs diff --git a/src/lib.rs b/src/lib.rs index e1f3a00..247e67f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,8 @@ use std as alloc; #[cfg(feature = "alloc")] mod boxed_error; +// #[cfg(not(feature = "std"))] +mod std_error; #[cfg(feature = "alloc")] mod thin_box; @@ -47,47 +49,8 @@ use core::{ }; #[cfg(feature = "std")] pub use std::error::Error as StdError; - -#[cfg(not(feature = "std"))] -/// An error that can be debugged and displayed. -/// -/// With the `std` feature enabled, this is a re-export of the [`Error`] trait -/// instead. -/// -/// [`Error`]: std::error::Error -pub trait StdError: fmt::Debug + fmt::Display { - /// The lower-level source of this error, if any. - fn source(&self) -> Option<&(dyn StdError + 'static)> { - None - } -} - -#[cfg(not(feature = "std"))] -// SAFETY: The metadata type of `dyn StdError` is `DynMetadata`. -unsafe impl ptr_meta::Pointee for dyn StdError { - type Metadata = ptr_meta::DynMetadata; -} - -#[cfg(not(feature = "std"))] -// SAFETY: The metadata type of `dyn StdError + Send` is -// `DynMetadata`. -unsafe impl ptr_meta::Pointee for dyn StdError + Send { - type Metadata = ptr_meta::DynMetadata; -} - #[cfg(not(feature = "std"))] -// SAFETY: The metadata type of `dyn StdError + Sync` is -// `DynMetadata`. -unsafe impl ptr_meta::Pointee for dyn StdError + Sync { - type Metadata = ptr_meta::DynMetadata; -} - -#[cfg(not(feature = "std"))] -// SAFETY: The metadata type of `dyn StdError + Send + Sync` is -// `DynMetadata`. -unsafe impl ptr_meta::Pointee for dyn StdError + Send + Sync { - type Metadata = ptr_meta::DynMetadata; -} +pub use self::std_error::StdError; /// A type which can add an additional trace to itself. pub trait Trace: Sized + Send + Sync + 'static { diff --git a/src/std_error.rs b/src/std_error.rs new file mode 100644 index 0000000..7ff54bc --- /dev/null +++ b/src/std_error.rs @@ -0,0 +1,117 @@ +use core::{ + alloc::LayoutError, + array::TryFromSliceError, + cell::{BorrowError, BorrowMutError}, + char::{CharTryFromError, DecodeUtf16Error, ParseCharError, TryFromCharError}, + ffi::{ + FromBytesUntilNulError, + FromBytesWithNulError, + }, + fmt, + num::{ParseFloatError, ParseIntError, TryFromIntError}, str::{ParseBoolError, Utf8Error}, + time::TryFromFloatSecsError, +}; +#[cfg(feature = "alloc")] +use crate::alloc::{ + collections::TryReserveError, + ffi::{ + NulError, + FromVecWithNulError, + IntoStringError, + }, + string::{FromUtf16Error, FromUtf8Error}, +}; + +/// An error that can be debugged and displayed. +/// +/// With the `std` feature enabled, this is a re-export of the [`Error`] trait +/// instead. +/// +/// [`Error`]: std::error::Error +pub trait StdError: fmt::Debug + fmt::Display { + /// The lower-level source of this error, if any. + fn source(&self) -> Option<&(dyn StdError + 'static)> { + None + } +} + +// SAFETY: The metadata type of `dyn StdError` is `DynMetadata`. +unsafe impl ptr_meta::Pointee for dyn StdError { + type Metadata = ptr_meta::DynMetadata; +} + +// SAFETY: The metadata type of `dyn StdError + Send` is +// `DynMetadata`. +unsafe impl ptr_meta::Pointee for dyn StdError + Send { + type Metadata = ptr_meta::DynMetadata; +} + +// SAFETY: The metadata type of `dyn StdError + Sync` is +// `DynMetadata`. +unsafe impl ptr_meta::Pointee for dyn StdError + Sync { + type Metadata = ptr_meta::DynMetadata; +} + +// SAFETY: The metadata type of `dyn StdError + Send + Sync` is +// `DynMetadata`. +unsafe impl ptr_meta::Pointee for dyn StdError + Send + Sync { + type Metadata = ptr_meta::DynMetadata; +} + +impl StdError for &'_ T { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + T::source(self) + } +} + +#[cfg(feature = "alloc")] +impl StdError for crate::alloc::boxed::Box { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + T::source(self) + } +} + +#[cfg(feature = "alloc")] +impl StdError for crate::alloc::sync::Arc { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + T::source(self) + } +} + +macro_rules! impl_std_error { + ($($tys:ty),* $(,)?) => { + $( + impl StdError for $tys {} + )* + } +} + +impl_std_error! { + LayoutError, + TryFromSliceError, + BorrowError, + BorrowMutError, + CharTryFromError, + DecodeUtf16Error, + ParseCharError, + TryFromCharError, + FromBytesUntilNulError, + FromBytesWithNulError, + fmt::Error, + ParseFloatError, + ParseIntError, + TryFromIntError, + ParseBoolError, + Utf8Error, + FromUtf8Error, + FromUtf16Error, + TryFromFloatSecsError, +} + +#[cfg(feature = "alloc")] +impl_std_error! { + TryReserveError, + NulError, + FromVecWithNulError, + IntoStringError, +}