diff --git a/Cargo.toml b/Cargo.toml index 84b61e9cb7..60dc116f43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,10 +60,11 @@ alloc = [] derive = ["zerocopy-derive"] simd = [] simd-nightly = ["simd"] +std-error = ["alloc"] # This feature depends on all other features that work on the stable compiler. # We make no stability guarantees about this feature; it may be modified or # removed at any time. -__internal_use_only_features_that_work_on_stable = ["alloc", "derive", "simd"] +__internal_use_only_features_that_work_on_stable = ["alloc", "derive", "simd", "std-error"] [dependencies] zerocopy-derive = { version = "=0.8.0-alpha.14", path = "zerocopy-derive", optional = true } diff --git a/src/error.rs b/src/error.rs index fff9e4d36e..d30d8dee03 100644 --- a/src/error.rs +++ b/src/error.rs @@ -25,9 +25,9 @@ use core::{convert::Infallible, fmt, marker::PhantomData, ops::Deref}; -use crate::TryFromBytes; #[cfg(doc)] use crate::{FromBytes, Ref}; +use crate::{KnownLayout, TryFromBytes}; /// Zerocopy's generic error type. /// @@ -82,6 +82,15 @@ impl fmt::Display for Convert } } +#[cfg(feature = "std-error")] +impl std::error::Error for ConvertError +where + A: fmt::Display + fmt::Debug, + S: fmt::Display + fmt::Debug, + V: fmt::Display + fmt::Debug, +{ +} + /// The error emitted if the conversion source is improperly aligned. #[derive(PartialEq, Eq)] pub struct AlignmentError { @@ -126,9 +135,10 @@ impl fmt::Debug for AlignmentError { // The bounds on this impl are intentionally conservative, and can be relaxed // either once a `?Sized` alignment accessor is stabilized, or by storing the // alignment as a runtime value. -impl fmt::Display for AlignmentError +impl fmt::Display for AlignmentError where Src: Deref, + Dst: KnownLayout, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -139,14 +149,22 @@ where f.write_str("the conversion failed because the address of the source (a multiple of ")?; addr_align.fmt(f)?; f.write_str(") is not a multiple of the alignment (")?; - core::mem::align_of::().fmt(f)?; + ::LAYOUT.align.get().fmt(f)?; f.write_str(") of the destination type: ")?; f.write_str(core::any::type_name::())?; Ok(()) } } -impl From> +#[cfg(feature = "std-error")] +impl std::error::Error for AlignmentError +where + Src: Deref, + Dst: KnownLayout, +{ +} + +impl From> for ConvertError, S, V> { #[inline] @@ -216,7 +234,10 @@ where } } -impl From> for ConvertError, V> { +#[cfg(feature = "std-error")] +impl std::error::Error for SizeError where Src: Deref {} + +impl From> for ConvertError, V> { #[inline] fn from(err: SizeError) -> Self { Self::Size(err) @@ -274,6 +295,9 @@ where } } +#[cfg(feature = "std-error")] +impl std::error::Error for ValidityError where Src: Deref {} + impl From> for ConvertError> { diff --git a/src/lib.rs b/src/lib.rs index 084d5fe743..7627a4b6c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -255,7 +255,7 @@ clippy::arithmetic_side_effects, clippy::indexing_slicing, ))] -#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(any(test, feature = "std-error")), no_std)] #![cfg_attr( all(feature = "simd-nightly", any(target_arch = "x86", target_arch = "x86_64")), feature(stdarch_x86_avx512)