From 8f5670017dc27d937b60a7917a9ab344a4b1520f Mon Sep 17 00:00:00 2001
From: Joshua Liebow-Feeser <hello@joshlf.com>
Date: Sat, 12 Oct 2024 18:31:10 -0700
Subject: [PATCH] [WIP][pointer] Support generic TransmuteFrom

Makes progress on #1122
---
 src/impls.rs             |  78 ++++----
 src/lib.rs               |   2 +-
 src/pointer/invariant.rs | 145 ++++++++++++++-
 src/pointer/ptr.rs       |  44 ++---
 src/pointer/transmute.rs | 384 +++++++++------------------------------
 src/util/macros.rs       | 297 ++++++++++++++----------------
 src/wrappers.rs          |   8 +-
 7 files changed, 408 insertions(+), 550 deletions(-)

diff --git a/src/impls.rs b/src/impls.rs
index 0a552d52312..250704a55f8 100644
--- a/src/impls.rs
+++ b/src/impls.rs
@@ -443,13 +443,13 @@ mod atomics {
     use super::*;
 
     macro_rules! impl_traits_for_atomics {
-        ($($atomics:ident),* $(,)?) => {
+        ($($atomics:ident[$repr:ty]),* $(,)?) => {
             $(
                 impl_known_layout!($atomics);
-                impl_for_transparent_wrapper!(=> TryFromBytes for $atomics);
-                impl_for_transparent_wrapper!(=> FromZeros for $atomics);
-                impl_for_transparent_wrapper!(=> FromBytes for $atomics);
-                impl_for_transparent_wrapper!(=> IntoBytes for $atomics);
+                impl_for_transmute_from!(=> TryFromBytes for $atomics[$repr]);
+                impl_for_transmute_from!(=> FromZeros for $atomics[$repr]);
+                impl_for_transmute_from!(=> FromBytes for $atomics[$repr]);
+                impl_for_transmute_from!(=> IntoBytes for $atomics[$repr]);
             )*
         };
     }
@@ -461,13 +461,13 @@ mod atomics {
 
         use super::*;
 
-        impl_traits_for_atomics!(AtomicU8, AtomicI8);
+        impl_traits_for_atomics!(AtomicU8[u8], AtomicI8[i8]);
 
         impl_known_layout!(AtomicBool);
 
-        impl_for_transparent_wrapper!(=> TryFromBytes for AtomicBool);
-        impl_for_transparent_wrapper!(=> FromZeros for AtomicBool);
-        impl_for_transparent_wrapper!(=> IntoBytes for AtomicBool);
+        impl_for_transmute_from!(=> TryFromBytes for AtomicBool[bool]);
+        impl_for_transmute_from!(=> FromZeros for AtomicBool[bool]);
+        impl_for_transmute_from!(=> IntoBytes for AtomicBool[bool]);
 
         safety_comment! {
             /// SAFETY:
@@ -497,7 +497,7 @@ mod atomics {
             /// SAFETY:
             /// All of these pass an atomic type and that type's native equivalent, as
             /// required by the macro safety preconditions.
-            unsafe_impl_transparent_wrapper_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
+            unsafe_impl_transmute_from_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
         }
     }
 
@@ -508,13 +508,13 @@ mod atomics {
 
         use super::*;
 
-        impl_traits_for_atomics!(AtomicU16, AtomicI16);
+        impl_traits_for_atomics!(AtomicU16[u16], AtomicI16[i16]);
 
         safety_comment! {
             /// SAFETY:
             /// All of these pass an atomic type and that type's native equivalent, as
             /// required by the macro safety preconditions.
-            unsafe_impl_transparent_wrapper_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
+            unsafe_impl_transmute_from_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
         }
     }
 
@@ -525,13 +525,13 @@ mod atomics {
 
         use super::*;
 
-        impl_traits_for_atomics!(AtomicU32, AtomicI32);
+        impl_traits_for_atomics!(AtomicU32[u32], AtomicI32[i32]);
 
         safety_comment! {
             /// SAFETY:
             /// All of these pass an atomic type and that type's native equivalent, as
             /// required by the macro safety preconditions.
-            unsafe_impl_transparent_wrapper_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
+            unsafe_impl_transmute_from_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
         }
     }
 
@@ -542,13 +542,13 @@ mod atomics {
 
         use super::*;
 
-        impl_traits_for_atomics!(AtomicU64, AtomicI64);
+        impl_traits_for_atomics!(AtomicU64[u64], AtomicI64[i64]);
 
         safety_comment! {
             /// SAFETY:
             /// All of these pass an atomic type and that type's native equivalent, as
             /// required by the macro safety preconditions.
-            unsafe_impl_transparent_wrapper_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
+            unsafe_impl_transmute_from_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
         }
     }
 
@@ -559,21 +559,21 @@ mod atomics {
 
         use super::*;
 
-        impl_traits_for_atomics!(AtomicUsize, AtomicIsize);
+        impl_traits_for_atomics!(AtomicUsize[usize], AtomicIsize[isize]);
 
         impl_known_layout!(T => AtomicPtr<T>);
 
         // TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
         // those traits for `*mut T`.
-        impl_for_transparent_wrapper!(T => TryFromBytes for AtomicPtr<T>);
-        impl_for_transparent_wrapper!(T => FromZeros for AtomicPtr<T>);
+        impl_for_transmute_from!(T => TryFromBytes for AtomicPtr<T>[*mut T]);
+        impl_for_transmute_from!(T => FromZeros for AtomicPtr<T>[*mut T]);
 
         safety_comment! {
             /// SAFETY:
             /// This passes an atomic type and that type's native equivalent, as
             /// required by the macro safety preconditions.
-            unsafe_impl_transparent_wrapper_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
-            unsafe_impl_transparent_wrapper_for_atomic!(T => AtomicPtr<T> [*mut T]);
+            unsafe_impl_transmute_from_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
+            unsafe_impl_transmute_from_for_atomic!(T => AtomicPtr<T> [*mut T]);
         }
     }
 }
@@ -603,12 +603,12 @@ safety_comment! {
     assert_unaligned!(PhantomData<()>, PhantomData<u8>, PhantomData<u64>);
 }
 
-impl_for_transparent_wrapper!(T: Immutable => Immutable for Wrapping<T>);
-impl_for_transparent_wrapper!(T: TryFromBytes => TryFromBytes for Wrapping<T>);
-impl_for_transparent_wrapper!(T: FromZeros => FromZeros for Wrapping<T>);
-impl_for_transparent_wrapper!(T: FromBytes => FromBytes for Wrapping<T>);
-impl_for_transparent_wrapper!(T: IntoBytes => IntoBytes for Wrapping<T>);
-impl_for_transparent_wrapper!(T: Unaligned => Unaligned for Wrapping<T>);
+impl_for_transmute_from!(T: Immutable => Immutable for Wrapping<T>[T]);
+impl_for_transmute_from!(T: TryFromBytes => TryFromBytes for Wrapping<T>[T]);
+impl_for_transmute_from!(T: FromZeros => FromZeros for Wrapping<T>[T]);
+impl_for_transmute_from!(T: FromBytes => FromBytes for Wrapping<T>[T]);
+impl_for_transmute_from!(T: IntoBytes => IntoBytes for Wrapping<T>[T]);
+impl_for_transmute_from!(T: Unaligned => Unaligned for Wrapping<T>[T]);
 assert_unaligned!(Wrapping<()>, Wrapping<u8>);
 
 safety_comment! {
@@ -620,22 +620,22 @@ safety_comment! {
     unsafe_impl!(T => FromBytes for MaybeUninit<T>);
 }
 
-impl_for_transparent_wrapper!(T: Immutable => Immutable for MaybeUninit<T>);
-impl_for_transparent_wrapper!(T: Unaligned => Unaligned for MaybeUninit<T>);
+impl_for_transmute_from!(T: Immutable => Immutable for MaybeUninit<T>[T]);
+impl_for_transmute_from!(T: Unaligned => Unaligned for MaybeUninit<T>[T]);
 assert_unaligned!(MaybeUninit<()>, MaybeUninit<u8>);
 
-impl_for_transparent_wrapper!(T: ?Sized + Immutable => Immutable for ManuallyDrop<T>);
-impl_for_transparent_wrapper!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop<T>);
-impl_for_transparent_wrapper!(T: ?Sized + FromZeros => FromZeros for ManuallyDrop<T>);
-impl_for_transparent_wrapper!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>);
-impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for ManuallyDrop<T>);
-impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>);
+impl_for_transmute_from!(T: ?Sized + Immutable => Immutable for ManuallyDrop<T>[T]);
+impl_for_transmute_from!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop<T>[T]);
+impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for ManuallyDrop<T>[T]);
+impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>[T]);
+impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for ManuallyDrop<T>[T]);
+impl_for_transmute_from!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>[T]);
 assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
 
-impl_for_transparent_wrapper!(T: ?Sized + FromZeros => FromZeros for UnsafeCell<T>);
-impl_for_transparent_wrapper!(T: ?Sized + FromBytes => FromBytes for UnsafeCell<T>);
-impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell<T>);
-impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for UnsafeCell<T>);
+impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for UnsafeCell<T>[T]);
+impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for UnsafeCell<T>[T]);
+impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell<T>[T]);
+impl_for_transmute_from!(T: ?Sized + Unaligned => Unaligned for UnsafeCell<T>[T]);
 assert_unaligned!(UnsafeCell<()>, UnsafeCell<u8>);
 
 // SAFETY: See safety comment in `is_bit_valid` impl.
diff --git a/src/lib.rs b/src/lib.rs
index 2db7816c0e6..ef2ac427818 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2718,7 +2718,7 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
     // We use `from_mut` despite not mutating via `c_ptr` so that we don't need
     // to add a `T: Immutable` bound.
     let c_ptr = Ptr::from_mut(&mut candidate);
-    let c_ptr = c_ptr.transparent_wrapper_into_inner();
+    let c_ptr = c_ptr.transmute();
     // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
     // `candidate`, which the caller promises is entirely initialized.
     let c_ptr = unsafe { c_ptr.assume_validity::<invariant::Initialized>() };
diff --git a/src/pointer/invariant.rs b/src/pointer/invariant.rs
index 6a16071c6db..7fedd4e5e86 100644
--- a/src/pointer/invariant.rs
+++ b/src/pointer/invariant.rs
@@ -13,6 +13,8 @@
 //! Invariants are encoded as ([`Aliasing`], [`Alignment`], [`Validity`])
 //! triples implementing the [`Invariants`] trait.
 
+use super::*;
+
 /// The invariants of a [`Ptr`][super::Ptr].
 pub trait Invariants: Sealed {
     type Aliasing: Aliasing;
@@ -88,7 +90,14 @@ pub trait Validity: Sealed {
 ///
 /// Given `A: Reference`, callers may assume that either `A = Shared` or `A =
 /// Exclusive`.
-pub trait Reference: Aliasing + Sealed {}
+pub trait Reference: Aliasing + Sealed {
+    fn with<'a, T, I, S, E, O>(ptr: Ptr<'a, T, I>, shared: S, exclusive: E) -> O
+    where
+        T: 'a + ?Sized,
+        I: Invariants<Aliasing = Self>,
+        S: FnOnce(Ptr<'a, T, I::WithAliasing<Shared>>) -> O,
+        E: FnOnce(Ptr<'a, T, I::WithAliasing<Exclusive>>) -> O;
+}
 
 /// It is unknown whether any invariant holds.
 pub enum Unknown {}
@@ -130,7 +139,18 @@ impl Aliasing for Shared {
     type Variance<'a, T: 'a + ?Sized> = &'a T;
     type MappedTo<M: AliasingMapping> = M::FromShared;
 }
-impl Reference for Shared {}
+impl Reference for Shared {
+    #[inline(always)]
+    fn with<'a, T, I, S, E, O>(ptr: Ptr<'a, T, I>, shared: S, _exclusive: E) -> O
+    where
+        T: 'a + ?Sized,
+        I: Invariants<Aliasing = Shared>,
+        S: FnOnce(Ptr<'a, T, I::WithAliasing<Shared>>) -> O,
+        E: FnOnce(Ptr<'a, T, I::WithAliasing<Exclusive>>) -> O,
+    {
+        shared(ptr.unify_invariants())
+    }
+}
 
 /// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a mut T`.
 ///
@@ -143,10 +163,21 @@ impl Aliasing for Exclusive {
     type Variance<'a, T: 'a + ?Sized> = &'a mut T;
     type MappedTo<M: AliasingMapping> = M::FromExclusive;
 }
-impl Reference for Exclusive {}
+impl Reference for Exclusive {
+    #[inline(always)]
+    fn with<'a, T, I, S, E, O>(ptr: Ptr<'a, T, I>, _shared: S, exclusive: E) -> O
+    where
+        T: 'a + ?Sized,
+        I: Invariants<Aliasing = Exclusive>,
+        S: FnOnce(Ptr<'a, T, I::WithAliasing<Shared>>) -> O,
+        E: FnOnce(Ptr<'a, T, I::WithAliasing<Exclusive>>) -> O,
+    {
+        exclusive(ptr.unify_invariants())
+    }
+}
 
-/// The referent is aligned: for `Ptr<T>`, the referent's address is a
-/// multiple of the `T`'s alignment.
+/// The referent is aligned: for `Ptr<T>`, the referent's address is a multiple
+/// of the `T`'s alignment.
 pub enum Aligned {}
 impl Alignment for Aligned {
     type MappedTo<M: AlignmentMapping> = M::FromAligned;
@@ -183,8 +214,8 @@ impl Validity for AsInitialized {
     type MappedTo<M: ValidityMapping> = M::FromAsInitialized;
 }
 
-/// The byte ranges in the referent are fully initialized. In other words, if
-/// the referent is `N` bytes long, then it contains a bit-valid `[u8; N]`.
+/// The byte ranges in the referent are fully initialized. In other words,
+/// if the referent is `N` bytes long, then it contains a bit-valid `[u8; N]`.
 pub enum Initialized {}
 impl Validity for Initialized {
     type MappedTo<M: ValidityMapping> = M::FromInitialized;
@@ -260,6 +291,32 @@ pub use mapping::*;
 mod mapping {
     use super::*;
 
+    pub trait Mapping {
+        type Aliasing: AliasingMapping;
+        type Alignment: AlignmentMapping;
+        type Validity: ValidityMapping;
+    }
+
+    // TODO: How to make this less error prone? Right now, e.g.,
+    // `(Preserved, Unknown, Preserved)` and `(Unknown, Preserved, Preserved)` both
+    // implement `Mapping`, and it's not clear from the definition which
+    // order the invariants come in.
+    //
+    // First attempt was to do `Mapping for ((Aliasing, A), (Alignment, AA),
+    // (Validity, V))`, but not all of `Aliasing`, `Alignment`, and
+    // `Validity` are object safe.
+    impl<A: AliasingMapping, AA: AlignmentMapping, V: ValidityMapping> Mapping for (A, AA, V) {
+        type Aliasing = A;
+        type Alignment = AA;
+        type Validity = V;
+    }
+
+    impl Mapping for Preserved {
+        type Aliasing = Preserved;
+        type Alignment = Preserved;
+        type Validity = Preserved;
+    }
+
     pub trait AliasingMapping {
         type FromInaccessible: Aliasing;
         type FromShared: Aliasing;
@@ -278,6 +335,16 @@ mod mapping {
         type FromValid: Validity;
     }
 
+    // TODO: Better name?
+    pub enum Preserved {}
+
+    #[allow(type_alias_bounds)]
+    pub type Mapped<I: Invariants, M: Mapping> = (
+        MappedAliasing<I::Aliasing, M::Aliasing>,
+        MappedAlignment<I::Alignment, M::Alignment>,
+        MappedValidity<I::Validity, M::Validity>,
+    );
+
     #[allow(type_alias_bounds)]
     pub type MappedAliasing<I: Aliasing, M: AliasingMapping> = I::MappedTo<M>;
 
@@ -295,13 +362,40 @@ mod mapping {
         type FromExclusive = FromExclusive;
     }
 
+    pub enum UnsafeCellMismatch {}
+
+    impl AliasingMapping for UnsafeCellMismatch {
+        type FromShared = Unknown;
+        type FromExclusive = Exclusive;
+    }
+
+    impl AliasingMapping for Preserved {
+        type FromShared = Shared;
+        type FromExclusive = Exclusive;
+    }
+
     impl<FromUnknown: Alignment, FromAligned: Alignment> AlignmentMapping
-        for ((Unknown, FromUnknown), (Shared, FromAligned))
+        for ((Unknown, FromUnknown), (Aligned, FromAligned))
     {
         type FromUnknown = FromUnknown;
         type FromAligned = FromAligned;
     }
 
+    impl AlignmentMapping for Unknown {
+        type FromUnknown = Unknown;
+        type FromAligned = Unknown;
+    }
+
+    impl AlignmentMapping for Preserved {
+        type FromUnknown = Unknown;
+        type FromAligned = Aligned;
+    }
+
+    impl AlignmentMapping for Aligned {
+        type FromUnknown = Aligned;
+        type FromAligned = Aligned;
+    }
+
     impl<
             FromUnknown: Validity,
             FromAsInitialized: Validity,
@@ -327,4 +421,39 @@ mod mapping {
         type FromInitialized = FromInitialized;
         type FromValid = Unknown;
     }
+
+    impl ValidityMapping for Unknown {
+        type FromUnknown = Unknown;
+        type FromAsInitialized = Unknown;
+        type FromInitialized = Unknown;
+        type FromValid = Unknown;
+    }
+
+    impl ValidityMapping for Preserved {
+        type FromUnknown = Unknown;
+        type FromAsInitialized = AsInitialized;
+        type FromInitialized = Initialized;
+        type FromValid = Valid;
+    }
+
+    impl ValidityMapping for AsInitialized {
+        type FromUnknown = AsInitialized;
+        type FromAsInitialized = AsInitialized;
+        type FromInitialized = AsInitialized;
+        type FromValid = AsInitialized;
+    }
+
+    impl ValidityMapping for Initialized {
+        type FromUnknown = Initialized;
+        type FromAsInitialized = Initialized;
+        type FromInitialized = Initialized;
+        type FromValid = Initialized;
+    }
+
+    impl ValidityMapping for Valid {
+        type FromUnknown = Valid;
+        type FromAsInitialized = Valid;
+        type FromInitialized = Valid;
+        type FromValid = Valid;
+    }
 }
diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs
index 549f42dd480..d79fb1552cb 100644
--- a/src/pointer/ptr.rs
+++ b/src/pointer/ptr.rs
@@ -172,9 +172,7 @@ mod _external {
 /// Methods for converting to and from `Ptr` and Rust's safe reference types.
 mod _conversions {
     use super::*;
-    use crate::pointer::transmute::{
-        AlignmentVariance, Covariant, TransparentWrapper, ValidityVariance,
-    };
+    use crate::pointer::transmute::{TransmuteFrom, TransmuteFromPtr};
 
     /// `&'a T` → `Ptr<'a, T>`
     impl<'a, T> Ptr<'a, T, (Shared, Aligned, Valid)>
@@ -350,25 +348,17 @@ mod _conversions {
         }
     }
 
-    /// `Ptr<'a, T = Wrapper<U>>` → `Ptr<'a, U>`
+    /// `Ptr<'a, T>` → `Ptr<'a, U>`
     impl<'a, T, I> Ptr<'a, T, I>
     where
-        T: 'a + TransparentWrapper<I, UnsafeCellVariance = Covariant> + ?Sized,
+        T: 'a + ?Sized,
         I: Invariants,
     {
-        /// Converts `self` to a transparent wrapper type into a `Ptr` to the
-        /// wrapped inner type.
-        pub(crate) fn transparent_wrapper_into_inner(
-            self,
-        ) -> Ptr<
-            'a,
-            T::Inner,
-            (
-                I::Aliasing,
-                <T::AlignmentVariance as AlignmentVariance<I::Alignment>>::Applied,
-                <T::ValidityVariance as ValidityVariance<I::Validity>>::Applied,
-            ),
-        > {
+        pub(crate) fn transmute<U, R>(self) -> Ptr<'a, U, Mapped<I, U::Mapping>>
+        where
+            U: ?Sized + TransmuteFromPtr<T, I::Aliasing, R>,
+            R: crate::pointer::ReadReason,
+        {
             // SAFETY:
             // - By invariant on `TransparentWrapper::cast_into_inner`:
             //   - This cast preserves address and referent size, and thus the
@@ -379,20 +369,8 @@ mod _conversions {
             //   byte ranges. Since `p` and the returned pointer address the
             //   same byte range, they refer to `UnsafeCell`s at the same byte
             //   ranges.
-            let c = unsafe { self.cast_unsized_unchecked(|p| T::cast_into_inner(p)) };
-            // SAFETY: By invariant on `TransparentWrapper`, since `self`
-            // satisfies the alignment invariant `I::Alignment`, `c` (of type
-            // `T::Inner`) satisfies the given "applied" alignment invariant.
-            let c = unsafe {
-                c.assume_alignment::<<T::AlignmentVariance as AlignmentVariance<I::Alignment>>::Applied>()
-            };
-            // SAFETY: By invariant on `TransparentWrapper`, since `self`
-            // satisfies the validity invariant `I::Validity`, `c` (of type
-            // `T::Inner`) satisfies the given "applied" validity invariant.
-            let c = unsafe {
-                c.assume_validity::<<T::ValidityVariance as ValidityVariance<I::Validity>>::Applied>()
-            };
-            c
+            let ptr = unsafe { self.cast_unsized_unchecked(|p| U::cast_from(p)) };
+            unsafe { ptr.assume_invariants() }
         }
     }
 
@@ -478,7 +456,7 @@ mod _transitions {
         /// # Safety
         ///
         /// The caller promises that `self` satisfies the invariants `H`.
-        const unsafe fn assume_invariants<H: Invariants>(self) -> Ptr<'a, T, H> {
+        pub(super) const unsafe fn assume_invariants<H: Invariants>(self) -> Ptr<'a, T, H> {
             // SAFETY: The caller has promised to satisfy all parameterized
             // invariants of `Ptr`. `Ptr`'s other invariants are satisfied
             // by-contract by the source `Ptr`.
diff --git a/src/pointer/transmute.rs b/src/pointer/transmute.rs
index 113eb60ec31..c24bed812c8 100644
--- a/src/pointer/transmute.rs
+++ b/src/pointer/transmute.rs
@@ -12,348 +12,132 @@ use core::{
     num::Wrapping,
 };
 
-use crate::{
-    pointer::invariant::{self, Invariants},
-    Unalign,
-};
+use crate::{pointer::invariant::*, Unalign};
 
-/// A type which has the same layout as the type it wraps.
-///
-/// # Safety
-///
-/// `T: TransparentWrapper` implies that `T` has the same size as [`T::Inner`].
-/// Further, `T: TransparentWrapper<I>` implies that:
-/// - If `T::UnsafeCellVariance = Covariant`, then `T` has `UnsafeCell`s
-///   covering the same byte ranges as `T::Inner`.
-/// - If a `T` pointer satisfies the alignment invariant `I::Alignment`, then
-///   that same pointer, cast to `T::Inner`, satisfies the alignment invariant
-///   `<T::AlignmentVariance as AlignmentVariance<I::Alignment>>::Applied`.
-/// - If a `T` pointer satisfies the validity invariant `I::Validity`, then that
-///   same pointer, cast to `T::Inner`, satisfies the validity invariant
-///   `<T::ValidityVariance as ValidityVariance<I::Validity>>::Applied`.
-///
-/// [`T::Inner`]: TransparentWrapper::Inner
-/// [`UnsafeCell`]: core::cell::UnsafeCell
-/// [`T::AlignmentVariance`]: TransparentWrapper::AlignmentVariance
-/// [`T::ValidityVariance`]: TransparentWrapper::ValidityVariance
-#[doc(hidden)]
-pub unsafe trait TransparentWrapper<I: Invariants> {
-    type Inner: ?Sized;
+use super::{BecauseExclusive, BecauseImmutable, ReadReason};
 
-    type UnsafeCellVariance;
-    type AlignmentVariance: AlignmentVariance<I::Alignment>;
-    type ValidityVariance: ValidityVariance<I::Validity>;
+pub unsafe trait TransmuteFromPtr<T: ?Sized, A: Aliasing, R: ReadReason>:
+    TransmuteFrom<T>
+{
+}
 
-    /// Casts a wrapper pointer to an inner pointer.
-    ///
-    /// # Safety
-    ///
-    /// The resulting pointer has the same address and provenance as `ptr`, and
-    /// addresses the same number of bytes.
-    fn cast_into_inner(ptr: *mut Self) -> *mut Self::Inner;
+unsafe impl<T, U> TransmuteFromPtr<T, Shared, BecauseImmutable> for U
+where
+    T: ?Sized + crate::Immutable,
+    U: ?Sized + crate::Immutable + TransmuteFrom<T>,
+{
+}
+
+unsafe impl<T, U> TransmuteFromPtr<T, Shared, BecauseExclusive> for U
+where
+    T: ?Sized + TransmuteFrom<U>,
+    U: ?Sized + TransmuteFrom<T>,
+{
+}
+
+unsafe impl<T, U> TransmuteFromPtr<T, Exclusive, BecauseExclusive> for U
+where
+    T: ?Sized + TransmuteFrom<U>,
+    U: ?Sized + TransmuteFrom<T>,
+{
+}
+
+pub unsafe trait TransmuteFrom<T: ?Sized> {
+    type Mapping: Mapping;
 
-    /// Casts an inner pointer to a wrapper pointer.
+    /// Casts a `*mut T` to a `*mut Self`.
     ///
     /// # Safety
     ///
     /// The resulting pointer has the same address and provenance as `ptr`, and
     /// addresses the same number of bytes.
-    fn cast_from_inner(ptr: *mut Self::Inner) -> *mut Self;
+    fn cast_from(ptr: *mut T) -> *mut Self;
 }
 
-#[allow(unreachable_pub)]
-#[doc(hidden)]
-pub trait AlignmentVariance<I: invariant::Alignment> {
-    type Applied: invariant::Alignment;
-}
+unsafe impl<T: ?Sized> TransmuteFrom<T> for T {
+    type Mapping = Preserved;
 
-#[allow(unreachable_pub)]
-#[doc(hidden)]
-pub trait ValidityVariance<I: invariant::Validity> {
-    type Applied: invariant::Validity;
+    fn cast_from(ptr: *mut T) -> *mut T {
+        ptr
+    }
 }
 
-#[doc(hidden)]
-#[allow(missing_copy_implementations, missing_debug_implementations)]
-pub enum Covariant {}
-
-impl<I: invariant::Alignment> AlignmentVariance<I> for Covariant {
-    type Applied = I;
-}
+unsafe impl<T> TransmuteFrom<T> for MaybeUninit<T> {
+    type Mapping = (Preserved, Preserved, Valid);
 
-impl<I: invariant::Validity> ValidityVariance<I> for Covariant {
-    type Applied = I;
+    fn cast_from(ptr: *mut T) -> *mut MaybeUninit<T> {
+        ptr.cast()
+    }
 }
 
-#[doc(hidden)]
-#[allow(missing_copy_implementations, missing_debug_implementations)]
-pub enum Invariant {}
-
-impl<I: invariant::Alignment> AlignmentVariance<I> for Invariant {
-    type Applied = invariant::Unknown;
-}
+unsafe impl<T> TransmuteFrom<MaybeUninit<T>> for T {
+    type Mapping = (Preserved, Preserved, Unknown);
 
-impl<I: invariant::Validity> ValidityVariance<I> for Invariant {
-    type Applied = invariant::Unknown;
+    fn cast_from(ptr: *mut MaybeUninit<T>) -> *mut T {
+        ptr.cast()
+    }
 }
 
-// SAFETY:
-// - Per [1], `MaybeUninit<T>` has the same size as `T`.
-// - See inline comments for other safety justifications.
-//
-// [1] Per https://doc.rust-lang.org/1.81.0/std/mem/union.MaybeUninit.html#layout-1:
-//
-//   `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as
-//   `T`
-unsafe impl<T, I: Invariants> TransparentWrapper<I> for MaybeUninit<T> {
-    type Inner = T;
-
-    // SAFETY: `MaybeUninit<T>` has `UnsafeCell`s covering the same byte ranges
-    // as `Inner = T`. This is not explicitly documented, but it can be
-    // inferred. Per [1] in the preceding safety comment, `MaybeUninit<T>` has
-    // the same size as `T`. Further, note the signature of
-    // `MaybeUninit::assume_init_ref` [2]:
-    //
-    //   pub unsafe fn assume_init_ref(&self) -> &T
-    //
-    // If the argument `&MaybeUninit<T>` and the returned `&T` had `UnsafeCell`s
-    // at different offsets, this would be unsound. Its existence is proof that
-    // this is not the case.
-    //
-    // [2] https://doc.rust-lang.org/1.81.0/std/mem/union.MaybeUninit.html#method.assume_init_ref
-    type UnsafeCellVariance = Covariant;
-    // SAFETY: Per [1], `MaybeUninit<T>` has the same layout as `T`, and thus
-    // has the same alignment as `T`.
-    //
-    // [1] Per https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#layout-1:
-    //
-    //   `MaybeUninit<T>` is guaranteed to have the same size, alignment, and
-    //   ABI as `T`.
-    type AlignmentVariance = Covariant;
-    // SAFETY: `MaybeUninit` has no validity invariants. Thus, a valid
-    // `MaybeUninit<T>` is not necessarily a valid `T`.
-    type ValidityVariance = Invariant;
-
-    #[inline(always)]
-    fn cast_into_inner(ptr: *mut MaybeUninit<T>) -> *mut T {
-        // SAFETY: Per [1] (from comment above), `MaybeUninit<T>` has the same
-        // layout as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        ptr.cast::<T>()
-    }
+unsafe impl<T: ?Sized> TransmuteFrom<T> for ManuallyDrop<T> {
+    type Mapping = Preserved;
 
-    #[inline(always)]
-    fn cast_from_inner(ptr: *mut T) -> *mut MaybeUninit<T> {
-        // SAFETY: Per [1] (from comment above), `MaybeUninit<T>` has the same
-        // layout as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        ptr.cast::<MaybeUninit<T>>()
+    fn cast_from(ptr: *mut T) -> *mut ManuallyDrop<T> {
+        ptr as *mut ManuallyDrop<T>
     }
 }
 
-// SAFETY:
-// - Per [1], `ManuallyDrop<T>` has the same size as `T`.
-// - See inline comments for other safety justifications.
-//
-// [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
-//
-//   `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
-//   `T`
-unsafe impl<T: ?Sized, I: Invariants> TransparentWrapper<I> for ManuallyDrop<T> {
-    type Inner = T;
-
-    // SAFETY: Per [1], `ManuallyDrop<T>` has `UnsafeCell`s covering the same
-    // byte ranges as `Inner = T`.
-    //
-    // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
-    //
-    //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
-    //   validity as `T`, and is subject to the same layout optimizations as
-    //   `T`. As a consequence, it has no effect on the assumptions that the
-    //   compiler makes about its contents.
-    type UnsafeCellVariance = Covariant;
-    // SAFETY: Per [1], `ManuallyDrop<T>` has the same layout as `T`, and thus
-    // has the same alignment as `T`.
-    //
-    // [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
-    //
-    //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
-    //   validity as `T`
-    type AlignmentVariance = Covariant;
-
-    // SAFETY: Per [1] (from comment above), `ManuallyDrop<T>` has the same bit
-    // validity as `T`.
-    type ValidityVariance = Covariant;
+unsafe impl<T: ?Sized> TransmuteFrom<ManuallyDrop<T>> for T {
+    type Mapping = Preserved;
 
-    #[inline(always)]
-    fn cast_into_inner(ptr: *mut ManuallyDrop<T>) -> *mut T {
-        // SAFETY: Per [1] (from comment above), `ManuallyDrop<T>` has the same
-        // layout as `T`. Thus, this cast preserves size even if `T` is unsized.
-        //
-        // This cast trivially preserves provenance.
-        #[allow(clippy::as_conversions)]
-        return ptr as *mut T;
-    }
-
-    #[inline(always)]
-    fn cast_from_inner(ptr: *mut T) -> *mut ManuallyDrop<T> {
-        // SAFETY: Per [1] (from comment above), `ManuallyDrop<T>` has the same
-        // layout as `T`. Thus, this cast preserves size even if `T` is unsized.
-        //
-        // This cast trivially preserves provenance.
-        #[allow(clippy::as_conversions)]
-        return ptr as *mut ManuallyDrop<T>;
+    fn cast_from(ptr: *mut ManuallyDrop<T>) -> *mut T {
+        ptr as *mut T
     }
 }
 
-// SAFETY:
-// - Per [1], `Wrapping<T>` has the same size as `T`.
-// - See inline comments for other safety justifications.
-//
-// [1] Per https://doc.rust-lang.org/1.81.0/std/num/struct.Wrapping.html#layout-1:
-//
-//   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
-unsafe impl<T, I: Invariants> TransparentWrapper<I> for Wrapping<T> {
-    type Inner = T;
-
-    // SAFETY: Per [1], `Wrapping<T>` has the same layout as `T`. Since its
-    // single field (of type `T`) is public, it would be a breaking change to
-    // add or remove fields. Thus, we know that `Wrapping<T>` contains a `T` (as
-    // opposed to just having the same size and alignment as `T`) with no pre-
-    // or post-padding. Thus, `Wrapping<T>` must have `UnsafeCell`s covering the
-    // same byte ranges as `Inner = T`.
-    //
-    // [1] Per https://doc.rust-lang.org/1.81.0/std/num/struct.Wrapping.html#layout-1:
-    //
-    //   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
-    type UnsafeCellVariance = Covariant;
-    // SAFETY: Per [1], `Wrapping<T>` has the same layout as `T`, and thus has
-    // the same alignment as `T`.
-    //
-    // [1] Per https://doc.rust-lang.org/core/num/struct.Wrapping.html#layout-1:
-    //
-    //   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
-    type AlignmentVariance = Covariant;
-
-    // SAFETY: `Wrapping<T>` has only one field, which is `pub` [2]. We are also
-    // guaranteed per [1] (from the comment above) that `Wrapping<T>` has the
-    // same layout as `T`. The only way for both of these to be true
-    // simultaneously is for `Wrapping<T>` to have the same bit validity as `T`.
-    // In particular, in order to change the bit validity, one of the following
-    // would need to happen:
-    // - `Wrapping` could change its `repr`, but this would violate the layout
-    //   guarantee.
-    // - `Wrapping` could add or change its fields, but this would be a
-    //   stability-breaking change.
-    //
-    // [2] https://doc.rust-lang.org/core/num/struct.Wrapping.html
-    type ValidityVariance = Covariant;
+unsafe impl<T> TransmuteFrom<T> for Wrapping<T> {
+    type Mapping = Preserved;
 
-    #[inline(always)]
-    fn cast_into_inner(ptr: *mut Wrapping<T>) -> *mut T {
-        // SAFETY: Per [1] (from comment above), `Wrapping<T>` has the same
-        // layout as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        ptr.cast::<T>()
-    }
-
-    #[inline(always)]
-    fn cast_from_inner(ptr: *mut T) -> *mut Wrapping<T> {
-        // SAFETY: Per [1] (from comment above), `Wrapping<T>` has the same
-        // layout as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        ptr.cast::<Wrapping<T>>()
+    fn cast_from(ptr: *mut T) -> *mut Wrapping<T> {
+        ptr.cast()
     }
 }
 
-// SAFETY:
-// - Per [1], `UnsafeCell<T>` has the same size as `T`.
-// - See inline comments for other safety justifications.
-//
-// [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
-//
-//   `UnsafeCell<T>` has the same in-memory representation as its inner type
-//   `T`.
-unsafe impl<T: ?Sized, I: Invariants> TransparentWrapper<I> for UnsafeCell<T> {
-    type Inner = T;
-
-    // SAFETY: Since we set this to `Invariant`, we make no safety claims.
-    type UnsafeCellVariance = Invariant;
-
-    // SAFETY: Per [1] (from comment on impl), `Unalign<T>` has the same
-    // representation as `T`, and thus has the same alignment as `T`.
-    type AlignmentVariance = Covariant;
+unsafe impl<T> TransmuteFrom<Wrapping<T>> for T {
+    type Mapping = Preserved;
 
-    // SAFETY: Per [1], `Unalign<T>` has the same bit validity as `T`.
-    // Technically the term "representation" doesn't guarantee this, but the
-    // subsequent sentence in the documentation makes it clear that this is the
-    // intention.
-    //
-    // [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
-    //
-    //   `UnsafeCell<T>` has the same in-memory representation as its inner type
-    //   `T`. A consequence of this guarantee is that it is possible to convert
-    //   between `T` and `UnsafeCell<T>`.
-    type ValidityVariance = Covariant;
-
-    #[inline(always)]
-    fn cast_into_inner(ptr: *mut UnsafeCell<T>) -> *mut T {
-        // SAFETY: Per [1] (from comment above), `UnsafeCell<T>` has the same
-        // representation as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        #[allow(clippy::as_conversions)]
-        return ptr as *mut T;
+    fn cast_from(ptr: *mut Wrapping<T>) -> *mut T {
+        ptr.cast()
     }
+}
+
+unsafe impl<T: ?Sized> TransmuteFrom<T> for UnsafeCell<T> {
+    type Mapping = (UnsafeCellMismatch, Preserved, Preserved);
 
-    #[inline(always)]
-    fn cast_from_inner(ptr: *mut T) -> *mut UnsafeCell<T> {
-        // SAFETY: Per [1] (from comment above), `UnsafeCell<T>` has the same
-        // representation as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        #[allow(clippy::as_conversions)]
-        return ptr as *mut UnsafeCell<T>;
+    fn cast_from(ptr: *mut T) -> *mut UnsafeCell<T> {
+        ptr as *mut UnsafeCell<T>
     }
 }
 
-// SAFETY: `Unalign<T>` promises to have the same size as `T`.
-//
-// See inline comments for other safety justifications.
-unsafe impl<T, I: Invariants> TransparentWrapper<I> for Unalign<T> {
-    type Inner = T;
-
-    // SAFETY: `Unalign<T>` promises to have `UnsafeCell`s covering the same
-    // byte ranges as `Inner = T`.
-    type UnsafeCellVariance = Covariant;
+unsafe impl<T: ?Sized> TransmuteFrom<UnsafeCell<T>> for T {
+    type Mapping = (UnsafeCellMismatch, Preserved, Preserved);
 
-    // SAFETY: Since `Unalign<T>` promises to have alignment 1 regardless of
-    // `T`'s alignment. Thus, an aligned pointer to `Unalign<T>` is not
-    // necessarily an aligned pointer to `T`.
-    type AlignmentVariance = Invariant;
+    fn cast_from(ptr: *mut UnsafeCell<T>) -> *mut T {
+        ptr as *mut T
+    }
+}
 
-    // SAFETY: `Unalign<T>` promises to have the same validity as `T`.
-    type ValidityVariance = Covariant;
+unsafe impl<T> TransmuteFrom<T> for Unalign<T> {
+    type Mapping = (Preserved, Aligned, Preserved);
 
-    #[inline(always)]
-    fn cast_into_inner(ptr: *mut Unalign<T>) -> *mut T {
-        // SAFETY: Per the safety comment on the impl block, `Unalign<T>` has
-        // the size as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        ptr.cast::<T>()
+    fn cast_from(ptr: *mut T) -> *mut Unalign<T> {
+        ptr.cast()
     }
+}
+
+unsafe impl<T> TransmuteFrom<Unalign<T>> for T {
+    type Mapping = (Preserved, Unknown, Preserved);
 
-    #[inline(always)]
-    fn cast_from_inner(ptr: *mut T) -> *mut Unalign<T> {
-        // SAFETY: Per the safety comment on the impl block, `Unalign<T>` has
-        // the size as `T`. Thus, this cast preserves size.
-        //
-        // This cast trivially preserves provenance.
-        ptr.cast::<Unalign<T>>()
+    fn cast_from(ptr: *mut Unalign<T>) -> *mut T {
+        ptr.cast()
     }
 }
diff --git a/src/util/macros.rs b/src/util/macros.rs
index af9f35bdb90..261dc43a080 100644
--- a/src/util/macros.rs
+++ b/src/util/macros.rs
@@ -190,160 +190,156 @@ macro_rules! unsafe_impl {
     };
 }
 
-/// Implements `$trait` for a type which implements `TransparentWrapper`.
+/// Implements `$trait` for a type which is `TransmuteFrom<$repr>` where `$repr:
+/// $trait`.
 ///
 /// Calling this macro is safe; the internals of the macro emit appropriate
 /// trait bounds which ensure that the given impl is sound.
-macro_rules! impl_for_transparent_wrapper {
+macro_rules! impl_for_transmute_from {
     (
         $(#[$attr:meta])*
         $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?)?
-        => $trait:ident for $ty:ty $(; |$candidate:ident $(: MaybeAligned<$ref_repr:ty>)? $(: Maybe<$ptr_repr:ty>)?| $is_bit_valid:expr)?
+        => $trait:ident for $ty:ty[$repr:ty] $(; |$candidate:ident $(: MaybeAligned<$ref_repr:ty>)? $(: Maybe<$ptr_repr:ty>)?| $is_bit_valid:expr)?
     ) => {
         $(#[$attr])*
         #[allow(non_local_definitions)]
 
         // This block implements `$trait` for `$ty` under the following
         // conditions:
-        // - `$ty: TransparentWrapper`
-        // - `$ty::Inner: $trait`
-        // - For some `Xxx`, `$ty::XxxVariance = Covariant` (`Xxx` is determined
-        //   by the `@define_is_transparent_wrapper` macro arms). This bound
-        //   ensures that some layout property is the same between `$ty` and
-        //   `$ty::Inner`. Which layout property this is depends on the trait
-        //   being implemented (for example, `FromBytes` is not concerned with
-        //   alignment, but is concerned with bit validity).
+        // - `$ty: TransmuteFrom<$repr>`
+        // - `$repr: $trait`
+        // - For some invariant `Xxx`, `$ty::Mapping: Mapping<Xxx = Preserved>`
+        //   (`Xxx` is determined by the `@define_is_transmute_from` macro
+        //   arms). This bound ensures that some layout property is the same
+        //   between `$ty` and `$repr`. Which layout property this is depends on
+        //   the trait being implemented (for example, `FromBytes` is not
+        //   concerned with alignment, but is concerned with bit validity).
         //
         // In other words, `$ty` is guaranteed to soundly implement `$trait`
-        // because some property of its layout is the same as `$ty::Inner`,
-        // which implements `$trait`. Most of the complexity in this macro is to
+        // because some property of its layout is the same as `$repr`, which
+        // implements `$trait`. Most of the complexity in this macro is to
         // ensure that the above-mentioned conditions are actually met, and that
-        // the proper variance (ie, the proper layout property) is chosen.
+        // the proper invariant (ie, the proper layout property) is chosen.
 
         // SAFETY:
-        // - `is_transparent_wrapper<I, W>` requires:
-        //   - `W: TransparentWrapper<I>`
-        //   - `W::Inner: $trait`
-        // - `f` is generic over `I: Invariants`, and in its body, calls
-        //   `is_transparent_wrapper::<I, $ty>()`. Thus, this code will only
-        //   compile if, for all `I: Invariants`:
-        //   - `$ty: TransparentWrapper<I>`
-        //   - `$ty::Inner: $trait`
+        // - `is_transmute_from<R, T>` requires:
+        //   - `R: $trait`
+        //   - `T: TransmuteFrom<R>`
+        //   - `T::Mapping: Mapping<$invariant = Preserved>`
+        // - `is_transmute_from<$repr, $ty>` is called in the body
         //
-        // These two facts - that `$ty: TransparentWrapper<I>` and that
-        // `$ty::Inner: $trait` - are the preconditions to the full safety
-        // proofs, which are completed below in the
-        // `@define_is_transparent_wrapper` macro arms. The safety proof is
+        // This enforces that `$repr: $trait`, `$ty: TransmuteFrom<$repr>`, and
+        // `$trait::Mapping: Mapping<$invariant = Preserved>`. `$invariant` is
+        // chosen below in the `@define_is_transmute_from` macro arms, which
+        // contain the full safety proofs. They use the facts in this safety
+        // comment as preconditions for their proofs. The safety proof is
         // slightly different for each trait.
         unsafe impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?)?> $trait for $ty {
             #[allow(dead_code, clippy::missing_inline_in_public_items)]
             #[cfg_attr(coverage_nightly, coverage(off))]
             fn only_derive_is_allowed_to_implement_this_trait() {
-                use crate::pointer::{invariant::Invariants, transmute::*};
-
-                impl_for_transparent_wrapper!(@define_is_transparent_wrapper $trait);
+                use crate::pointer::transmute::*;
 
-                #[cfg_attr(coverage_nightly, coverage(off))]
-                const fn f<I: Invariants, $($tyvar $(: $(? $optbound +)* $($bound +)*)?)?>() {
-                    is_transparent_wrapper::<I, $ty>();
-                }
+                impl_for_transmute_from!(@define_is_transmute_from $trait);
+                is_transmute_from::<$repr, $ty>();
             }
 
-            impl_for_transparent_wrapper!(
+            impl_for_transmute_from!(
                 @is_bit_valid
                 $(<$tyvar $(: $(? $optbound +)* $($bound +)*)?>)?
-                $trait for $ty
+                $trait for $ty[$repr]
             );
         }
     };
-    (@define_is_transparent_wrapper Immutable) => {
-        // SAFETY: `W: TransparentWrapper<UnsafeCellVariance = Covariant>`
-        // requires that `W` has `UnsafeCell`s at the same byte offsets as
-        // `W::Inner`. `W::Inner: Immutable` implies that `W::Inner` does not
-        // contain any `UnsafeCell`s, and so `W` does not contain any
-        // `UnsafeCell`s. Since `W = $ty`, `$ty` can soundly implement
-        // `Immutable`.
-        impl_for_transparent_wrapper!(@define_is_transparent_wrapper Immutable, UnsafeCellVariance)
-    };
-    (@define_is_transparent_wrapper FromZeros) => {
-        // SAFETY: `W: TransparentWrapper<ValidityVariance = Covariant>`
-        // requires that `W` has the same bit validity as `W::Inner`. `W::Inner:
-        // FromZeros` implies that the all-zeros bit pattern is a bit-valid
-        // instance of `W::Inner`, and so the all-zeros bit pattern is a
-        // bit-valid instance of `W`. Since `W = $ty`, `$ty` can soundly
-        // implement `FromZeros`.
-        impl_for_transparent_wrapper!(@define_is_transparent_wrapper FromZeros, ValidityVariance)
-    };
-    (@define_is_transparent_wrapper FromBytes) => {
-        // SAFETY: `W: TransparentWrapper<ValidityVariance = Covariant>`
-        // requires that `W` has the same bit validity as `W::Inner`. `W::Inner:
-        // FromBytes` implies that any initialized bit pattern is a bit-valid
-        // instance of `W::Inner`, and so any initialized bit pattern is a
-        // bit-valid instance of `W`. Since `W = $ty`, `$ty` can soundly
-        // implement `FromBytes`.
-        impl_for_transparent_wrapper!(@define_is_transparent_wrapper FromBytes, ValidityVariance)
-    };
-    (@define_is_transparent_wrapper IntoBytes) => {
-        // SAFETY: `W: TransparentWrapper<ValidityVariance = Covariant>`
-        // requires that `W` has the same bit validity as `W::Inner`. `W::Inner:
-        // IntoBytes` implies that no bit-valid instance of `W::Inner` contains
-        // uninitialized bytes, and so no bit-valid instance of `W` contains
-        // uninitialized bytes. Since `W = $ty`, `$ty` can soundly implement
-        // `IntoBytes`.
-        impl_for_transparent_wrapper!(@define_is_transparent_wrapper IntoBytes, ValidityVariance)
-    };
-    (@define_is_transparent_wrapper Unaligned) => {
-        // SAFETY: `W: TransparentWrapper<AlignmentVariance = Covariant>`
-        // requires that `W` has the same alignment as `W::Inner`. `W::Inner:
-        // Unaligned` implies `W::Inner`'s alignment is 1, and so `W`'s
-        // alignment is 1. Since `W = $ty`, `W` can soundly implement
-        // `Unaligned`.
-        impl_for_transparent_wrapper!(@define_is_transparent_wrapper Unaligned, AlignmentVariance)
-    };
-    (@define_is_transparent_wrapper TryFromBytes) => {
-        // SAFETY: `W: TransparentWrapper<ValidityVariance = Covariant>`
-        // requires that `W` has the same bit validity as `W::Inner`. `W::Inner:
-        // TryFromBytes` implies that `<W::Inner as
+    (@define_is_transmute_from Immutable) => {
+        // SAFETY: `T::Mapping: Mapping<Aliasing = Preserved>` ensures that `T`
+        // and `R` have `UnsafeCell`s at the same byte offsets. If this weren't
+        // the case, then it would be unsound to map `Shared` to `Shared` when
+        // transmuting from `R` to `T`. `R: Immutable` implies that `R` has no
+        // `UnsafeCell`s, and so `T` doesn't either. Since `T = $ty`, `$ty` can
+        // soundly implement `Immutable`.
+        impl_for_transmute_from!(@define_is_transmute_from Immutable, Aliasing)
+    };
+    (@define_is_transmute_from FromZeros) => {
+        // SAFETY: `T::Mapping: Mapping<Validity = Preserved>` requires that `T`
+        // has the same bit validity as `R`. `R: FromZeros` implies that the
+        // all-zeros bit pattern is a bit-valid instance of `R`, and so the
+        // all-zeros bit pattern is a bit-valid instance of `T`. Since `T =
+        // $ty`, `$ty` can soundly implement `FromZeros`.
+        impl_for_transmute_from!(@define_is_transmute_from FromZeros, Validity)
+    };
+    (@define_is_transmute_from FromBytes) => {
+        // SAFETY: `T::Mapping: Mapping<Validity = Preserved>` requires that `T`
+        // has the same bit validity as `R`. `R: FromBytes` implies that any
+        // initialized bit pattern is a bit-valid instance of `R`, and so the
+        // any initialized bit pattern is a bit-valid instance of `T`. Since `T
+        // = $ty`, `$ty` can soundly implement `FromBytes`.
+        impl_for_transmute_from!(@define_is_transmute_from FromBytes, Validity)
+    };
+    (@define_is_transmute_from IntoBytes) => {
+        // SAFETY: `T::Mapping: Mapping<Validity = Preserved>` requires that `T`
+        // has the same bit validity as `R`. `R: IntoBytes` implies that no
+        // bit-valid instance of `R` contains uninitialized bytes, and so no
+        // bit-valid instance of `T` does either. Since `T = $ty`, `$ty` can
+        // soundly implement `IntoBytes`.
+        impl_for_transmute_from!(@define_is_transmute_from IntoBytes, Validity)
+    };
+    (@define_is_transmute_from Unaligned) => {
+        // SAFETY: `T::Mapping: Mapping<Alignment = Preserved>` requires that
+        // `T` has the same alignment as `R`. `R: Unaligned` implies that
+        // `align_of::<R>() == 1`, and so `align_of::<T>() == 1`. Since `T =
+        // $ty`, `$ty` can soundly implement `Unaligned`.
+        impl_for_transmute_from!(@define_is_transmute_from Unaligned, Alignment)
+    };
+    (@define_is_transmute_from TryFromBytes) => {
+        // SAFETY: `T::Mapping: Mapping<Validity = Preserved>` requires that `T`
+        // has the same bit validity as `R`. `R: TryFromBytes` implies that `<R
+        // as TryFromBytes>::is_bit_valid(c)` only returns `true` if `c`
+        // references a bit-valid instance of `R`. Thus, `<R as
         // TryFromBytes>::is_bit_valid(c)` only returns `true` if `c` references
-        // a bit-valid instance of `W::Inner`. Thus, `<W::Inner as
-        // TryFromBytes>::is_bit_valid(c)` only returns `true` if `c` references
-        // a bit-valid instance of `W`. Below, we implement `<W as
-        // TryFromBytes>::is_bit_valid` by deferring to `<W::Inner as
-        // TryFromBytes>::is_bit_valid`. Since `W = $ty`, it is sound for `$ty`
-        // to implement `TryFromBytes` with this implementation of
-        // `is_bit_valid`.
-        impl_for_transparent_wrapper!(@define_is_transparent_wrapper TryFromBytes, ValidityVariance)
-    };
-    (@define_is_transparent_wrapper $trait:ident, $variance:ident) => {
+        // a bit-valid instance of `T`. Below, we implement `<T as
+        // TryFromBytes>::is_bit_valid` by deferring to `<R as
+        // TryFromBytes>::is_bit_valid`. Since `T = $ty`, it is sound for `$ty`
+        // to implement `TryFromBytes` with this `is_bit_valid` implementation.
+        impl_for_transmute_from!(@define_is_transmute_from TryFromBytes, Validity)
+    };
+    (@define_is_transmute_from $trait:ident, $invariant:ident) => {
         #[cfg_attr(coverage_nightly, coverage(off))]
-        const fn is_transparent_wrapper<I: Invariants, W: TransparentWrapper<I, $variance = Covariant> + ?Sized>()
+        const fn is_transmute_from<R, T: TransmuteFrom<R> + ?Sized>()
         where
-            W::Inner: $trait,
+            R: ?Sized + $trait,
+            T::Mapping: crate::pointer::invariant::Mapping<$invariant = crate::pointer::invariant::Preserved>
         {}
     };
     (
         @is_bit_valid
         $(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
-        TryFromBytes for $ty:ty
+        TryFromBytes for $ty:ty[$repr:ty]
     ) => {
-        // SAFETY: See safety comment in `(@define_is_transparent_wrapper
+        // SAFETY: See safety comment in `(@define_is_transmute_from
         // TryFromBytes)` macro arm for an explanation of why this is a sound
         // implementation of `is_bit_valid`.
         #[inline]
         fn is_bit_valid<A: crate::pointer::invariant::Reference>(candidate: Maybe<'_, Self, A>) -> bool {
-            TryFromBytes::is_bit_valid(candidate.transparent_wrapper_into_inner())
+            <$repr as TryFromBytes>::is_bit_valid(candidate.transmute())
+            // A::with(
+            //     candidate,
+            //     |shared| <$repr as TryFromBytes>::is_bit_valid(shared.transmute()),
+            //     |excl| <$repr as TryFromBytes>::is_bit_valid(excl.transmute()),
+            // )
         }
     };
     (
         @is_bit_valid
         $(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
-        $trait:ident for $ty:ty
+        $trait:ident for $ty:ty[$repr:ty]
     ) => {
         // Trait other than `TryFromBytes`; no `is_bit_valid` impl.
     };
 }
 
-/// Implements `TransparentWrapper` for an atomic type.
+/// Implements `TransmuteFrom<$native>` for an atomic type and
+/// vice-versa.
 ///
 /// # Safety
 ///
@@ -356,18 +352,22 @@ macro_rules! impl_for_transparent_wrapper {
     target_has_atomic = "64",
     target_has_atomic = "ptr"
 ))]
-macro_rules! unsafe_impl_transparent_wrapper_for_atomic {
+macro_rules! unsafe_impl_transmute_from_for_atomic {
     ($(#[$attr:meta])* $(,)?) => {};
     ($(#[$attr:meta])* $atomic:ty [$native:ty], $($atomics:ty [$natives:ty]),* $(,)?) => {
         $(#[$attr])*
         // SAFETY: See safety comment in next match arm.
-        unsafe impl<I: crate::invariant::Invariants> crate::pointer::transmute::TransparentWrapper<I> for $atomic {
-            unsafe_impl_transparent_wrapper_for_atomic!(@inner $atomic [$native]);
+        unsafe impl crate::pointer::transmute::TransmuteFrom<$native> for $atomic {
+            unsafe_impl_transmute_from_for_atomic!(@inner $native => $atomic);
+        }
+        // SAFETY: See safety comment in next match arm.
+        unsafe impl crate::pointer::transmute::TransmuteFrom<$atomic> for $native {
+            unsafe_impl_transmute_from_for_atomic!(@inner $atomic => $native);
         }
-        unsafe_impl_transparent_wrapper_for_atomic!($(#[$attr])* $($atomics [$natives],)*);
+        unsafe_impl_transmute_from_for_atomic!($(#[$attr])* $($atomics [$natives],)*);
     };
     ($(#[$attr:meta])* $tyvar:ident => $atomic:ty [$native:ty]) => {
-        // We implement for `$atomic` and set `Inner = $native`. The caller has
+        // We implement `TransmuteFrom<$native>` for `$atomic`. The caller has
         // promised that `$atomic` and `$native` are an atomic type and its
         // native counterpart, respectively. Per [1], `$atomic` and `$native`
         // have the same size.
@@ -377,71 +377,38 @@ macro_rules! unsafe_impl_transparent_wrapper_for_atomic {
         //   This type has the same size and bit validity as the underlying
         //   integer type
         $(#[$attr])*
-        unsafe impl<$tyvar, I: crate::invariant::Invariants> crate::pointer::transmute::TransparentWrapper<I> for $atomic {
-            unsafe_impl_transparent_wrapper_for_atomic!(@inner $atomic [$native]);
+        unsafe impl<$tyvar> crate::pointer::transmute::TransmuteFrom<$native> for $atomic {
+            unsafe_impl_transmute_from_for_atomic!(@inner $native => $atomic);
         }
-    };
-    (@inner $atomic:ty [$native:ty]) => {
-        type Inner = UnsafeCell<$native>;
-
-        // SAFETY: It is "obvious" that each atomic type contains a single
-        // `UnsafeCell` that covers all bytes of the type, but we can also prove
-        // it:
-        // - Since `$atomic` provides an API which permits loading and storing
-        //   values of type `$native` via a `&self` (shared) reference, *some*
-        //   interior mutation must be happening, and interior mutation can only
-        //   happen via `UnsafeCell`. Further, there must be enough bytes in
-        //   `$atomic` covered by an `UnsafeCell` to hold every possible value
-        //   of `$native`.
-        // - Per [1], `$atomic` has the same size as `$native`. This on its own
-        //   isn't enough: it would still be possible for `$atomic` to store
-        //   `$native` using a compact representation (for `$native` types for
-        //   which some bit patterns are illegal). However, this is ruled out by
-        //   the fact that `$atomic` has the same bit validity as `$native` [1].
-        //   Thus, we can conclude that every byte of `$atomic` must be covered
-        //   by an `UnsafeCell`.
-        //
-        // Thus, every byte of `$atomic` is covered by an `UnsafeCell`, and we
-        // set `type Inner = UnsafeCell<$native>`. Thus, `Self` and
-        // `Self::Inner` have `UnsafeCell`s covering the same byte ranges.
-        //
-        // [1] Per (for example) https://doc.rust-lang.org/1.81.0/std/sync/atomic/struct.AtomicU64.html:
-        //
-        //   This type has the same size and bit validity as the underlying
-        //   integer type
-        type UnsafeCellVariance = crate::pointer::transmute::Covariant;
 
-        // SAFETY: No safety justification is required for an invariant
-        // variance.
-        type AlignmentVariance = crate::pointer::transmute::Invariant;
-
-        // SAFETY: Per [1], all atomic types have the same bit validity as their
-        // native counterparts. The caller has promised that `$atomic` and
-        // `$native` are an atomic type and its native counterpart,
-        // respectively.
-        //
-        // [1] Per (for example) https://doc.rust-lang.org/1.81.0/std/sync/atomic/struct.AtomicU64.html:
-        //
-        //   This type has the same size and bit validity as the underlying
-        //   integer type
-        type ValidityVariance = crate::pointer::transmute::Covariant;
-
-        #[inline(always)]
-        fn cast_into_inner(ptr: *mut $atomic) -> *mut UnsafeCell<$native> {
-            // SAFETY: Per [1] (from comment on impl block), `$atomic` has the
-            // same size as `$native`. Thus, this cast preserves size.
-            //
-            // This cast trivially preserves provenance.
-            ptr.cast::<UnsafeCell<$native>>()
+        unsafe impl<$tyvar> crate::pointer::transmute::TransmuteFrom<$atomic> for $native {
+            unsafe_impl_transmute_from_for_atomic!(@inner $atomic => $native);
         }
+    };
+    (@inner $from:ty => $to:ty) => {
+        type Mapping = (
+            // SAFETY: The only invariant which is preserved is `Exclusive ->
+            // Exclusive`. It is always sound to preserve `Exclusive` regardless
+            // of the presence or absence of `UnsafeCell`s.
+            crate::pointer::invariant::UnsafeCellMismatch,
+            // SAFETY: No invariant is preserved; no safety proof required.
+            crate::pointer::invariant::Unknown,
+            // SAFETY: Per [1], all atomic types have the same bit validity as
+            // their native counterparts. The caller has promised that `$atomic`
+            // and `$native` are an atomic type and its native counterpart,
+            // respectively.
+            //
+            // [1] Per (for example) https://doc.rust-lang.org/1.81.0/std/sync/atomic/struct.AtomicU64.html:
+            //
+            //   This type has the same size and bit validity as the underlying
+            //   integer type
+            crate::pointer::invariant::Preserved,
+        );
 
         #[inline(always)]
-        fn cast_from_inner(ptr: *mut UnsafeCell<$native>) -> *mut $atomic {
-            // SAFETY: Per [1] (from comment on impl block), `$atomic` has the
-            // same size as `$native`. Thus, this cast preserves size.
-            //
-            // This cast trivially preserves provenance.
-            ptr.cast::<$atomic>()
+        #[allow(clippy::as_conversions)]
+        fn cast_from(ptr: *mut $from) -> *mut $to {
+            ptr as *mut $to
         }
     };
 }
diff --git a/src/wrappers.rs b/src/wrappers.rs
index ac2442486ed..b0707560b16 100644
--- a/src/wrappers.rs
+++ b/src/wrappers.rs
@@ -200,7 +200,7 @@ impl<T> Unalign<T> {
     /// may prefer [`Deref::deref`], which is infallible.
     #[inline(always)]
     pub fn try_deref(&self) -> Result<&T, AlignmentError<&Self, T>> {
-        let inner = Ptr::from_ref(self).transparent_wrapper_into_inner();
+        let inner = Ptr::from_ref(self).transmute();
         match inner.bikeshed_try_into_aligned() {
             Ok(aligned) => Ok(aligned.as_ref()),
             Err(err) => Err(err.map_src(|src| src.into_unalign().as_ref())),
@@ -217,7 +217,7 @@ impl<T> Unalign<T> {
     /// callers may prefer [`DerefMut::deref_mut`], which is infallible.
     #[inline(always)]
     pub fn try_deref_mut(&mut self) -> Result<&mut T, AlignmentError<&mut Self, T>> {
-        let inner = Ptr::from_mut(self).transparent_wrapper_into_inner();
+        let inner = Ptr::from_mut(self).transmute();
         match inner.bikeshed_try_into_aligned() {
             Ok(aligned) => Ok(aligned.as_mut()),
             Err(err) => Err(err.map_src(|src| src.into_unalign().as_mut())),
@@ -401,14 +401,14 @@ impl<T: Unaligned> Deref for Unalign<T> {
 
     #[inline(always)]
     fn deref(&self) -> &T {
-        Ptr::from_ref(self).transparent_wrapper_into_inner().bikeshed_recall_aligned().as_ref()
+        Ptr::from_ref(self).transmute().bikeshed_recall_aligned().as_ref()
     }
 }
 
 impl<T: Unaligned> DerefMut for Unalign<T> {
     #[inline(always)]
     fn deref_mut(&mut self) -> &mut T {
-        Ptr::from_mut(self).transparent_wrapper_into_inner().bikeshed_recall_aligned().as_mut()
+        Ptr::from_mut(self).transmute().bikeshed_recall_aligned().as_mut()
     }
 }