Skip to content

Commit

Permalink
[error] Implement std::error::Error on errors
Browse files Browse the repository at this point in the history
While we're here, also relax `Dispaly for AlignmentError<Src, Dst>` to
permit `Dst: ?Sized` in exchange for `Dst: KnownLayout`. This is an
important relaxation since our APIs permit performing conversions into
unsized destination types with runtime alignment checking.

Makes progress on #1297
  • Loading branch information
joshlf committed May 18, 2024
1 parent 1c77a9d commit a688425
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
34 changes: 29 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -82,6 +82,15 @@ impl<A: fmt::Display, S: fmt::Display, V: fmt::Display> fmt::Display for Convert
}
}

#[cfg(feature = "std-error")]
impl<A, S, V> std::error::Error for ConvertError<A, S, V>
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<Src, Dst: ?Sized> {
Expand Down Expand Up @@ -126,9 +135,10 @@ impl<Src, Dst: ?Sized> fmt::Debug for AlignmentError<Src, Dst> {
// 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<Src, Dst> fmt::Display for AlignmentError<Src, Dst>
impl<Src, Dst: ?Sized> fmt::Display for AlignmentError<Src, Dst>
where
Src: Deref,
Dst: KnownLayout,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand All @@ -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::<Dst>().fmt(f)?;
<Dst as KnownLayout>::LAYOUT.align.get().fmt(f)?;
f.write_str(") of the destination type: ")?;
f.write_str(core::any::type_name::<Dst>())?;
Ok(())
}
}

impl<Src, Dst, S, V> From<AlignmentError<Src, Dst>>
#[cfg(feature = "std-error")]
impl<Src, Dst: ?Sized> std::error::Error for AlignmentError<Src, Dst>
where
Src: Deref,
Dst: KnownLayout,
{
}

impl<Src, Dst: ?Sized, S, V> From<AlignmentError<Src, Dst>>
for ConvertError<AlignmentError<Src, Dst>, S, V>
{
#[inline]
Expand Down Expand Up @@ -216,7 +234,10 @@ where
}
}

impl<Src, Dst, A, V> From<SizeError<Src, Dst>> for ConvertError<A, SizeError<Src, Dst>, V> {
#[cfg(feature = "std-error")]
impl<Src, Dst: ?Sized> std::error::Error for SizeError<Src, Dst> where Src: Deref {}

impl<Src, Dst: ?Sized, A, V> From<SizeError<Src, Dst>> for ConvertError<A, SizeError<Src, Dst>, V> {
#[inline]
fn from(err: SizeError<Src, Dst>) -> Self {
Self::Size(err)
Expand Down Expand Up @@ -274,6 +295,9 @@ where
}
}

#[cfg(feature = "std-error")]
impl<Src, Dst: ?Sized + TryFromBytes> std::error::Error for ValidityError<Src, Dst> where Src: Deref {}

impl<Src, Dst: ?Sized + TryFromBytes, A, S> From<ValidityError<Src, Dst>>
for ConvertError<A, S, ValidityError<Src, Dst>>
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit a688425

Please sign in to comment.