diff --git a/src/lib.rs b/src/lib.rs index 23359d8279..a15b15474a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -307,7 +307,7 @@ #![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr( __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, - feature(layout_for_ptr, strict_provenance, coverage_attribute) + feature(layout_for_ptr, strict_provenance, coverage_attribute, marker_trait_attr) )] // This is a hack to allow zerocopy-derive derives to work in this crate. They diff --git a/src/pointer/invariant.rs b/src/pointer/invariant.rs index c6543207dc..e52a458650 100644 --- a/src/pointer/invariant.rs +++ b/src/pointer/invariant.rs @@ -210,27 +210,27 @@ impl Validity for Valid { /// /// As a consequence, if `T: Read`, then any `Ptr` is /// permitted to perform unsynchronized reads from its referent. -pub trait Read {} +#[cfg_attr(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, marker)] +pub unsafe trait Read {} -impl Read for T {} -impl Read for T {} - -/// Used to disambiguate [`Read`] impls. -pub trait ReadReason: Sealed {} - -/// Unsynchronized reads are permitted because only one live [`Ptr`](crate::Ptr) -/// or reference may exist to the referent bytes at a time. -#[derive(Copy, Clone, Debug)] -#[doc(hidden)] -pub enum BecauseExclusive {} -impl ReadReason for BecauseExclusive {} - -/// Unsynchronized reads are permitted because no live [`Ptr`](crate::Ptr)s or -/// references permit interior mutation. -#[derive(Copy, Clone, Debug)] -#[doc(hidden)] -pub enum BecauseImmutable {} -impl ReadReason for BecauseImmutable {} +define_because!( + /// Unsynchronized reads are permitted because only one live + /// [`Ptr`](crate::Ptr) or reference may exist to the referent bytes at a + /// time. + #[doc(hidden)] + pub BecauseExclusive +); +// SAFETY: The aliasing parameter is `Exclusive`. +unsafe impl Read for T {} + +define_because!( + /// Unsynchronized reads are permitted because no live [`Ptr`](crate::Ptr)s + /// or references permit interior mutation. + #[doc(hidden)] + pub BecauseImmutable +); +// SAFETY: `T: Immutable`. +unsafe impl Read for T {} use sealed::Sealed; mod sealed { @@ -251,9 +251,6 @@ mod sealed { impl Sealed for Valid {} impl Sealed for (A, AA, V) {} - - impl Sealed for BecauseImmutable {} - impl Sealed for BecauseExclusive {} } pub use mapping::*; diff --git a/src/pointer/mod.rs b/src/pointer/mod.rs index e7b8c0e802..1b9bd44234 100644 --- a/src/pointer/mod.rs +++ b/src/pointer/mod.rs @@ -14,7 +14,7 @@ pub mod invariant; mod ptr; #[doc(hidden)] -pub use invariant::{BecauseExclusive, BecauseImmutable, Read, ReadReason}; +pub use invariant::{BecauseExclusive, BecauseImmutable, Read}; #[doc(hidden)] pub use ptr::Ptr; @@ -48,7 +48,6 @@ where pub fn read_unaligned(self) -> T where T: Copy, - R: invariant::ReadReason, T: invariant::Read, { // SAFETY: By invariant on `MaybeAligned`, `raw` contains diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs index cb729dbb4f..b476d1428f 100644 --- a/src/pointer/ptr.rs +++ b/src/pointer/ptr.rs @@ -658,7 +658,6 @@ mod _transitions { T: TryFromBytes + Read, I::Aliasing: Reference, I: Invariants, - R: crate::pointer::ReadReason, { // This call may panic. If that happens, it doesn't cause any soundness // issues, as we have not generated any invalid state which we need to @@ -805,8 +804,6 @@ mod _casts { where T: Read, U: 'a + ?Sized + Read, - R: ReadReason, - S: ReadReason, F: FnOnce(*mut T) -> *mut U, { // SAFETY: Because `T` and `U` both implement `Read`, @@ -829,7 +826,6 @@ mod _casts { #[allow(clippy::wrong_self_convention)] pub(crate) fn as_bytes(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Valid)> where - R: ReadReason, T: Read, I::Aliasing: Reference, { @@ -919,7 +915,6 @@ mod _casts { CastError, > where - R: ReadReason, I::Aliasing: Reference, U: 'a + ?Sized + KnownLayout + Read, { @@ -983,7 +978,6 @@ mod _casts { where I::Aliasing: Reference, U: 'a + ?Sized + KnownLayout + Read, - R: ReadReason, { match self.try_cast_into(CastType::Prefix, meta) { Ok((slf, remainder)) => { diff --git a/src/util/macro_util.rs b/src/util/macro_util.rs index bd8898a4b8..9d3f6ed77c 100644 --- a/src/util/macro_util.rs +++ b/src/util/macro_util.rs @@ -25,7 +25,7 @@ use core::mem::{self, ManuallyDrop}; use core::ptr::{self, NonNull}; use crate::{ - pointer::invariant::{self, BecauseExclusive, BecauseImmutable, Invariants, ReadReason}, + pointer::invariant::{self, BecauseExclusive, BecauseImmutable, Invariants}, Immutable, IntoBytes, Ptr, TryFromBytes, Unalign, ValidityError, }; @@ -528,7 +528,6 @@ where Dst: TryFromBytes + invariant::Read, I: Invariants, I::Aliasing: invariant::Reference, - R: ReadReason, { static_assert!(Src, Dst => mem::size_of::() == mem::size_of::()); diff --git a/src/util/macros.rs b/src/util/macros.rs index 9b33757e59..263fde6ac7 100644 --- a/src/util/macros.rs +++ b/src/util/macros.rs @@ -655,3 +655,14 @@ macro_rules! static_assert_dst_is_not_zst { }, "cannot call this method on a dynamically-sized type whose trailing slice element is zero-sized"); }} } + +macro_rules! define_because { + ($(#[$attr:meta])* $vis:vis $name:ident) => { + #[cfg(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)] + $(#[$attr])* + $vis type $name = (); + #[cfg(not(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS))] + $(#[$attr])* + $vis enum $name {} + }; +}