// SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
//
// Copyright 2024 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.

use core::{marker::PhantomData, ops::Range, ptr::NonNull};

pub use _def::PtrInner;

#[allow(unused_imports)]
use crate::util::polyfills::NumExt as _;
use crate::{
    layout::{CastType, MetadataCastError},
    pointer::cast,
    util::AsAddress,
    AlignmentError, CastError, KnownLayout, MetadataOf, SizeError, SplitAt,
};

mod _def {
    use super::*;
    /// The inner pointer stored inside a [`Ptr`][crate::Ptr].
    ///
    /// `PtrInner<'a, T>` is [covariant] in `'a` and invariant in `T`.
    ///
    /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
    #[allow(missing_debug_implementations)]
    pub struct PtrInner<'a, T>
    where
        T: ?Sized,
    {
        /// # Invariants
        ///
        /// 0. If `ptr`'s referent is not zero sized, then `ptr` has valid
        ///    provenance for its referent, which is entirely contained in some
        ///    Rust allocation, `A`.
        /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live
        ///    for at least `'a`.
        ///
        /// # Postconditions
        ///
        /// By virtue of these invariants, code may assume the following, which
        /// are logical implications of the invariants:
        /// - `ptr`'s referent is not larger than `isize::MAX` bytes \[1\]
        /// - `ptr`'s referent does not wrap around the address space \[1\]
        ///
        /// \[1\] Per <https://doc.rust-lang.org/1.85.0/std/ptr/index.html#allocated-object>:
        ///
        ///   For any allocated object with `base` address, `size`, and a set of
        ///   `addresses`, the following are guaranteed:
        ///   ...
        ///   - `size <= isize::MAX`
        ///
        ///   As a consequence of these guarantees, given any address `a` within
        ///   the set of addresses of an allocated object:
        ///   ...
        ///   - It is guaranteed that, given `o = a - base` (i.e., the offset of
        ///     `a` within the allocated object), `base + o` will not wrap
        ///     around the address space (in other words, will not overflow
        ///     `usize`)
        ptr: NonNull<T>,
        // SAFETY: `&'a UnsafeCell<T>` is covariant in `'a` and invariant in `T`
        // [1]. We use this construction rather than the equivalent `&mut T`,
        // because our MSRV of 1.65 prohibits `&mut` types in const contexts.
        //
        // [1] https://doc.rust-lang.org/1.81.0/reference/subtyping.html#variance
        _marker: PhantomData<&'a core::cell::UnsafeCell<T>>,
    }

    impl<'a, T: 'a + ?Sized> Copy for PtrInner<'a, T> {}
    impl<'a, T: 'a + ?Sized> Clone for PtrInner<'a, T> {
        #[inline(always)]
        fn clone(&self) -> PtrInner<'a, T> {
            // SAFETY: None of the invariants on `ptr` are affected by having
            // multiple copies of a `PtrInner`.
            *self
        }
    }

    impl<'a, T: 'a + ?Sized> PtrInner<'a, T> {
        /// Constructs a `Ptr` from a [`NonNull`].
        ///
        /// # Safety
        ///
        /// The caller promises that:
        ///
        /// 0. If `ptr`'s referent is not zero sized, then `ptr` has valid
        ///    provenance for its referent, which is entirely contained in some
        ///    Rust allocation, `A`.
        /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live
        ///    for at least `'a`.
        #[inline(always)]
        #[must_use]
        pub const unsafe fn new(ptr: NonNull<T>) -> PtrInner<'a, T> {
            // SAFETY: The caller has promised to satisfy all safety invariants
            // of `PtrInner`.
            Self { ptr, _marker: PhantomData }
        }

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

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

impl<'a, T: ?Sized> PtrInner<'a, T> {
    /// Constructs a `PtrInner` from a reference.
    #[inline]
    pub fn from_ref(ptr: &'a T) -> Self {
        let ptr = NonNull::from(ptr);
        // SAFETY:
        // 0. If `ptr`'s referent is not zero sized, then `ptr`, by invariant on
        //    `&'a T` [1], has valid provenance for its referent, which is
        //    entirely contained in some Rust allocation, `A`.
        // 1. If `ptr`'s referent is not zero sized, then `A`, by invariant on
        //    `&'a T`, is guaranteed to live for at least `'a`.
        //
        // [1] Per https://doc.rust-lang.org/1.85.0/std/primitive.reference.html#safety:
        //
        //   For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`,
        //   when such values cross an API boundary, the following invariants
        //   must generally be upheld:
        //   ...
        //   - if `size_of_val(t) > 0`, then `t` is dereferenceable for
        //     `size_of_val(t)` many bytes
        //
        //   If `t` points at address `a`, being “dereferenceable” for N bytes
        //   means that the memory range `[a, a + N)` is all contained within a
        //   single allocated object.
        unsafe { Self::new(ptr) }
    }

    /// Constructs a `PtrInner` from a mutable reference.
    #[inline]
    pub fn from_mut(ptr: &'a mut T) -> Self {
        let ptr = NonNull::from(ptr);
        // SAFETY:
        // 0. If `ptr`'s referent is not zero sized, then `ptr`, by invariant on
        //    `&'a mut T` [1], has valid provenance for its referent, which is
        //    entirely contained in some Rust allocation, `A`.
        // 1. If `ptr`'s referent is not zero sized, then `A`, by invariant on
        //    `&'a mut T`, is guaranteed to live for at least `'a`.
        //
        // [1] Per https://doc.rust-lang.org/1.85.0/std/primitive.reference.html#safety:
        //
        //   For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`,
        //   when such values cross an API boundary, the following invariants
        //   must generally be upheld:
        //   ...
        //   - if `size_of_val(t) > 0`, then `t` is dereferenceable for
        //     `size_of_val(t)` many bytes
        //
        //   If `t` points at address `a`, being “dereferenceable” for N bytes
        //   means that the memory range `[a, a + N)` is all contained within a
        //   single allocated object.
        unsafe { Self::new(ptr) }
    }

    /// # Safety
    ///
    /// The caller may assume that the resulting `PtrInner` addresses the subset
    /// of the bytes of `self`'s referent addressed by `C::project(self)`.
    #[must_use]
    #[inline(always)]
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
        let projected_raw = C::project(self);

        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
        // zero-sized or lives in an allocation. In either case, it does not
        // wrap around the address space [1], and so none of the addresses
        // contained in it or one-past-the-end of it are null.
        //
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
        // projection which preserves or shrinks the set of referent bytes, so
        // `projected_raw` references a subset of `self`'s referent, and so it
        // cannot be null.
        //
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };

        // SAFETY: As described in the preceding safety comment, `projected_raw`,
        // and thus `projected_non_null`, addresses a subset of `self`'s
        // referent. Thus, `projected_non_null` either:
        // - Addresses zero bytes or,
        // - Addresses a subset of the referent of `self`. In this case, `self`
        //   has provenance for its referent, which lives in an allocation.
        //   Since `projected_non_null` was constructed using a sequence of
        //   provenance-preserving operations, it also has provenance for its
        //   referent and that referent lives in an allocation. By invariant on
        //   `self`, that allocation lives for `'a`.
        unsafe { PtrInner::new(projected_non_null) }
    }
}

#[allow(clippy::needless_lifetimes)]
impl<'a, T> PtrInner<'a, T>
where
    T: ?Sized + KnownLayout,
{
    /// Extracts the metadata of this `ptr`.
    #[inline]
    #[must_use]
    pub fn meta(self) -> MetadataOf<T> {
        let meta = T::pointer_to_metadata(self.as_ptr());
        // SAFETY: By invariant on `PtrInner`, `self.as_non_null()` addresses no
        // more than `isize::MAX` bytes.
        unsafe { MetadataOf::new_unchecked(meta) }
    }

    /// Produces a `PtrInner` with the same address and provenance as `self` but
    /// the given `meta`.
    ///
    /// # Safety
    ///
    /// The caller promises that if `self`'s referent is not zero sized, then
    /// a pointer constructed from its address with the given `meta` metadata
    /// will address a subset of the allocation pointed to by `self`.
    #[inline]
    #[must_use]
    pub unsafe fn with_meta(self, meta: T::PointerMetadata) -> Self
    where
        T: KnownLayout,
    {
        let raw = T::raw_from_ptr_len(self.as_non_null().cast(), meta);

        // SAFETY:
        //
        // Lemma 0: `raw` either addresses zero bytes, or addresses a subset of
        //          the allocation pointed to by `self` and has the same
        //          provenance as `self`. Proof: `raw` is constructed using
        //          provenance-preserving operations, and the caller has
        //          promised that, if `self`'s referent is not zero-sized, the
        //          resulting pointer addresses a subset of the allocation
        //          pointed to by `self`.
        //
        // 0. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
        //    zero sized, then `ptr` is derived from some valid Rust allocation,
        //    `A`.
        // 1. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
        //    zero sized, then `ptr` has valid provenance for `A`.
        // 2. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
        //    zero sized, then `ptr` addresses a byte range which is entirely
        //    contained in `A`.
        // 3. Per Lemma 0 and by invariant on `self`, `ptr` addresses a byte
        //    range whose length fits in an `isize`.
        // 4. Per Lemma 0 and by invariant on `self`, `ptr` addresses a byte
        //    range which does not wrap around the address space.
        // 5. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
        //    zero sized, then `A` is guaranteed to live for at least `'a`.
        unsafe { PtrInner::new(raw) }
    }
}

#[allow(clippy::needless_lifetimes)]
impl<'a, T> PtrInner<'a, T>
where
    T: ?Sized + KnownLayout<PointerMetadata = usize>,
{
    /// Splits `T` in two.
    ///
    /// # Safety
    ///
    /// The caller promises that:
    ///  - `l_len.get() <= self.meta()`.
    ///
    /// ## (Non-)Overlap
    ///
    /// Given `let (left, right) = ptr.split_at(l_len)`, it is guaranteed that
    /// `left` and `right` are contiguous and non-overlapping if
    /// `l_len.padding_needed_for() == 0`. This is true for all `[T]`.
    ///
    /// If `l_len.padding_needed_for() != 0`, then the left pointer will overlap
    /// the right pointer to satisfy `T`'s padding requirements.
    #[inline]
    #[must_use]
    pub unsafe fn split_at_unchecked(
        self,
        l_len: crate::util::MetadataOf<T>,
    ) -> (Self, PtrInner<'a, [T::Elem]>)
    where
        T: SplitAt,
    {
        let l_len = l_len.get();

        // SAFETY: The caller promises that `l_len.get() <= self.meta()`.
        // Trivially, `0 <= l_len`.
        let left = unsafe { self.with_meta(l_len) };

        let right = self.trailing_slice();
        // SAFETY: The caller promises that `l_len <= self.meta() = slf.meta()`.
        // Trivially, `slf.meta() <= slf.meta()`.
        let right = unsafe { right.slice_unchecked(l_len..self.meta().get()) };

        // SAFETY: If `l_len.padding_needed_for() == 0`, then `left` and `right`
        // are non-overlapping. Proof: `left` is constructed `slf` with `l_len`
        // as its (exclusive) upper bound. If `l_len.padding_needed_for() == 0`,
        // then `left` requires no trailing padding following its final element.
        // Since `right` is constructed from `slf`'s trailing slice with `l_len`
        // as its (inclusive) lower bound, no byte is referred to by both
        // pointers.
        //
        // Conversely, `l_len.padding_needed_for() == N`, where `N
        // > 0`, `left` requires `N` bytes of trailing padding following its
        // final element. Since `right` is constructed from the trailing slice
        // of `slf` with `l_len` as its (inclusive) lower bound, the first `N`
        // bytes of `right` are aliased by `left`.
        (left, right)
    }

    /// Produces the trailing slice of `self`.
    #[inline]
    #[must_use]
    pub fn trailing_slice(self) -> PtrInner<'a, [T::Elem]>
    where
        T: SplitAt,
    {
        let offset = crate::trailing_slice_layout::<T>().offset;

        let bytes = self.as_non_null().cast::<u8>().as_ptr();

        // SAFETY:
        // - By invariant on `T: KnownLayout`, `T::LAYOUT` describes `T`'s
        //   layout. `offset` is the offset of the trailing slice within `T`,
        //   which is by definition in-bounds or one byte past the end of any
        //   `T`, regardless of metadata. By invariant on `PtrInner`, `self`
        //   (and thus `bytes`) points to a byte range of size `<= isize::MAX`,
        //   and so `offset <= isize::MAX`. Since `size_of::<u8>() == 1`,
        //   `offset * size_of::<u8>() <= isize::MAX`.
        // - If `offset > 0`, then by invariant on `PtrInner`, `self` (and thus
        //   `bytes`) points to a byte range entirely contained within the same
        //   allocated object as `self`. As explained above, this offset results
        //   in a pointer to or one byte past the end of this allocated object.
        let bytes = unsafe { bytes.add(offset) };

        // SAFETY: By the preceding safety argument, `bytes` is within or one
        // byte past the end of the same allocated object as `self`, which
        // ensures that it is non-null.
        let bytes = unsafe { NonNull::new_unchecked(bytes) };

        let ptr = KnownLayout::raw_from_ptr_len(bytes, self.meta().get());

        // SAFETY:
        // 0. If `ptr`'s referent is not zero sized, then `ptr` is derived from
        //    some valid Rust allocation, `A`, because `ptr` is derived from
        //    the same allocated object as `self`.
        // 1. If `ptr`'s referent is not zero sized, then `ptr` has valid
        //    provenance for `A` because `raw` is derived from the same
        //    allocated object as `self` via provenance-preserving operations.
        // 2. If `ptr`'s referent is not zero sized, then `ptr` addresses a byte
        //    range which is entirely contained in `A`, by previous safety proof
        //    on `bytes`.
        // 3. `ptr` addresses a byte range whose length fits in an `isize`, by
        //    consequence of #2.
        // 4. `ptr` addresses a byte range which does not wrap around the
        //    address space, by consequence of #2.
        // 5. If `ptr`'s referent is not zero sized, then `A` is guaranteed to
        //    live for at least `'a`, because `ptr` is derived from `self`.
        unsafe { PtrInner::new(ptr) }
    }
}

#[allow(clippy::needless_lifetimes)]
impl<'a, T> PtrInner<'a, [T]> {
    /// Creates a pointer which addresses the given `range` of self.
    ///
    /// # Safety
    ///
    /// `range` is a valid range (`start <= end`) and `end <= self.meta()`.
    #[inline]
    #[must_use]
    pub unsafe fn slice_unchecked(self, range: Range<usize>) -> Self {
        let base = self.as_non_null().cast::<T>().as_ptr();

        // SAFETY: The caller promises that `start <= end <= self.meta()`. By
        // invariant, if `self`'s referent is not zero-sized, then `self` refers
        // to a byte range which is contained within a single allocation, which
        // is no more than `isize::MAX` bytes long, and which does not wrap
        // around the address space. Thus, this pointer arithmetic remains
        // in-bounds of the same allocation, and does not wrap around the
        // address space. The offset (in bytes) does not overflow `isize`.
        //
        // If `self`'s referent is zero-sized, then these conditions are
        // trivially satisfied.
        let base = unsafe { base.add(range.start) };

        // SAFETY: The caller promises that `start <= end`, and so this will not
        // underflow.
        #[allow(unstable_name_collisions)]
        let len = unsafe { range.end.unchecked_sub(range.start) };

        let ptr = core::ptr::slice_from_raw_parts_mut(base, len);

        // SAFETY: By invariant, `self`'s referent is either a ZST or lives
        // entirely in an allocation. `ptr` points inside of or one byte past
        // the end of that referent. Thus, in either case, `ptr` is non-null.
        let ptr = unsafe { NonNull::new_unchecked(ptr) };

        // SAFETY:
        //
        // Lemma 0: `ptr` addresses a subset of the bytes addressed by `self`,
        //          and has the same provenance. Proof: The caller guarantees
        //          that `start <= end <= self.meta()`. Thus, `base` is
        //          in-bounds of `self`, and `base + (end - start)` is also
        //          in-bounds of self. Finally, `ptr` is constructed using
        //          provenance-preserving operations.
        //
        // 0. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
        //    zero sized, then `ptr` has valid provenance for its referent,
        //    which is entirely contained in some Rust allocation, `A`.
        // 1. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
        //    zero sized, then `A` is guaranteed to live for at least `'a`.
        unsafe { PtrInner::new(ptr) }
    }

    /// Iteratively projects the elements `PtrInner<T>` from `PtrInner<[T]>`.
    #[inline]
    pub fn iter(&self) -> impl Iterator<Item = PtrInner<'a, T>> {
        // FIXME(#429): Once `NonNull::cast` documents that it preserves
        // provenance, cite those docs.
        let base = self.as_non_null().cast::<T>().as_ptr();
        (0..self.meta().get()).map(move |i| {
            // FIXME(https://github.com/rust-lang/rust/issues/74265): Use
            // `NonNull::get_unchecked_mut`.

            // SAFETY: If the following conditions are not satisfied
            // `pointer::cast` may induce Undefined Behavior [1]:
            //
            // > - The computed offset, `count * size_of::<T>()` bytes, must not
            // >   overflow `isize``.
            // > - If the computed offset is non-zero, then `self` must be
            // >   derived from a pointer to some allocated object, and the
            // >   entire memory range between `self` and the result must be in
            // >   bounds of that allocated object. In particular, this range
            // >   must not “wrap around” the edge of the address space.
            //
            // [1] https://doc.rust-lang.org/std/primitive.pointer.html#method.add
            //
            // We satisfy both of these conditions here:
            // - By invariant on `Ptr`, `self` addresses a byte range whose
            //   length fits in an `isize`. Since `elem` is contained in `self`,
            //   the computed offset of `elem` must fit within `isize.`
            // - If the computed offset is non-zero, then this means that the
            //   referent is not zero-sized. In this case, `base` points to an
            //   allocated object (by invariant on `self`). Thus:
            //   - By contract, `self.meta()` accurately reflects the number of
            //     elements in the slice. `i` is in bounds of `c.meta()` by
            //     construction, and so the result of this addition cannot
            //     overflow past the end of the allocation referred to by `c`.
            //   - By invariant on `Ptr`, `self` addresses a byte range which
            //     does not wrap around the address space. Since `elem` is
            //     contained in `self`, the computed offset of `elem` must wrap
            //     around the address space.
            //
            // FIXME(#429): Once `pointer::add` documents that it preserves
            // provenance, cite those docs.
            let elem = unsafe { base.add(i) };

            // SAFETY: `elem` must not be null. `base` is constructed from a
            // `NonNull` pointer, and the addition that produces `elem` must not
            // overflow or wrap around, so `elem >= base > 0`.
            //
            // FIXME(#429): Once `NonNull::new_unchecked` documents that it
            // preserves provenance, cite those docs.
            let elem = unsafe { NonNull::new_unchecked(elem) };

            // SAFETY: The safety invariants of `Ptr::new` (see definition) are
            // satisfied:
            // 0. If `elem`'s referent is not zero sized, then `elem` has valid
            //    provenance for its referent, because it derived from `self`
            //    using a series of provenance-preserving operations, and
            //    because `self` has valid provenance for its referent. By the
            //    same argument, `elem`'s referent is entirely contained within
            //    the same allocated object as `self`'s referent.
            // 1. If `elem`'s referent is not zero sized, then the allocation of
            //    `elem` is guaranteed to live for at least `'a`, because `elem`
            //    is entirely contained in `self`, which lives for at least `'a`
            //    by invariant on `Ptr`.
            unsafe { PtrInner::new(elem) }
        })
    }
}

impl<'a, T, const N: usize> PtrInner<'a, [T; N]> {
    /// Casts this pointer-to-array into a slice.
    ///
    /// # Safety
    ///
    /// Callers may assume that the returned `PtrInner` references the same
    /// address and length as `self`.
    #[allow(clippy::wrong_self_convention)]
    #[inline]
    #[must_use]
    pub fn as_slice(self) -> PtrInner<'a, [T]> {
        let start = self.as_non_null().cast::<T>().as_ptr();
        let slice = core::ptr::slice_from_raw_parts_mut(start, N);
        // SAFETY: `slice` is not null, because it is derived from `start`
        // which is non-null.
        let slice = unsafe { NonNull::new_unchecked(slice) };
        // SAFETY: Lemma: In the following safety arguments, note that `slice`
        // is derived from `self` in two steps: first, by casting `self: [T; N]`
        // to `start: T`, then by constructing a pointer to a slice starting at
        // `start` of length `N`. As a result, `slice` references exactly the
        // same allocation as `self`, if any.
        //
        // 0. By the above lemma, if `slice`'s referent is not zero sized, then
        //    `slice` has the same referent as `self`. By invariant on `self`,
        //    this referent is entirely contained within some allocation, `A`.
        //    Because `slice` was constructed using provenance-preserving
        //    operations, it has provenance for its entire referent.
        // 1. By the above lemma, if `slice`'s referent is not zero sized, then
        //    `A` is guaranteed to live for at least `'a`, because it is derived
        //    from the same allocation as `self`, which, by invariant on
        //    `PtrInner`, lives for at least `'a`.
        unsafe { PtrInner::new(slice) }
    }
}

impl<'a> PtrInner<'a, [u8]> {
    /// 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]
    pub fn try_cast_into<U>(
        self,
        cast_type: CastType,
        meta: Option<U::PointerMetadata>,
    ) -> Result<(PtrInner<'a, U>, PtrInner<'a, [u8]>), CastError<Self, U>>
    where
        U: 'a + ?Sized + KnownLayout,
    {
        // PANICS: By invariant, the byte range addressed by
        // `self.as_non_null()` does not wrap around the address space. This
        // implies that the sum of the address (represented as a `usize`) and
        // length do not overflow `usize`, as required by
        // `validate_cast_and_convert_metadata`. Thus, this call to
        // `validate_cast_and_convert_metadata` will only panic if `U` is a DST
        // whose trailing slice element is zero-sized.
        let maybe_metadata = MetadataOf::<U>::validate_cast_and_convert_metadata(
            AsAddress::addr(self.as_ptr()),
            self.meta(),
            cast_type,
            meta,
        );

        let (elems, split_at) = match maybe_metadata {
            Ok((elems, split_at)) => (elems, split_at),
            Err(MetadataCastError::Alignment) => {
                // SAFETY: Since `validate_cast_and_convert_metadata` returned
                // an alignment error, `U` must have an alignment requirement
                // greater than one.
                let err = unsafe { AlignmentError::<_, U>::new_unchecked(self) };
                return Err(CastError::Alignment(err));
            }
            Err(MetadataCastError::Size) => return Err(CastError::Size(SizeError::new(self))),
        };

        // SAFETY: `validate_cast_and_convert_metadata` promises to return
        // `split_at <= self.meta()`.
        //
        // Lemma 0: `l_slice` and `r_slice` are non-overlapping. Proof: By
        // contract on `PtrInner::split_at_unchecked`, the produced `PtrInner`s
        // are always non-overlapping if `self` is a `[T]`; here it is a `[u8]`.
        let (l_slice, r_slice) = unsafe { self.split_at_unchecked(split_at) };

        let (target, remainder) = match cast_type {
            CastType::Prefix => (l_slice, r_slice),
            CastType::Suffix => (r_slice, l_slice),
        };

        let base = target.as_non_null().cast::<u8>();

        let ptr = U::raw_from_ptr_len(base, elems.get());

        // SAFETY:
        // 0. By invariant, if `target`'s referent is not zero sized, then
        //    `target` has provenance valid for some Rust allocation, `A`.
        //    Because `ptr` is derived from `target` via provenance-preserving
        //    operations, `ptr` will also have provenance valid for its entire
        //    referent.
        // 1. `validate_cast_and_convert_metadata` promises that the object
        //    described by `elems` and `split_at` lives at a byte range which is
        //    a subset of the input byte range. Thus, by invariant, if
        //    `target`'s referent is not zero sized, then `target` refers to an
        //    allocation which is guaranteed to live for at least `'a`, and thus
        //    so does `ptr`.
        Ok((unsafe { PtrInner::new(ptr) }, remainder))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::*;

    #[test]
    fn test_meta() {
        let arr = [1; 16];
        let dst = <[u8]>::ref_from_bytes(&arr[..]).unwrap();
        let ptr = PtrInner::from_ref(dst);
        assert_eq!(ptr.meta().get(), 16);

        // SAFETY: 8 is less than 16
        let ptr = unsafe { ptr.with_meta(8) };

        assert_eq!(ptr.meta().get(), 8);
    }

    #[test]
    fn test_split_at() {
        fn test_split_at<const OFFSET: usize, const BUFFER_SIZE: usize>() {
            #[derive(FromBytes, KnownLayout, SplitAt, Immutable)]
            #[repr(C)]
            struct SliceDst<const OFFSET: usize> {
                prefix: [u8; OFFSET],
                trailing: [u8],
            }

            let n: usize = BUFFER_SIZE - OFFSET;
            let arr = [1; BUFFER_SIZE];
            let dst = SliceDst::<OFFSET>::ref_from_bytes(&arr[..]).unwrap();
            let ptr = PtrInner::from_ref(dst);
            for i in 0..=n {
                assert_eq!(ptr.meta().get(), n);
                // SAFETY: `i` is in bounds by construction.
                let i = unsafe { MetadataOf::new_unchecked(i) };
                // SAFETY: `i` is in bounds by construction.
                let (l, r) = unsafe { ptr.split_at_unchecked(i) };
                // SAFETY: Points to a valid value by construction.
                #[allow(clippy::undocumented_unsafe_blocks, clippy::as_conversions)]
                // Clippy false positive
                let l_sum: usize = l
                    .trailing_slice()
                    .iter()
                    .map(
                        #[inline(always)]
                        |ptr| unsafe { core::ptr::read_unaligned(ptr.as_ptr()) } as usize,
                    )
                    .sum();
                // SAFETY: Points to a valid value by construction.
                #[allow(clippy::undocumented_unsafe_blocks, clippy::as_conversions)]
                // Clippy false positive
                let r_sum: usize = r
                    .iter()
                    .map(
                        #[inline(always)]
                        |ptr| unsafe { core::ptr::read_unaligned(ptr.as_ptr()) } as usize,
                    )
                    .sum();
                assert_eq!(l_sum, i.get());
                assert_eq!(r_sum, n - i.get());
                assert_eq!(l_sum + r_sum, n);
            }
        }

        test_split_at::<0, 16>();
        test_split_at::<1, 17>();
        test_split_at::<2, 18>();
    }

    #[test]
    fn test_trailing_slice() {
        fn test_trailing_slice<const OFFSET: usize, const BUFFER_SIZE: usize>() {
            #[derive(FromBytes, KnownLayout, SplitAt, Immutable)]
            #[repr(C)]
            struct SliceDst<const OFFSET: usize> {
                prefix: [u8; OFFSET],
                trailing: [u8],
            }

            let n: usize = BUFFER_SIZE - OFFSET;
            let arr = [1; BUFFER_SIZE];
            let dst = SliceDst::<OFFSET>::ref_from_bytes(&arr[..]).unwrap();
            let ptr = PtrInner::from_ref(dst);

            assert_eq!(ptr.meta().get(), n);
            let trailing = ptr.trailing_slice();
            assert_eq!(trailing.meta().get(), n);

            assert_eq!(
                // SAFETY: We assume this to be sound for the sake of this test,
                // which will fail, here, in miri, if the safety precondition of
                // `offset_of` is not satisfied.
                unsafe {
                    #[allow(clippy::as_conversions)]
                    let offset = (trailing.as_ptr() as *mut u8).offset_from(ptr.as_ptr() as *mut _);
                    offset
                },
                isize::try_from(OFFSET).unwrap(),
            );

            // SAFETY: Points to a valid value by construction.
            #[allow(clippy::undocumented_unsafe_blocks, clippy::as_conversions)]
            // Clippy false positive
            let trailing: usize = trailing
                .iter()
                .map(|ptr| unsafe { core::ptr::read_unaligned(ptr.as_ptr()) } as usize)
                .sum();

            assert_eq!(trailing, n);
        }

        test_trailing_slice::<0, 16>();
        test_trailing_slice::<1, 17>();
        test_trailing_slice::<2, 18>();
    }
    #[test]
    fn test_ptr_inner_clone() {
        let mut x = 0u8;
        let p = PtrInner::from_mut(&mut x);
        #[allow(clippy::clone_on_copy)]
        let p2 = p.clone();
        assert_eq!(p.as_non_null(), p2.as_non_null());
    }
}
