// SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
//
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.

#![allow(missing_docs)]

use core::{
    fmt::{Debug, Formatter},
    marker::PhantomData,
};

use crate::{
    pointer::{
        inner::PtrInner,
        invariant::*,
        transmute::{MutationCompatible, SizeEq, TransmuteFromPtr},
    },
    AlignmentError, CastError, CastType, KnownLayout, SizeError, TryFromBytes, ValidityError,
};

/// Module used to gate access to [`Ptr`]'s fields.
mod def {
    #[cfg(doc)]
    use super::super::invariant;
    use super::*;

    /// A raw pointer with more restrictions.
    ///
    /// `Ptr<T>` is similar to [`NonNull<T>`], but it is more restrictive in the
    /// following ways (note that these requirements only hold of non-zero-sized
    /// referents):
    /// - It must derive from a valid allocation.
    /// - It must reference a byte range which is contained inside the
    ///   allocation from which it derives.
    ///   - As a consequence, the byte range it references must have a size
    ///     which does not overflow `isize`.
    ///
    /// Depending on how `Ptr` is parameterized, it may have additional
    /// invariants:
    /// - `ptr` conforms to the aliasing invariant of
    ///   [`I::Aliasing`](invariant::Aliasing).
    /// - `ptr` conforms to the alignment invariant of
    ///   [`I::Alignment`](invariant::Alignment).
    /// - `ptr` conforms to the validity invariant of
    ///   [`I::Validity`](invariant::Validity).
    ///
    /// `Ptr<'a, T>` is [covariant] in `'a` and invariant in `T`.
    ///
    /// [`NonNull<T>`]: core::ptr::NonNull
    /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
    pub struct Ptr<'a, T, I>
    where
        T: ?Sized,
        I: Invariants,
    {
        /// # Invariants
        ///
        /// 0. `ptr` conforms to the aliasing invariant of
        ///    [`I::Aliasing`](invariant::Aliasing).
        /// 1. `ptr` conforms to the alignment invariant of
        ///    [`I::Alignment`](invariant::Alignment).
        /// 2. `ptr` conforms to the validity invariant of
        ///    [`I::Validity`](invariant::Validity).
        // SAFETY: `PtrInner<'a, T>` is covariant in `'a` and invariant in `T`.
        ptr: PtrInner<'a, T>,
        _invariants: PhantomData<I>,
    }

    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants,
    {
        /// Constructs a new `Ptr` from a [`PtrInner`].
        ///
        /// # Safety
        ///
        /// The caller promises that:
        ///
        /// 0. `ptr` conforms to the aliasing invariant of
        ///    [`I::Aliasing`](invariant::Aliasing).
        /// 1. `ptr` conforms to the alignment invariant of
        ///    [`I::Alignment`](invariant::Alignment).
        /// 2. `ptr` conforms to the validity invariant of
        ///    [`I::Validity`](invariant::Validity).
        pub(crate) unsafe fn from_inner(ptr: PtrInner<'a, T>) -> Ptr<'a, T, I> {
            // SAFETY: The caller has promised to satisfy all safety invariants
            // of `Ptr`.
            Self { ptr, _invariants: PhantomData }
        }

        /// Converts this `Ptr<T>` to a [`PtrInner<T>`].
        ///
        /// Note that this method does not consume `self`. The caller should
        /// watch out for `unsafe` code which uses the returned value in a way
        /// that violates the safety invariants of `self`.
        #[inline]
        #[must_use]
        pub fn as_inner(&self) -> PtrInner<'a, T> {
            self.ptr
        }
    }
}

#[allow(unreachable_pub)] // This is a false positive on our MSRV toolchain.
pub use def::Ptr;

/// External trait implementations on [`Ptr`].
mod _external {
    use super::*;

    /// SAFETY: Shared pointers are safely `Copy`. `Ptr`'s other invariants
    /// (besides aliasing) are unaffected by the number of references that exist
    /// to `Ptr`'s referent. The notable cases are:
    /// - Alignment is a property of the referent type (`T`) and the address,
    ///   both of which are unchanged
    /// - Let `S(T, V)` be the set of bit values permitted to appear in the
    ///   referent of a `Ptr<T, I: Invariants<Validity = V>>`. 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,
    ///   I::Validity)`. Since this invariant holds on the original `Ptr`, it
    ///   cannot be violated by the original `Ptr`, and thus the original `Ptr`
    ///   cannot be used to violate this invariant on the copy. The inverse
    ///   holds as well.
    impl<'a, T, I> Copy for Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants<Aliasing = Shared>,
    {
    }

    /// SAFETY: See the safety comment on `Copy`.
    impl<'a, T, I> Clone for Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants<Aliasing = Shared>,
    {
        #[inline]
        fn clone(&self) -> Self {
            *self
        }
    }

    impl<'a, T, I> Debug for Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants,
    {
        #[inline]
        fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
            self.as_inner().as_non_null().fmt(f)
        }
    }
}

/// Methods for converting to and from `Ptr` and Rust's safe reference types.
mod _conversions {
    use super::*;
    use crate::pointer::cast::{CastExact, CastSized, IdCast};

    /// `&'a T` → `Ptr<'a, T>`
    impl<'a, T> Ptr<'a, T, (Shared, Aligned, Safe)>
    where
        T: 'a + ?Sized,
    {
        /// Constructs a `Ptr` from a shared reference.
        #[inline(always)]
        pub fn from_ref(ptr: &'a T) -> Self {
            let inner = PtrInner::from_ref(ptr);
            // SAFETY:
            // 0. `ptr`, by invariant on `&'a T`, conforms to the aliasing
            //    invariant of `Shared`.
            // 1. `ptr`, by invariant on `&'a T`, conforms to the alignment
            //    invariant of `Aligned`.
            // 2. `ptr`'s referent, by invariant on `&'a T`, is a bit-valid `T`.
            //    This satisfies the requirement that a `Ptr<T, (_, _, Safe)>`
            //    point to a bit-valid `T`. Even if `T` permits interior
            //    mutation, this invariant guarantees that the returned `Ptr` can
            //    only ever be used to modify the referent to store bit-valid
            //    `T`s, which ensures that the returned `Ptr` cannot be used to
            //    violate the soundness of the original `ptr: &'a T` or of any
            //    other references that may exist to the same referent.
            unsafe { Self::from_inner(inner) }
        }
    }

    /// `&'a mut T` → `Ptr<'a, T>`
    impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Safe)>
    where
        T: 'a + ?Sized,
    {
        /// Constructs a `Ptr` from an exclusive reference.
        #[inline(always)]
        pub fn from_mut(ptr: &'a mut T) -> Self {
            let inner = PtrInner::from_mut(ptr);
            // SAFETY:
            // 0. `ptr`, by invariant on `&'a mut T`, conforms to the aliasing
            //    invariant of `Exclusive`.
            // 1. `ptr`, by invariant on `&'a mut T`, conforms to the alignment
            //    invariant of `Aligned`.
            // 2. `ptr`'s referent, by invariant on `&'a mut T`, is a bit-valid
            //    `T`. This satisfies the requirement that a `Ptr<T, (_, _,
            //    Safe)>` point to a bit-valid `T`. This invariant guarantees
            //    that the returned `Ptr` can only ever be used to modify the
            //    referent to store bit-valid `T`s, which ensures that the
            //    returned `Ptr` cannot be used to violate the soundness of the
            //    original `ptr: &'a mut T`.
            unsafe { Self::from_inner(inner) }
        }
    }

    /// `Ptr<'a, T>` → `&'a T`
    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants<Alignment = Aligned, Validity = Safe>,
        I::Aliasing: Reference,
    {
        /// Converts `self` to a shared reference.
        // This consumes `self`, not `&self`, because `self` is, logically, a
        // pointer. For `I::Aliasing = invariant::Shared`, `Self: Copy`, and so
        // this doesn't prevent the caller from still using the pointer after
        // calling `as_ref`.
        #[allow(clippy::wrong_self_convention)]
        #[inline]
        #[must_use]
        pub fn as_ref(self) -> &'a T {
            let raw = self.as_inner().as_non_null();
            // SAFETY: `self` satisfies the `Aligned` invariant, so we know that
            // `raw` is validly-aligned for `T`.
            #[cfg(all(miri, __ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE))]
            unsafe {
                crate::util::miri_promise_symbolic_alignment(
                    raw.as_ptr().cast(),
                    core::mem::align_of_val_raw(raw.as_ptr()),
                );
            }
            // SAFETY: This invocation of `NonNull::as_ref` satisfies its
            // documented safety preconditions:
            //
            // 1. The pointer is properly aligned. This is ensured by-contract
            //    on `Ptr`, because the `I::Alignment` is `Aligned`.
            //
            // 2. If the pointer's referent is not zero-sized, then the pointer
            //    must be “dereferenceable” in the sense defined in the module
            //    documentation; i.e.:
            //
            //    > The memory range of the given size starting at the pointer
            //    > must all be within the bounds of a single allocated object.
            //    > [2]
            //
            //   This is ensured by contract on all `PtrInner`s.
            //
            // 3. The pointer must point to a validly-initialized instance of
            //    `T`. This is ensured by-contract on `Ptr`, because the
            //    `I::Validity` is `Safe`.
            //
            // 4. You must enforce Rust’s aliasing rules. This is ensured by
            //    contract on `Ptr`, because `I::Aliasing: Reference`. Either it
            //    is `Shared` or `Exclusive`. If it is `Shared`, other
            //    references may not mutate the referent outside of
            //    `UnsafeCell`s.
            //
            // [1]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_ref
            // [2]: https://doc.rust-lang.org/std/ptr/index.html#safety
            unsafe { raw.as_ref() }
        }
    }

    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants,
        I::Aliasing: Reference,
    {
        /// Reborrows `self`, producing another `Ptr`.
        ///
        /// Since `self` is borrowed mutably, this prevents any methods from
        /// being called on `self` as long as the returned `Ptr` exists.
        #[inline]
        #[must_use]
        #[allow(clippy::needless_lifetimes)] // Allows us to name the lifetime in the safety comment below.
        pub fn reborrow<'b>(&'b mut self) -> Ptr<'b, T, I>
        where
            'a: 'b,
        {
            // SAFETY: The following all hold by invariant on `self`, and thus
            // hold of `ptr = self.as_inner()`:
            // 0. SEE BELOW.
            // 1. `ptr` conforms to the alignment invariant of
            //    [`I::Alignment`](invariant::Alignment).
            // 2. `ptr` conforms to the validity invariant of
            //    [`I::Validity`](invariant::Validity). `self` and the returned
            //    `Ptr` permit the same bit values in their referents since they
            //    have the same referent type (`T`) and the same validity
            //    (`I::Validity`). Thus, regardless of what mutation is
            //    permitted (`Exclusive` aliasing or `Shared`-aliased interior
            //    mutation), neither can be used to write a value to the
            //    referent which violates the other's validity invariant.
            //
            // For aliasing (0 above), since `I::Aliasing: Reference`,
            // there are two cases for `I::Aliasing`:
            // - For `invariant::Shared`: `'a` outlives `'b`, and so the
            //   returned `Ptr` does not permit accessing the referent any
            //   longer than is possible via `self`. For shared aliasing, it is
            //   sound for multiple `Ptr`s to exist simultaneously which
            //   reference the same memory, so creating a new one is not
            //   problematic.
            // - For `invariant::Exclusive`: Since `self` is `&'b mut` and we
            //   return a `Ptr` with lifetime `'b`, `self` is inaccessible to
            //   the caller for the lifetime `'b` - in other words, `self` is
            //   inaccessible to the caller as long as the returned `Ptr`
            //   exists. Since `self` is an exclusive `Ptr`, no other live
            //   references or `Ptr`s may exist which refer to the same memory
            //   while `self` is live. Thus, as long as the returned `Ptr`
            //   exists, no other references or `Ptr`s which refer to the same
            //   memory may be live.
            unsafe { Ptr::from_inner(self.as_inner()) }
        }

        /// Reborrows `self` as shared, producing another `Ptr` with `Shared`
        /// aliasing.
        ///
        /// Since `self` is borrowed mutably, this prevents any methods from
        /// being called on `self` as long as the returned `Ptr` exists.
        #[inline]
        #[must_use]
        #[allow(clippy::needless_lifetimes)] // Allows us to name the lifetime in the safety comment below.
        pub fn reborrow_shared<'b>(&'b mut self) -> Ptr<'b, T, (Shared, I::Alignment, I::Validity)>
        where
            'a: 'b,
        {
            // SAFETY: The following all hold by invariant on `self`, and thus
            // hold of `ptr = self.as_inner()`:
            // 0. SEE BELOW.
            // 1. `ptr` conforms to the alignment invariant of
            //    [`I::Alignment`](invariant::Alignment).
            // 2. `ptr` conforms to the validity invariant of
            //    [`I::Validity`](invariant::Validity). `self` and the returned
            //    `Ptr` permit the same bit values in their referents since they
            //    have the same referent type (`T`) and the same validity
            //    (`I::Validity`). Thus, regardless of what mutation is
            //    permitted (`Exclusive` aliasing or `Shared`-aliased interior
            //    mutation), neither can be used to write a value to the
            //    referent which violates the other's validity invariant.
            //
            // For aliasing (0 above), since `I::Aliasing: Reference`,
            // there are two cases for `I::Aliasing`:
            // - For `invariant::Shared`: `'a` outlives `'b`, and so the
            //   returned `Ptr` does not permit accessing the referent any
            //   longer than is possible via `self`. For shared aliasing, it is
            //   sound for multiple `Ptr`s to exist simultaneously which
            //   reference the same memory, so creating a new one is not
            //   problematic.
            // - For `invariant::Exclusive`: Since `self` is `&'b mut` and we
            //   return a `Ptr` with lifetime `'b`, `self` is inaccessible to
            //   the caller for the lifetime `'b` - in other words, `self` is
            //   inaccessible to the caller as long as the returned `Ptr`
            //   exists. Since `self` is an exclusive `Ptr`, no other live
            //   references or `Ptr`s may exist which refer to the same memory
            //   while `self` is live. Thus, as long as the returned `Ptr`
            //   exists, no other references or `Ptr`s which refer to the same
            //   memory may be live.
            unsafe { Ptr::from_inner(self.as_inner()) }
        }
    }

    /// `Ptr<'a, T>` → `&'a mut T`
    impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Safe)>
    where
        T: 'a + ?Sized,
    {
        /// Converts `self` to a mutable reference.
        #[allow(clippy::wrong_self_convention)]
        #[inline]
        #[must_use]
        pub fn as_mut(self) -> &'a mut T {
            let mut raw = self.as_inner().as_non_null();
            // SAFETY: `self` satisfies the `Aligned` invariant, so we know that
            // `raw` is validly-aligned for `T`.
            #[cfg(all(miri, __ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE))]
            unsafe {
                crate::util::miri_promise_symbolic_alignment(
                    raw.as_ptr().cast(),
                    core::mem::align_of_val_raw(raw.as_ptr()),
                );
            }
            // SAFETY: This invocation of `NonNull::as_mut` satisfies its
            // documented safety preconditions:
            //
            // 1. The pointer is properly aligned. This is ensured by-contract
            //    on `Ptr`, because the `ALIGNMENT_INVARIANT` is `Aligned`.
            //
            // 2. If the pointer's referent is not zero-sized, then the pointer
            //    must be “dereferenceable” in the sense defined in the module
            //    documentation; i.e.:
            //
            //    > The memory range of the given size starting at the pointer
            //    > must all be within the bounds of a single allocated object.
            //    > [2]
            //
            //   This is ensured by contract on all `PtrInner`s.
            //
            // 3. The pointer must point to a validly-initialized instance of
            //    `T`. This is ensured by-contract on `Ptr`, because the validity
            //    invariant is `Safe`.
            //
            // 4. You must enforce Rust’s aliasing rules. This is ensured by
            //    contract on `Ptr`, because the `ALIASING_INVARIANT` is
            //    `Exclusive`.
            //
            // [1]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_mut
            // [2]: https://doc.rust-lang.org/std/ptr/index.html#safety
            unsafe { raw.as_mut() }
        }
    }

    /// `Ptr<'a, T>` → `Ptr<'a, U>`
    impl<'a, T: ?Sized, I> Ptr<'a, T, I>
    where
        I: Invariants,
    {
        /// Reinterprets the same byte region as `U` with validity `V`.
        ///
        /// This preserves the aliasing invariant, uses [`SizeEq`] to select a
        /// [`CastExact`] implementation, and conservatively forgets alignment.
        #[must_use]
        #[inline(always)]
        pub fn transmute<U, V, R>(self) -> Ptr<'a, U, (I::Aliasing, Unaligned, V)>
        where
            V: Validity,
            U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, <U as SizeEq<T>>::CastFrom, R>
                + SizeEq<T>
                + ?Sized,
        {
            self.transmute_with::<U, V, <U as SizeEq<T>>::CastFrom, R>()
        }

        /// Reinterprets the same byte region as `U` with validity `V` using
        /// `C`.
        ///
        /// `C: CastExact` preserves the byte region. The aliasing invariant is
        /// preserved, while alignment is conservatively forgotten because the
        /// destination type may have a different alignment requirement.
        #[inline]
        #[must_use]
        pub fn transmute_with<U, V, C, R>(self) -> Ptr<'a, U, (I::Aliasing, Unaligned, V)>
        where
            V: Validity,
            U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, C, R> + ?Sized,
            C: CastExact<T, U>,
        {
            // SAFETY:
            // - By `C: CastExact`, `C` preserves referent address, and so we
            //   don't need to consider projections in the following safety
            //   arguments.
            // - If aliasing is `Shared`, then by `U: TransmuteFromPtr<T>`, at
            //   least one of the following holds:
            //   - `T: Immutable` and `U: Immutable`, in which case it is
            //     trivially sound for shared code to operate on a `&T` and `&U`
            //     at the same time, as neither can perform interior mutation
            //   - It is directly guaranteed that it is sound for shared code to
            //     operate on these references simultaneously
            // - By `U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, C>`, it
            //   is sound to perform this transmute using `C`.
            unsafe { self.project_transmute_unchecked::<_, _, C>() }
        }

        /// Changes only the validity invariant to `V`.
        ///
        /// The referent type and byte region are unchanged, so this preserves
        /// the existing aliasing and alignment invariants.
        #[inline]
        #[must_use]
        pub fn recall_validity<V, R>(self) -> Ptr<'a, T, (I::Aliasing, I::Alignment, V)>
        where
            V: Validity,
            T: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, IdCast, R>,
        {
            let ptr = self.transmute_with::<T, V, IdCast, R>();
            // SAFETY: `self` and `ptr` have the same address and referent type.
            // Therefore, if `self` satisfies `I::Alignment`, then so does
            // `ptr`.
            unsafe { ptr.assume_alignment::<I::Alignment>() }
        }

        /// Projects and/or transmutes to a different (unsized) referent type
        /// without checking interior mutability.
        ///
        /// Callers should prefer [`cast`] or [`project`] where possible.
        ///
        /// [`cast`]: Ptr::cast
        /// [`project`]: Ptr::project
        ///
        /// # Safety
        ///
        /// The caller promises that:
        /// - If `I::Aliasing` is [`Shared`], it must not be possible for safe
        ///   code, operating on a `&T` and `&U`, with the referents of `self`
        ///   and `self.project_transmute_unchecked()`, respectively, to cause
        ///   undefined behavior.
        /// - It is sound to project and/or transmute a pointer of type `T` with
        ///   aliasing `I::Aliasing` and validity `I::Validity` to a pointer of
        ///   type `U` with aliasing `I::Aliasing` and validity `V`. This is a
        ///   subtle soundness requirement that is a function of `T`, `U`,
        ///   `I::Aliasing`, `I::Validity`, and `V`, and may depend upon the
        ///   presence, absence, or specific location of `UnsafeCell`s in `T`
        ///   and/or `U`, and on whether interior mutation is ever permitted via
        ///   those `UnsafeCell`s. See [`Validity`] for more details.
        #[inline]
        #[must_use]
        pub unsafe fn project_transmute_unchecked<U: ?Sized, V, P>(
            self,
        ) -> Ptr<'a, U, (I::Aliasing, Unaligned, V)>
        where
            V: Validity,
            P: crate::pointer::cast::Project<T, U>,
        {
            let ptr = self.as_inner().project::<_, P>();

            // SAFETY:
            //
            // The following safety arguments rely on the fact that `P: Project`
            // guarantees that `P` is a referent-preserving or -shrinking
            // projection. Thus, `ptr` addresses a subset of the bytes of
            // `*self`, and so certain properties that hold of `*self` also hold
            // of `*ptr`.
            //
            // 0. `ptr` conforms to the aliasing invariant of `I::Aliasing`:
            //    - `Exclusive`: `self` is the only `Ptr` or reference which is
            //      permitted to read or modify the referent for the lifetime
            //      `'a`. Since we consume `self` by value, the returned pointer
            //      remains the only `Ptr` or reference which is permitted to
            //      read or modify the referent for the lifetime `'a`.
            //    - `Shared`: Since `self` has aliasing `Shared`, we know that
            //      no other code may mutate the referent during the lifetime
            //      `'a`, except via `UnsafeCell`s, and except as permitted by
            //      `T`'s library safety invariants. The caller promises that
            //      any safe operations which can be permitted on a `&T` and a
            //      `&U` simultaneously must be sound. Thus, no operations on a
            //      `&U` could violate `&T`'s library safety invariants, and
            //      vice-versa. Since any mutation via shared references outside
            //      of `UnsafeCell`s is unsound, this must be impossible using
            //      `&T` and `&U`.
            //    - `Inaccessible`: There are no restrictions we need to uphold.
            // 1. `ptr` trivially satisfies the alignment invariant `Unaligned`.
            // 2. The caller promises that the returned pointer satisfies the
            //    validity invariant `V` with respect to its referent type, `U`.
            unsafe { Ptr::from_inner(ptr) }
        }
    }

    /// `Ptr<'a, T, (_, _, _)>` → `Ptr<'a, Unalign<T>, (_, Aligned, _)>`
    impl<'a, T, I> Ptr<'a, T, I>
    where
        I: Invariants,
    {
        /// Converts a `Ptr` an unaligned `T` into a `Ptr` to an aligned
        /// `Unalign<T>`.
        #[inline]
        #[must_use]
        pub fn into_unalign(
            self,
        ) -> Ptr<'a, crate::Unalign<T>, (I::Aliasing, Aligned, I::Validity)> {
            // FIXME(#1359): This should be a `transmute_with` call.
            // Unfortunately, to avoid blanket impl conflicts, we only implement
            // `TransmuteFrom<T>` for `Unalign<T>` (and vice versa) specifically
            // for `Safe` validity, not for all validity types.

            // SAFETY:
            // - By `CastSized: Cast`, `CastSized` preserves referent address,
            //   and so we don't need to consider projections in the following
            //   safety arguments.
            // - Since `Unalign<T>` has the same layout as `T`, the returned
            //   pointer refers to `UnsafeCell`s at the same locations as
            //   `self`.
            // - `Unalign<T>` promises to have the same bit validity as `T`. By
            //   invariant on `Validity`, the set of bit patterns allowed in the
            //   referent of a `Ptr<X, (_, _, V)>` is only a function of the
            //   validity of `X` and of `V`. Thus, the set of bit patterns
            //   allowed in the referent of a `Ptr<T, (_, _, I::Validity)>` is
            //   the same as the set of bit patterns allowed in the referent of
            //   a `Ptr<Unalign<T>, (_, _, I::Validity)>`. As a result, `self`
            //   and the returned `Ptr` permit the same set of bit patterns in
            //   their referents, and so neither can be used to violate the
            //   validity of the other.
            let ptr = unsafe { self.project_transmute_unchecked::<_, _, CastSized>() };
            ptr.bikeshed_recall_aligned()
        }
    }

    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: ?Sized,
        I: Invariants<Validity = Safe>,
        I::Aliasing: Reference,
    {
        /// Reads the referent.
        #[must_use]
        #[inline(always)]
        pub fn read<R>(self) -> T
        where
            T: Copy,
            T: Read<I::Aliasing, R>,
        {
            <I::Alignment as Alignment>::read(self)
        }

        /// Views the value as an aligned reference.
        ///
        /// This is only available if `T` is [`Unaligned`].
        #[must_use]
        #[inline]
        pub fn unaligned_as_ref(self) -> &'a T
        where
            T: crate::Unaligned,
        {
            self.bikeshed_recall_aligned().as_ref()
        }
    }
}

/// State transitions between invariants.
mod _transitions {
    use super::*;
    use crate::{
        pointer::{cast::IdCast, transmute::TryTransmuteFromPtr},
        ReadOnly,
    };

    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants,
    {
        /// Assumes that `self` satisfies the invariants `H`.
        ///
        /// # Safety
        ///
        /// The caller promises that `self` satisfies the invariants `H`.
        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`.
            unsafe { Ptr::from_inner(self.as_inner()) }
        }

        /// Helps the type system unify two distinct invariant types which are
        /// actually the same.
        #[inline]
        #[must_use]
        pub fn unify_invariants<
            H: Invariants<Aliasing = I::Aliasing, Alignment = I::Alignment, Validity = I::Validity>,
        >(
            self,
        ) -> Ptr<'a, T, H> {
            // SAFETY: The associated type bounds on `H` ensure that the
            // invariants are unchanged.
            unsafe { self.assume_invariants::<H>() }
        }

        /// Downgrades `self` to shared aliasing.
        #[inline]
        #[must_use]
        pub(super) fn into_shared(self) -> Ptr<'a, T, (Shared, I::Alignment, I::Validity)>
        where
            I::Aliasing: Reference,
        {
            // SAFETY: `I::Aliasing: Reference` guarantees that the source
            // aliasing is either `Shared` or `Exclusive`. `Shared` requires no
            // transition. If it is `Exclusive`, consuming `self` ends the only
            // permitted access to the referent, so the returned pointer can
            // soundly carry `Shared` aliasing. The referent type, alignment,
            // and validity invariants are unchanged.
            unsafe { self.assume_invariants() }
        }

        /// Assumes that `self`'s referent is validly-aligned for `T` if
        /// required by `A`.
        ///
        /// # Safety
        ///
        /// The caller promises that `self`'s referent conforms to the alignment
        /// invariant of `T` if required by `A`.
        #[inline]
        pub(crate) unsafe fn assume_alignment<A: Alignment>(
            self,
        ) -> Ptr<'a, T, (I::Aliasing, A, I::Validity)> {
            // SAFETY: The caller promises that `self`'s referent is
            // well-aligned for `T` if required by `A` .
            unsafe { self.assume_invariants() }
        }

        /// Checks the `self`'s alignment at runtime, returning an aligned `Ptr`
        /// on success.
        #[inline]
        pub fn try_into_aligned(
            self,
        ) -> Result<Ptr<'a, T, (I::Aliasing, Aligned, I::Validity)>, AlignmentError<Self, T>>
        where
            T: Sized,
        {
            if let Err(err) =
                crate::util::validate_aligned_to::<_, T>(self.as_inner().as_non_null())
            {
                return Err(err.with_src(self));
            }

            // SAFETY: We just checked the alignment.
            Ok(unsafe { self.assume_alignment::<Aligned>() })
        }

        /// Recalls that `self`'s referent is validly-aligned for `T`.
        #[inline]
        // FIXME(#859): Reconsider the name of this method before making it
        // public.
        #[must_use]
        pub fn bikeshed_recall_aligned(self) -> Ptr<'a, T, (I::Aliasing, Aligned, I::Validity)>
        where
            T: crate::Unaligned,
        {
            // SAFETY: The bound `T: Unaligned` ensures that `T` has no
            // non-trivial alignment requirement.
            unsafe { self.assume_alignment::<Aligned>() }
        }

        /// Assumes that `self`'s referent conforms to the validity requirement
        /// of `V`.
        ///
        /// # Safety
        ///
        /// The caller promises that `self`'s referent conforms to the validity
        /// requirement of `V`.
        #[must_use]
        #[inline]
        pub unsafe fn assume_validity<V: Validity>(
            self,
        ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, V)> {
            // SAFETY: The caller promises that `self`'s referent conforms to
            // the validity requirement of `V`.
            unsafe { self.assume_invariants() }
        }

        /// A shorthand for `self.assume_validity<invariant::Initialized>()`.
        ///
        /// # Safety
        ///
        /// The caller promises to uphold the safety preconditions of
        /// `self.assume_validity<invariant::Initialized>()`.
        #[must_use]
        #[inline]
        pub unsafe fn assume_initialized(
            self,
        ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Initialized)> {
            // SAFETY: The caller has promised to uphold the safety
            // preconditions.
            unsafe { self.assume_validity::<Initialized>() }
        }

        /// A shorthand for `self.assume_validity<Safe>()`.
        ///
        /// # Safety
        ///
        /// The caller promises to uphold the safety preconditions of
        /// `self.assume_validity<Safe>()`.
        #[must_use]
        #[inline]
        pub unsafe fn assume_safe(self) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Safe)> {
            // SAFETY: The caller has promised to uphold the safety
            // preconditions.
            unsafe { self.assume_validity::<Safe>() }
        }

        /// Checks that `self`'s referent is validly initialized for `T`,
        /// returning a `Ptr` with `Safe` on success.
        ///
        /// # Panics
        ///
        /// This method will panic if
        /// [`T::is_safe`][TryFromBytes::is_safe] panics.
        ///
        /// # Safety
        ///
        /// On error, unsafe code may rely on this method's returned
        /// `ValidityError` containing `self`.
        #[inline]
        pub fn try_into_safe<R, S>(
            mut self,
        ) -> Result<Ptr<'a, T, (I::Aliasing, I::Alignment, Safe)>, ValidityError<Self, T>>
        where
            T: TryFromBytes
                + Read<I::Aliasing, R>
                + TryTransmuteFromPtr<T, I::Aliasing, I::Validity, Safe, IdCast, S>,
            ReadOnly<T>: Read<I::Aliasing, R>,
            I::Aliasing: Reference,
            I: Invariants<Validity = Initialized>,
        {
            // 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 fix before returning.
            if T::is_safe(self.reborrow().transmute::<_, _, _>().reborrow_shared()) {
                // SAFETY: If `T::is_safe` returns true, code may assume that
                // `self` contains a valid `T`, so its referent conforms to
                // `Safe` for `T`. By `T: TryTransmuteFromPtr<T, I::Aliasing,
                // I::Validity, Safe>`, given that condition, changing `self`'s
                // validity to `Safe` is sound.
                Ok(unsafe { self.assume_safe() })
            } else {
                Err(ValidityError::new(self))
            }
        }

        /// Forgets that `self`'s referent is validly-aligned for `T`.
        #[inline]
        #[must_use]
        pub fn forget_aligned(self) -> Ptr<'a, T, (I::Aliasing, Unaligned, I::Validity)> {
            // SAFETY: `Unaligned` is less restrictive than `Aligned`.
            unsafe { self.assume_invariants() }
        }
    }
}

/// Casts of the referent type.
#[allow(unreachable_pub)] // False positive on MSRV
pub use _casts::TryWithError;
mod _casts {
    use core::cell::UnsafeCell;

    use super::*;
    use crate::{
        pointer::cast::{AsBytesCast, Cast},
        HasTag, ProjectField,
    };

    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + ?Sized,
        I: Invariants,
    {
        /// Casts to a different referent type without checking interior
        /// mutability.
        ///
        /// Callers should prefer [`cast`][Ptr::cast] where possible.
        ///
        /// # Safety
        ///
        /// If `I::Aliasing` is [`Shared`], it must not be possible for safe
        /// code, operating on a `&T` and `&U` with the same referent
        /// simultaneously, to cause undefined behavior.
        #[inline]
        #[must_use]
        pub unsafe fn cast_unchecked<U, C: Cast<T, U>>(
            self,
        ) -> Ptr<'a, U, (I::Aliasing, Unaligned, I::Validity)>
        where
            U: 'a + CastableFrom<T, I::Validity, I::Validity> + ?Sized,
        {
            // SAFETY:
            // - By `C: Cast`, `C` preserves the address of the referent.
            // - If `I::Aliasing` is [`Shared`], the caller promises that it
            //   is not possible for safe code, operating on a `&T` and `&U`
            //   with the same referent simultaneously, to cause undefined
            //   behavior.
            // - By `U: CastableFrom<T, I::Validity, I::Validity>`,
            //   `I::Validity` is either `Uninit` or `Initialized`. In both
            //   cases, the bit validity `I::Validity` has the same semantics
            //   regardless of referent type. In other words, the set of allowed
            //   referent values for `Ptr<T, (_, _, I::Validity)>` and `Ptr<U,
            //   (_, _, I::Validity)>` are identical. As a consequence, neither
            //   `self` nor the returned `Ptr` can be used to write values which
            //   are invalid for the other.
            unsafe { self.project_transmute_unchecked::<_, _, C>() }
        }

        /// Casts to a different referent type.
        #[inline]
        #[must_use]
        pub fn cast<U, C, R>(self) -> Ptr<'a, U, (I::Aliasing, Unaligned, I::Validity)>
        where
            T: MutationCompatible<U, I::Aliasing, I::Validity, I::Validity, R>,
            U: 'a + ?Sized + CastableFrom<T, I::Validity, I::Validity>,
            C: Cast<T, U>,
        {
            // SAFETY: Because `T: MutationCompatible<U, I::Aliasing, R>`, one
            // of the following holds:
            // - `T: Read<I::Aliasing>` and `U: Read<I::Aliasing>`, in which
            //   case one of the following holds:
            //   - `I::Aliasing` is `Exclusive`
            //   - `T` and `U` are both `Immutable`
            // - It is sound for safe code to operate on `&T` and `&U` with the
            //   same referent simultaneously.
            unsafe { self.cast_unchecked::<_, C>() }
        }

        #[inline(always)]
        pub fn project<Client, F, const VARIANT_ID: i128, const FIELD_ID: i128>(
            mut self,
        ) -> Result<Ptr<'a, T::Type, T::Invariants>, T::Error>
        where
            T: ProjectField<Client, F, I, VARIANT_ID, FIELD_ID>,
            I::Aliasing: Reference,
        {
            use crate::pointer::cast::Projection;
            match <T as ProjectField<Client, F, I, VARIANT_ID, FIELD_ID>>::is_projectable(
                self.reborrow().project_tag::<Client>(),
            ) {
                Ok(()) => {
                    let inner = self.as_inner();
                    let projected =
                        inner.project::<_, Projection<Client, F, VARIANT_ID, FIELD_ID>>();
                    // SAFETY: By `T: ProjectField<Client, F, I, VARIANT_ID, FIELD_ID>`,
                    // for `self: Ptr<'_, T, I>` such that `T::is_projectable`
                    // (which we've verified in this match arm),
                    // `T::project(self.as_inner())` conforms to
                    // `T::Invariants`. The `projected` pointer satisfies these
                    // invariants because it is produced by way of an
                    // abstraction that is equivalent to
                    // `T::project(ptr.as_inner())`: by invariant on
                    // `PtrInner::project`, `projected` is guaranteed to address
                    // the subset of the bytes of `inner`'s referent addressed
                    // by `Projection::project(inner)`, and by invariant on
                    // `Projection`, `Projection::project` is implemented by
                    // delegating to an implementation of `HasField::project`.
                    Ok(unsafe { Ptr::from_inner(projected) })
                }
                Err(err) => Err(err),
            }
        }

        #[must_use]
        #[inline(always)]
        pub fn project_tag<Client>(
            self,
        ) -> Ptr<'a, <T as HasTag<Client>>::Tag, (Shared, I::Alignment, I::Validity)>
        where
            T: HasTag<Client>,
            I::Aliasing: Reference,
        {
            let ptr = self.into_shared();
            // SAFETY: By invariant on `ProjectToTag`, it is sound to project
            // `ptr` to a shared tag pointer with the same validity invariant.
            let ptr = unsafe {
                ptr.project_transmute_unchecked::<_, _, <T as HasTag<Client>>::ProjectToTag>()
            };
            // SAFETY: By invariant on `ProjectToTag`, the projected pointer has
            // the same alignment as `self`.
            unsafe { ptr.assume_alignment() }
        }

        /// Attempts to transform the pointer, restoring the original on
        /// failure.
        ///
        /// # Safety
        ///
        /// If `I::Aliasing != Shared`, then if `f` returns `Err(err)`, no copy
        /// of `f`'s argument must exist outside of `err`.
        #[inline(always)]
        pub(crate) unsafe fn try_with_unchecked<U, J, E, F>(
            self,
            f: F,
        ) -> Result<Ptr<'a, U, J>, E::Mapped>
        where
            U: 'a + ?Sized,
            J: Invariants<Aliasing = I::Aliasing>,
            E: TryWithError<Self>,
            F: FnOnce(Ptr<'a, T, I>) -> Result<Ptr<'a, U, J>, E>,
        {
            let old_inner = self.as_inner();
            #[rustfmt::skip]
            let res = f(self).map_err(#[inline(always)] move |err: E| {
                err.map(#[inline(always)] |src| {
                    drop(src);

                    // SAFETY:
                    // 0. Aliasing is either `Shared` or `Exclusive`:
                    //    - If aliasing is `Shared`, then it cannot violate
                    //      aliasing make another copy of this pointer (in fact,
                    //      using `I::Aliasing = Shared`, we could have just
                    //      cloned `self`).
                    //    - If aliasing is `Exclusive`, then `f` is not allowed
                    //      to make another copy of `self`. In `map_err`, we are
                    //      consuming the only value in the returned `Result`.
                    //      By invariant on `E: TryWithError<Self>`, that `err:
                    //      E` only contains a single `Self` and no other
                    //      non-ZST fields which could be `Ptr`s or references
                    //      to `self`'s referent. By the same invariant, `map`
                    //      consumes this single `Self` and passes it to this
                    //      closure. Since `self` was, by invariant on
                    //      `Exclusive`, the only `Ptr` or reference live for
                    //      `'a` with this referent, and since we `drop(src)`
                    //      above, there are no copies left, and so we are
                    //      creating the only copy.
                    // 1. `self` conforms to `I::Aliasing` by invariant on
                    //    `Ptr`, and `old_inner` has the same address, so it
                    //    does too.
                    // 2. `f` could not have violated `self`'s validity without
                    //    itself being unsound. Assuming that `f` is sound, the
                    //    referent of `self` is still valid for `T`.
                    unsafe { Ptr::from_inner(old_inner) }
                })
            });
            res
        }

        /// Attempts to transform the pointer, restoring the original on
        /// failure.
        #[inline(always)]
        pub fn try_with<U, J, E, F>(self, f: F) -> Result<Ptr<'a, U, J>, E::Mapped>
        where
            U: 'a + ?Sized,
            J: Invariants<Aliasing = I::Aliasing>,
            E: TryWithError<Self>,
            F: FnOnce(Ptr<'a, T, I>) -> Result<Ptr<'a, U, J>, E>,
            I: Invariants<Aliasing = Shared>,
        {
            // SAFETY: `I::Aliasing = Shared`, so the safety condition does not
            // apply.
            unsafe { self.try_with_unchecked(f) }
        }
    }

    /// # Safety
    ///
    /// `Self` only contains a single `Self::Inner`, and `Self::Mapped` only
    /// contains a single `MappedInner`. Other than that, `Self` and
    /// `Self::Mapped` contain no non-ZST fields.
    ///
    /// `map` must pass ownership of `self`'s sole `Self::Inner` to `f`.
    pub unsafe trait TryWithError<MappedInner> {
        type Inner;
        type Mapped;
        fn map<F: FnOnce(Self::Inner) -> MappedInner>(self, f: F) -> Self::Mapped;
    }

    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + KnownLayout + ?Sized,
        I: Invariants,
    {
        /// Casts this pointer-to-initialized into a pointer-to-bytes.
        #[allow(clippy::wrong_self_convention)]
        #[must_use]
        #[inline]
        pub fn as_bytes<R>(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Safe)>
        where
            [u8]: TransmuteFromPtr<T, I::Aliasing, I::Validity, Safe, AsBytesCast, R>,
        {
            self.transmute_with::<[u8], Safe, AsBytesCast, _>().bikeshed_recall_aligned()
        }
    }

    impl<'a, T, I, const N: usize> Ptr<'a, [T; N], I>
    where
        T: 'a,
        I: Invariants,
    {
        /// Casts this pointer-to-array into a slice.
        #[allow(clippy::wrong_self_convention)]
        #[inline]
        #[must_use]
        pub fn as_slice(self) -> Ptr<'a, [T], I> {
            let slice = self.as_inner().as_slice();
            // SAFETY: Note that, by post-condition on `PtrInner::as_slice`,
            // `slice` refers to the same byte range as `self.as_inner()`.
            //
            // 0. Thus, `slice` conforms to the aliasing invariant of
            //    `I::Aliasing` because `self` does.
            // 1. By the above lemma, `slice` conforms to the alignment
            //    invariant of `I::Alignment` because `self` does.
            // 2. Since `[T; N]` and `[T]` have the same bit validity [1][2],
            //    and since `self` and the returned `Ptr` have the same validity
            //    invariant, neither `self` nor the returned `Ptr` can be used
            //    to write a value to the referent which violates the other's
            //    validity invariant.
            //
            // [1] Per https://doc.rust-lang.org/1.81.0/reference/type-layout.html#array-layout:
            //
            //   An array of `[T; N]` has a size of `size_of::<T>() * N` and the
            //   same alignment of `T`. Arrays are laid out so that the
            //   zero-based `nth` element of the array is offset from the start
            //   of the array by `n * size_of::<T>()` bytes.
            //
            //   ...
            //
            //   Slices have the same layout as the section of the array they
            //   slice.
            //
            // [2] Per https://doc.rust-lang.org/1.81.0/reference/types/array.html#array-types:
            //
            //   All elements of arrays are always initialized
            unsafe { Ptr::from_inner(slice) }
        }
    }

    /// For caller convenience, these methods are generic over alignment
    /// invariant. In practice, the referent is always well-aligned, because the
    /// alignment of `[u8]` is 1.
    impl<'a, I> Ptr<'a, [u8], I>
    where
        I: Invariants<Validity = Safe>,
    {
        /// Attempts to cast `self` to a `U` using the given cast type.
        ///
        /// If `U` is a slice DST and pointer metadata (`meta`) is provided,
        /// then the cast will only succeed if it would produce an object with
        /// the given metadata.
        ///
        /// Returns `None` if the resulting `U` would be invalidly-aligned, if
        /// no `U` can fit in `self`, or if the provided pointer metadata
        /// describes an invalid instance of `U`. On success, returns a pointer
        /// to the largest-possible `U` which fits in `self`.
        ///
        /// # Safety
        ///
        /// The caller may assume that this implementation is correct, and may
        /// rely on that assumption for the soundness of their code. In
        /// particular, the caller may assume that, if `try_cast_into` returns
        /// `Some((ptr, remainder))`, then `ptr` and `remainder` refer to
        /// non-overlapping byte ranges within `self`, and that `ptr` and
        /// `remainder` entirely cover `self`. Finally:
        /// - If this is a prefix cast, `ptr` has the same address as `self`.
        /// - If this is a suffix cast, `remainder` has the same address as
        ///   `self`.
        #[inline(always)]
        pub fn try_cast_into<U, R>(
            self,
            cast_type: CastType,
            meta: Option<U::PointerMetadata>,
        ) -> Result<
            (Ptr<'a, U, (I::Aliasing, Aligned, Initialized)>, Ptr<'a, [u8], I>),
            CastError<Self, U>,
        >
        where
            I::Aliasing: Reference,
            U: 'a + ?Sized + KnownLayout + Read<I::Aliasing, R>,
        {
            let (inner, remainder) = self.as_inner().try_cast_into(cast_type, meta).map_err(
                #[inline(always)]
                |err| {
                    err.map_src(
                        #[inline(always)]
                        |inner|
                    // SAFETY: `PtrInner::try_cast_into` promises to return its
                    // original argument on error, which was originally produced
                    // by `self.as_inner()`, which is guaranteed to satisfy
                    // `Ptr`'s invariants.
                    unsafe { Ptr::from_inner(inner) },
                    )
                },
            )?;

            // SAFETY:
            // 0. Since `U: Read<I::Aliasing, _>`, either:
            //    - `I::Aliasing` is `Exclusive`, in which case both `src` and
            //      `ptr` conform to `Exclusive`
            //    - `I::Aliasing` is `Shared` and `U` is `Immutable` (we already
            //      know that `[u8]: Immutable`). In this case, neither `U` nor
            //      `[u8]` permit mutation, and so `Shared` aliasing is
            //      satisfied.
            // 1. `ptr` conforms to the alignment invariant of `Aligned` because
            //    it is derived from `try_cast_into`, which promises that the
            //    object described by `target` is validly aligned for `U`.
            // 2. By trait bound, `self` - and thus `target` - is a bit-valid
            //    `[u8]`. `Ptr<[u8], (_, _, Safe)>` and `Ptr<_, (_, _,
            //    Initialized)>` have the same bit validity, and so neither
            //    `self` nor `res` can be used to write a value to the referent
            //    which violates the other's validity invariant.
            let res = unsafe { Ptr::from_inner(inner) };

            // SAFETY:
            // 0. `self` and `remainder` both have the type `[u8]`. Thus, they
            //    have `UnsafeCell`s at the same locations. Type casting does not
            //    affect aliasing.
            // 1. `[u8]` has no alignment requirement.
            // 2. `self` has validity `Safe` and has type `[u8]`. Since
            //    `remainder` references a subset of `self`'s referent, it is
            //    also a bit-valid `[u8]`. Thus, neither `self` nor `remainder`
            //    can be used to write a value to the referent which violates the
            //    other's validity invariant.
            let remainder = unsafe { Ptr::from_inner(remainder) };

            Ok((res, remainder))
        }

        /// Attempts to cast `self` into a `U`, failing if all of the bytes of
        /// `self` cannot be treated as a `U`.
        ///
        /// In particular, this method fails if `self` is not validly-aligned
        /// for `U` or if `self`'s size is not a valid size for `U`.
        ///
        /// # Safety
        ///
        /// On success, the caller may assume that the returned pointer
        /// references the same byte range as `self`.
        #[allow(unused)]
        #[inline(always)]
        pub fn try_cast_into_no_leftover<U, R>(
            self,
            meta: Option<U::PointerMetadata>,
        ) -> Result<Ptr<'a, U, (I::Aliasing, Aligned, Initialized)>, CastError<Self, U>>
        where
            I::Aliasing: Reference,
            U: 'a + ?Sized + KnownLayout + Read<I::Aliasing, R>,
            [u8]: Read<I::Aliasing, R>,
        {
            // SAFETY: The provided closure returns the only copy of `slf`.
            unsafe {
                self.try_with_unchecked(
                    #[inline(always)]
                    |slf| match slf.try_cast_into(CastType::Prefix, meta) {
                        Ok((slf, remainder)) => {
                            if remainder.is_empty() {
                                Ok(slf)
                            } else {
                                Err(CastError::Size(SizeError::<_, U>::new(())))
                            }
                        }
                        Err(err) => Err(err.map_src(
                            #[inline(always)]
                            |_slf| (),
                        )),
                    },
                )
            }
        }
    }

    impl<'a, T, I> Ptr<'a, UnsafeCell<T>, I>
    where
        T: 'a + ?Sized,
        I: Invariants<Aliasing = Exclusive>,
    {
        /// Converts this `Ptr` into a pointer to the underlying data.
        ///
        /// This call borrows the `UnsafeCell` mutably (at compile-time) which
        /// guarantees that we possess the only reference.
        ///
        /// This is like [`UnsafeCell::get_mut`], but for `Ptr`.
        ///
        /// [`UnsafeCell::get_mut`]: core::cell::UnsafeCell::get_mut
        #[must_use]
        #[inline(always)]
        pub fn get_mut(self) -> Ptr<'a, T, I> {
            // SAFETY: As described below, `UnsafeCell<T>` has the same size
            // as `T: ?Sized` (same static size or same DST layout). Thus,
            // `*const UnsafeCell<T> as *const T` is a size-preserving cast.
            define_cast!(unsafe { Cast<T: ?Sized> = UnsafeCell<T> => T });

            // SAFETY:
            // - Aliasing is `Exclusive`, and so we are not required to promise
            //   anything about the locations of `UnsafeCell`s.
            // - `UnsafeCell<T>` has the same bit validity as `T` [1].
            //   Technically the term "representation" doesn't guarantee this,
            //   but the subsequent sentence in the documentation makes it clear
            //   that this is the intention.
            //
            //   By invariant on `Validity`, since `T` and `UnsafeCell<T>` have
            //   the same bit validity, then the set of values which may appear
            //   in the referent of a `Ptr<T, (_, _, V)>` is the same as the set
            //   which may appear in the referent of a `Ptr<UnsafeCell<T>, (_,
            //   _, V)>`. Thus, neither `self` nor `ptr` may be used to write a
            //   value to the referent which would violate the other's validity
            //   invariant.
            //
            // [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>`.
            let ptr = unsafe { self.project_transmute_unchecked::<_, _, Cast>() };

            // SAFETY: `UnsafeCell<T>` has the same alignment as `T` [1],
            // and so if `self` is guaranteed to be aligned, then so is the
            // returned `Ptr`.
            //
            // [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>`.
            let ptr = unsafe { ptr.assume_alignment::<I::Alignment>() };
            ptr.unify_invariants()
        }
    }
}

/// Projections through the referent.
mod _project {
    use super::*;

    impl<'a, T, I> Ptr<'a, [T], I>
    where
        T: 'a,
        I: Invariants,
        I::Aliasing: Reference,
    {
        /// Iteratively projects the elements `Ptr<T>` from `Ptr<[T]>`.
        #[inline]
        pub fn iter(self) -> impl Iterator<Item = Ptr<'a, T, I>> {
            // SAFETY:
            // 0. `elem` conforms to the aliasing invariant of `I::Aliasing`:
            //    - `Exclusive`: `self` is consumed by value, and therefore
            //      cannot be used to access the slice while any yielded
            //      element `Ptr` is live. Each non-zero-sized element is a
            //      disjoint byte range within the slice, and zero-sized
            //      elements address no bytes, so distinct yielded element
            //      `Ptr`s do not alias each other.
            //    - `Shared`: It is sound for multiple shared `Ptr`s to exist
            //      simultaneously which reference the same memory.
            // 1. `elem`, conditionally, conforms to the validity invariant of
            //    `I::Alignment`. If `elem` is projected from data well-aligned
            //    for `[T]`, `elem` will be valid for `T`.
            // 2. `elem` conforms to the validity invariant of `I::Validity`.
            //    Per https://doc.rust-lang.org/1.81.0/reference/type-layout.html#array-layout:
            //
            //      Slices have the same layout as the section of the array they
            //      slice.
            //
            //    Arrays are laid out so that the zero-based `nth` element of
            //    the array is offset from the start of the array by `n *
            //    size_of::<T>()` bytes. Thus, `elem` addresses a valid `T`
            //    within the slice. Since `self` satisfies `I::Validity`, `elem`
            //    also satisfies `I::Validity`.
            self.as_inner().iter().map(
                #[inline(always)]
                |elem| unsafe { Ptr::from_inner(elem) },
            )
        }
    }

    #[allow(clippy::needless_lifetimes)]
    impl<'a, T, I> Ptr<'a, T, I>
    where
        T: 'a + ?Sized + KnownLayout<PointerMetadata = usize>,
        I: Invariants,
    {
        /// The number of slice elements in the object referenced by `self`.
        #[inline]
        #[must_use]
        pub fn len(&self) -> usize {
            self.as_inner().meta().get()
        }

        /// Returns `true` if the slice pointer has a length of 0.
        #[inline]
        #[must_use]
        pub fn is_empty(&self) -> bool {
            self.len() == 0
        }
    }
}

#[cfg(test)]
mod tests {
    use core::mem::{self, MaybeUninit};

    use super::*;
    #[allow(unused)] // Needed on our MSRV, but considered unused on later toolchains.
    use crate::util::AsAddress;
    use crate::{pointer::BecauseImmutable, util::testutil::AU64, FromBytes, Immutable};

    #[test]
    fn test_project_tag_downgrades_aliasing() {
        #[allow(dead_code)]
        #[derive(zerocopy_derive::Project)]
        #[repr(u8)]
        enum Enum {
            Variant(u8),
        }

        let mut value = Enum::Variant(0);
        let _: Ptr<
            '_,
            <Enum as crate::HasTag<crate::project_clients::ProjectDerive>>::Tag,
            (Shared, Aligned, Safe),
        > = Ptr::from_mut(&mut value).project_tag::<crate::project_clients::ProjectDerive>();
    }

    mod test_ptr_try_cast_into_soundness {
        use super::*;

        // This test is designed so that if `Ptr::try_cast_into_xxx` are
        // buggy, it will manifest as unsoundness that Miri can detect.

        // - If `size_of::<T>() == 0`, `N == 4`
        // - Else, `N == 4 * size_of::<T>()`
        //
        // Each test will be run for each metadata in `metas`.
        fn test<T, I, const N: usize>(metas: I)
        where
            T: ?Sized + KnownLayout + Immutable + FromBytes,
            I: IntoIterator<Item = Option<T::PointerMetadata>> + Clone,
        {
            let mut bytes = [MaybeUninit::<u8>::uninit(); N];
            let initialized = [MaybeUninit::new(0u8); N];
            for start in 0..=bytes.len() {
                for end in start..=bytes.len() {
                    // Set all bytes to uninitialized other than those in
                    // the range we're going to pass to `try_cast_from`.
                    // This allows Miri to detect out-of-bounds reads
                    // because they read uninitialized memory. Without this,
                    // some out-of-bounds reads would still be in-bounds of
                    // `bytes`, and so might spuriously be accepted.
                    bytes = [MaybeUninit::<u8>::uninit(); N];
                    let bytes = &mut bytes[start..end];
                    // Initialize only the byte range we're going to pass to
                    // `try_cast_from`.
                    bytes.copy_from_slice(&initialized[start..end]);

                    let bytes = {
                        let bytes: *const [MaybeUninit<u8>] = bytes;
                        #[allow(clippy::as_conversions)]
                        let bytes = bytes as *const [u8];
                        // SAFETY: We just initialized these bytes to valid
                        // `u8`s.
                        unsafe { &*bytes }
                    };

                    // SAFETY: The bytes in `slf` must be initialized.
                    unsafe fn validate_and_get_len<
                        T: ?Sized + KnownLayout + FromBytes + Immutable,
                    >(
                        slf: Ptr<'_, T, (Shared, Aligned, Initialized)>,
                    ) -> usize {
                        let t = slf.recall_validity().as_ref();

                        let bytes = {
                            let len = mem::size_of_val(t);
                            let t: *const T = t;
                            // SAFETY:
                            // - We know `t`'s bytes are all initialized
                            //   because we just read it from `slf`, which
                            //   points to an initialized range of bytes. If
                            //   there's a bug and this doesn't hold, then
                            //   that's exactly what we're hoping Miri will
                            //   catch!
                            // - Since `T: FromBytes`, `T` doesn't contain
                            //   any `UnsafeCell`s, so it's okay for `t: T`
                            //   and a `&[u8]` to the same memory to be
                            //   alive concurrently.
                            unsafe { core::slice::from_raw_parts(t.cast::<u8>(), len) }
                        };

                        // This assertion ensures that `t`'s bytes are read
                        // and compared to another value, which in turn
                        // ensures that Miri gets a chance to notice if any
                        // of `t`'s bytes are uninitialized, which they
                        // shouldn't be (see the comment above).
                        assert_eq!(bytes, vec![0u8; bytes.len()]);

                        mem::size_of_val(t)
                    }

                    for meta in metas.clone().into_iter() {
                        for cast_type in [CastType::Prefix, CastType::Suffix] {
                            if let Ok((slf, remaining)) = Ptr::from_ref(bytes)
                                .try_cast_into::<T, BecauseImmutable>(cast_type, meta)
                            {
                                // SAFETY: All bytes in `bytes` have been
                                // initialized.
                                let len = unsafe { validate_and_get_len(slf) };
                                assert_eq!(remaining.len(), bytes.len() - len);
                                #[allow(unstable_name_collisions)]
                                let bytes_addr = bytes.as_ptr().addr();
                                #[allow(unstable_name_collisions)]
                                let remaining_addr = remaining.as_inner().as_ptr().addr();
                                match cast_type {
                                    CastType::Prefix => {
                                        assert_eq!(remaining_addr, bytes_addr + len)
                                    }
                                    CastType::Suffix => assert_eq!(remaining_addr, bytes_addr),
                                }

                                if let Some(want) = meta {
                                    let got =
                                        KnownLayout::pointer_to_metadata(slf.as_inner().as_ptr());
                                    assert_eq!(got, want);
                                }
                            }
                        }

                        if let Ok(slf) = Ptr::from_ref(bytes)
                            .try_cast_into_no_leftover::<T, BecauseImmutable>(meta)
                        {
                            // SAFETY: All bytes in `bytes` have been
                            // initialized.
                            let len = unsafe { validate_and_get_len(slf) };
                            assert_eq!(len, bytes.len());

                            if let Some(want) = meta {
                                let got = KnownLayout::pointer_to_metadata(slf.as_inner().as_ptr());
                                assert_eq!(got, want);
                            }
                        }
                    }
                }
            }
        }

        #[derive(FromBytes, KnownLayout, Immutable)]
        #[repr(C)]
        struct SliceDst<T> {
            a: u8,
            trailing: [T],
        }

        // Each test case becomes its own `#[test]` function. We do this because
        // this test in particular takes far, far longer to execute under Miri
        // than all of our other tests combined. Previously, we had these
        // execute sequentially in a single test function. We run Miri tests in
        // parallel in CI, but this test being sequential meant that most of
        // that parallelism was wasted, as all other tests would finish in a
        // fraction of the total execution time, leaving this test to execute on
        // a single thread for the remainder of the test. By putting each test
        // case in its own function, we permit better use of available
        // parallelism.
        macro_rules! test {
            ($test_name:ident: $ty:ty) => {
                #[test]
                #[allow(non_snake_case)]
                fn $test_name() {
                    const S: usize = core::mem::size_of::<$ty>();
                    const N: usize = if S == 0 { 4 } else { S * 4 };
                    test::<$ty, _, N>([None]);

                    // If `$ty` is a ZST, then we can't pass `None` as the
                    // pointer metadata, or else computing the correct trailing
                    // slice length will panic.
                    if S == 0 {
                        test::<[$ty], _, N>([Some(0), Some(1), Some(2), Some(3)]);
                        test::<SliceDst<$ty>, _, N>([Some(0), Some(1), Some(2), Some(3)]);
                    } else {
                        test::<[$ty], _, N>([None, Some(0), Some(1), Some(2), Some(3)]);
                        test::<SliceDst<$ty>, _, N>([None, Some(0), Some(1), Some(2), Some(3)]);
                    }
                }
            };
            ($ty:ident) => {
                test!($ty: $ty);
            };
            ($($ty:ident),*) => { $(test!($ty);)* }
        }

        test!(empty_tuple: ());
        test!(u8, u16, u32, u64, usize, AU64);
        test!(i8, i16, i32, i64, isize);
        test!(f32, f64);
    }

    #[test]
    fn test_try_cast_into_explicit_count() {
        macro_rules! test {
            ($ty:ty, $bytes:expr, $elems:expr, $expect:expr) => {{
                let bytes = [0u8; $bytes];
                let ptr = Ptr::from_ref(&bytes[..]);
                let res =
                    ptr.try_cast_into::<$ty, BecauseImmutable>(CastType::Prefix, Some($elems));
                if let Some(expect) = $expect {
                    let (ptr, _) = res.unwrap();
                    assert_eq!(KnownLayout::pointer_to_metadata(ptr.as_inner().as_ptr()), expect);
                } else {
                    let _ = res.unwrap_err();
                }
            }};
        }

        #[derive(KnownLayout, Immutable)]
        #[repr(C)]
        struct ZstDst {
            u: [u8; 8],
            slc: [()],
        }

        test!(ZstDst, 8, 0, Some(0));
        test!(ZstDst, 7, 0, None);

        test!(ZstDst, 8, usize::MAX, Some(usize::MAX));
        test!(ZstDst, 7, usize::MAX, None);

        #[derive(KnownLayout, Immutable)]
        #[repr(C)]
        struct Dst {
            u: [u8; 8],
            slc: [u8],
        }

        test!(Dst, 8, 0, Some(0));
        test!(Dst, 7, 0, None);

        test!(Dst, 9, 1, Some(1));
        test!(Dst, 8, 1, None);

        // If we didn't properly check for overflow, this would cause the
        // metadata to overflow to 0, and thus the cast would spuriously
        // succeed.
        test!(Dst, 8, usize::MAX - 8 + 1, None);
    }

    #[test]
    fn test_try_cast_into_no_leftover_restores_original_slice() {
        let bytes = [0u8; 4];
        let ptr = Ptr::from_ref(&bytes[..]);
        let res = ptr.try_cast_into_no_leftover::<[u8; 2], BecauseImmutable>(None);
        match res {
            Ok(_) => panic!("should have failed due to leftover bytes"),
            Err(CastError::Size(e)) => {
                assert_eq!(e.into_src().len(), 4, "Should return original slice length");
            }
            Err(e) => panic!("wrong error type: {:?}", e),
        }
    }

    #[test]
    fn test_iter_exclusive_yields_disjoint_ptrs() {
        let mut arr = [0u8, 1, 2, 3];

        {
            let mut iter = Ptr::from_mut(&mut arr[..]).iter();
            let first = iter.next().unwrap().as_mut();
            let second = iter.next().unwrap().as_mut();

            *first = 10;
            *second = 20;
            *first = 30;
        }

        assert_eq!(arr, [30, 20, 2, 3]);
    }
}
