From 846c36ecb3c1bb97e2e88126e421f4e21540242e Mon Sep 17 00:00:00 2001 From: raldone01 Date: Tue, 9 Sep 2025 22:52:51 +0200 Subject: [PATCH 1/2] Fix spelling. --- src/error.rs | 6 +++--- src/impls.rs | 2 +- src/lib.rs | 2 +- src/pointer/ptr.rs | 4 ++-- src/ref.rs | 4 ++-- src/util/mod.rs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/error.rs b/src/error.rs index c8bf6afa72..c4cc8fb87d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -246,7 +246,7 @@ where pub struct AlignmentError { /// The source value involved in the conversion. src: Src, - /// The inner destination type inolved in the conversion. + /// The inner destination type involved in the conversion. /// /// INVARIANT: An `AlignmentError` may only be constructed if `Dst`'s /// alignment requirement is greater than one. @@ -412,7 +412,7 @@ impl From> pub struct SizeError { /// The source value involved in the conversion. src: Src, - /// The inner destination type inolved in the conversion. + /// The inner destination type involved in the conversion. dst: SendSyncPhantomData, } @@ -556,7 +556,7 @@ impl From> for ConvertError { /// The source value involved in the conversion. pub(crate) src: Src, - /// The inner destination type inolved in the conversion. + /// The inner destination type involved in the conversion. dst: SendSyncPhantomData, } diff --git a/src/impls.rs b/src/impls.rs index 296c9bd8c5..3dca4f5866 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -812,7 +812,7 @@ unsafe impl TryFromBytes for UnsafeCell { // // `is_bit_valid` is documented as panicking or failing to monomorphize // if called with a shared-aliased pointer on a type containing an - // `UnsafeCell`. In practice, it will always be a monorphization error. + // `UnsafeCell`. In practice, it will always be a monomorphization error. // Since `is_bit_valid` is `#[doc(hidden)]` and only called directly // from this crate, we only need to worry about our own code incorrectly // calling `UnsafeCell::is_bit_valid`. The post-monomorphization error diff --git a/src/lib.rs b/src/lib.rs index 0c3a5417e5..9e4dc1e53d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -630,7 +630,7 @@ use {FromZeros as FromZeroes, IntoBytes as AsBytes, Ref as LayoutVerified}; /// example. /// /// A `#[repr(C)]` slice DST is laid out [just like sized `#[repr(C)]` -/// types][repr-c-structs], but the presenence of a variable-length field +/// types][repr-c-structs], but the presence of a variable-length field /// introduces the possibility of *dynamic padding*. In particular, it may be /// necessary to add trailing padding *after* the trailing slice field in order /// to satisfy the outer type's alignment, and the amount of padding required diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs index d40a1e8143..4d3fa7bf3d 100644 --- a/src/pointer/ptr.rs +++ b/src/pointer/ptr.rs @@ -118,7 +118,7 @@ mod _external { /// referent of a `Ptr>`. Since this copy /// does not change `I::Validity` or `T`, `S(T, I::Validity)` is also /// unchanged. - /// + /// /// We are required to guarantee that the referents of the original `Ptr` /// and of the copy (which, of course, are actually the same since they /// live in the same byte address range) both remain in the set `S(T, @@ -815,7 +815,7 @@ mod _transitions { // contains a bit-valid instance of `T`. By `T: // TryTransmuteFromPtr`, so // long as `self`'s referent conforms to the `Valid` validity - // for `T` (which we just confired), then this transmute is + // for `T` (which we just confirmed), then this transmute is // sound. Ok(unsafe { self.assume_valid() }) } else { diff --git a/src/ref.rs b/src/ref.rs index 10334cf7f3..352a9fc02b 100644 --- a/src/ref.rs +++ b/src/ref.rs @@ -717,7 +717,7 @@ where let b = unsafe { r.as_byte_slice() }; // SAFETY: By postcondition on `as_byte_slice`, we know that `b` is a - // valid size and ailgnment for `T`. By safety invariant on `ByteSlice`, + // valid size and alignment for `T`. By safety invariant on `ByteSlice`, // we know that this is preserved via `.deref()`. Because `T: // FromBytes`, it is sound to interpret these bytes as a `T`. unsafe { ptr::read(b.deref().as_ptr().cast::()) } @@ -741,7 +741,7 @@ where let b = unsafe { r.as_byte_slice_mut() }; // SAFETY: By postcondition on `as_byte_slice_mut`, we know that `b` is - // a valid size and ailgnment for `T`. By safety invariant on + // a valid size and alignment for `T`. By safety invariant on // `ByteSlice`, we know that this is preserved via `.deref()`. Writing // `t` to the buffer will allow all of the bytes of `t` to be accessed // as a `[u8]`, but because `T: IntoBytes`, we know that this is sound. diff --git a/src/util/mod.rs b/src/util/mod.rs index 34d6ef0049..85a42fbdb8 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -281,7 +281,7 @@ pub(crate) const unsafe fn transmute_unchecked(src: Src) -> Dst { // SAFETY: Since `Transmute` is `#[repr(C)]`, its `src` and `dst` // fields both start at the same offset and the types of those fields are // transparent wrappers around `Src` and `Dst` [1]. Consequently, - // initializng `Transmute` with with `src` and then reading out `dst` is + // initializing `Transmute` with with `src` and then reading out `dst` is // equivalent to transmuting from `Src` to `Dst` [2]. Transmuting from `src` // to `Dst` is valid because — by contract on the caller — `src` is a valid // instance of `Dst`. From 9e6dc73889e3db933f5b80ec584507c87215eb8e Mon Sep 17 00:00:00 2001 From: raldone01 Date: Tue, 9 Sep 2025 23:11:13 +0200 Subject: [PATCH 2/2] Make errors Clone. Manually implement PartialEq, Eq and Clone for types using SendSyncPhantomData. This is necessary because the default derive imposes an additional PartialEq/Eq/Clone bounds on the phantom type. --- src/error.rs | 119 +++++++++++++++++++++++++++++++++++++++++------- src/util/mod.rs | 10 +++- 2 files changed, 111 insertions(+), 18 deletions(-) diff --git a/src/error.rs b/src/error.rs index c4cc8fb87d..3f09ceae17 100644 --- a/src/error.rs +++ b/src/error.rs @@ -149,7 +149,7 @@ use crate::{FromBytes, Ref}; /// - [`CastError`]: the error type of reference conversions /// - [`TryCastError`]: the error type of fallible reference conversions /// - [`TryReadError`]: the error type of fallible read conversions -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, Clone)] pub enum ConvertError { /// The conversion source was improperly aligned. Alignment(A), @@ -242,7 +242,6 @@ where } /// The error emitted if the conversion source is improperly aligned. -#[derive(PartialEq, Eq)] pub struct AlignmentError { /// The source value involved in the conversion. src: Src, @@ -250,7 +249,7 @@ pub struct AlignmentError { /// /// INVARIANT: An `AlignmentError` may only be constructed if `Dst`'s /// alignment requirement is greater than one. - dst: SendSyncPhantomData, + _dst: SendSyncPhantomData, } impl AlignmentError { @@ -261,7 +260,7 @@ impl AlignmentError { pub(crate) unsafe fn new_unchecked(src: Src) -> Self { // INVARIANT: The caller guarantees that `Dst`'s alignment requirement // is greater than one. - Self { src, dst: SendSyncPhantomData::default() } + Self { src, _dst: SendSyncPhantomData::default() } } /// Produces the source underlying the failed conversion. @@ -274,7 +273,7 @@ impl AlignmentError { // INVARIANT: `with_src` doesn't change the type of `Dst`, so the // invariant that `Dst`'s alignment requirement is greater than one is // preserved. - AlignmentError { src: new_src, dst: SendSyncPhantomData::default() } + AlignmentError { src: new_src, _dst: SendSyncPhantomData::default() } } /// Maps the source value associated with the conversion error. @@ -299,7 +298,7 @@ impl AlignmentError { /// ``` #[inline] pub fn map_src(self, f: impl FnOnce(Src) -> NewSrc) -> AlignmentError { - AlignmentError { src: f(self.src), dst: SendSyncPhantomData::default() } + AlignmentError { src: f(self.src), _dst: SendSyncPhantomData::default() } } pub(crate) fn into(self) -> ConvertError { @@ -337,6 +336,22 @@ impl AlignmentError { } } +impl Clone for AlignmentError { + #[inline] + fn clone(&self) -> Self { + Self { src: self.src.clone(), _dst: SendSyncPhantomData::default() } + } +} + +impl PartialEq for AlignmentError { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.src == other.src + } +} + +impl Eq for AlignmentError {} + impl From> for Infallible { #[inline(always)] fn from(_: AlignmentError) -> Infallible { @@ -408,17 +423,16 @@ impl From> } /// The error emitted if the conversion source is of incorrect size. -#[derive(PartialEq, Eq)] pub struct SizeError { /// The source value involved in the conversion. src: Src, /// The inner destination type involved in the conversion. - dst: SendSyncPhantomData, + _dst: SendSyncPhantomData, } impl SizeError { pub(crate) fn new(src: Src) -> Self { - Self { src, dst: SendSyncPhantomData::default() } + Self { src, _dst: SendSyncPhantomData::default() } } /// Produces the source underlying the failed conversion. @@ -429,7 +443,7 @@ impl SizeError { /// Sets the source value associated with the conversion error. pub(crate) fn with_src(self, new_src: NewSrc) -> SizeError { - SizeError { src: new_src, dst: SendSyncPhantomData::default() } + SizeError { src: new_src, _dst: SendSyncPhantomData::default() } } /// Maps the source value associated with the conversion error. @@ -455,12 +469,12 @@ impl SizeError { /// ``` #[inline] pub fn map_src(self, f: impl FnOnce(Src) -> NewSrc) -> SizeError { - SizeError { src: f(self.src), dst: SendSyncPhantomData::default() } + SizeError { src: f(self.src), _dst: SendSyncPhantomData::default() } } /// Sets the destination type associated with the conversion error. pub(crate) fn with_dst(self) -> SizeError { - SizeError { src: self.src, dst: SendSyncPhantomData::default() } + SizeError { src: self.src, _dst: SendSyncPhantomData::default() } } /// Converts the error into a general [`ConvertError`]. @@ -507,6 +521,22 @@ impl SizeError { } } +impl Clone for SizeError { + #[inline] + fn clone(&self) -> Self { + Self { src: self.src.clone(), _dst: SendSyncPhantomData::default() } + } +} + +impl PartialEq for SizeError { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.src == other.src + } +} + +impl Eq for SizeError {} + impl fmt::Debug for SizeError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -552,17 +582,16 @@ impl From> for ConvertError { /// The source value involved in the conversion. pub(crate) src: Src, /// The inner destination type involved in the conversion. - dst: SendSyncPhantomData, + _dst: SendSyncPhantomData, } impl ValidityError { pub(crate) fn new(src: Src) -> Self { - Self { src, dst: SendSyncPhantomData::default() } + Self { src, _dst: SendSyncPhantomData::default() } } /// Produces the source underlying the failed conversion. @@ -593,7 +622,7 @@ impl ValidityError { /// ``` #[inline] pub fn map_src(self, f: impl FnOnce(Src) -> NewSrc) -> ValidityError { - ValidityError { src: f(self.src), dst: SendSyncPhantomData::default() } + ValidityError { src: f(self.src), _dst: SendSyncPhantomData::default() } } /// Converts the error into a general [`ConvertError`]. @@ -614,6 +643,22 @@ impl ValidityError { } } +impl Clone for ValidityError { + #[inline] + fn clone(&self) -> Self { + Self { src: self.src.clone(), _dst: SendSyncPhantomData::default() } + } +} + +impl PartialEq for ValidityError { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.src == other.src + } +} + +impl Eq for ValidityError {} + impl fmt::Debug for ValidityError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -993,6 +1038,48 @@ mod tests { } } + #[test] + fn test_eq_partial_eq_clone() { + // Test that all error types implement `Eq`, `PartialEq` + // and `Clone` if src does + // even if `Dst: !Eq`, `!PartialEq`, `!Clone`. + + #[allow(dead_code)] + fn is_eq_partial_eq_clone(_t: T) {} + + #[allow(dead_code)] + fn alignment_err_is_eq_partial_eq_clone( + err: AlignmentError, + ) { + is_eq_partial_eq_clone(err) + } + + #[allow(dead_code)] + fn size_err_is_eq_partial_eq_clone( + err: SizeError, + ) { + is_eq_partial_eq_clone(err) + } + + #[allow(dead_code)] + fn validity_err_is_eq_partial_eq_clone( + err: ValidityError, + ) { + is_eq_partial_eq_clone(err) + } + + #[allow(dead_code)] + fn convert_error_is_eq_partial_eq_clone( + err: ConvertError< + AlignmentError, + SizeError, + ValidityError, + >, + ) { + is_eq_partial_eq_clone(err) + } + } + #[test] fn alignment_display() { #[repr(C, align(128))] diff --git a/src/util/mod.rs b/src/util/mod.rs index 85a42fbdb8..9c04e5df48 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -39,13 +39,19 @@ impl Default for SendSyncPhantomData { } impl PartialEq for SendSyncPhantomData { - fn eq(&self, other: &Self) -> bool { - self.0.eq(&other.0) + fn eq(&self, _other: &Self) -> bool { + true } } impl Eq for SendSyncPhantomData {} +impl Clone for SendSyncPhantomData { + fn clone(&self) -> Self { + SendSyncPhantomData(PhantomData) + } +} + pub(crate) trait AsAddress { fn addr(self) -> usize; }