Coverage Report

Created: 2026-04-12 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.48/src/pointer/inner.rs
Line
Count
Source
1
// Copyright 2024 The Fuchsia Authors
2
//
3
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6
// This file may not be copied, modified, or distributed except according to
7
// those terms.
8
9
use core::{marker::PhantomData, ops::Range, ptr::NonNull};
10
11
pub use _def::PtrInner;
12
13
#[allow(unused_imports)]
14
use crate::util::polyfills::NumExt as _;
15
use crate::{
16
    layout::{CastType, MetadataCastError},
17
    pointer::cast,
18
    util::AsAddress,
19
    AlignmentError, CastError, KnownLayout, MetadataOf, SizeError, SplitAt,
20
};
21
22
mod _def {
23
    use super::*;
24
    /// The inner pointer stored inside a [`Ptr`][crate::Ptr].
25
    ///
26
    /// `PtrInner<'a, T>` is [covariant] in `'a` and invariant in `T`.
27
    ///
28
    /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
29
    #[allow(missing_debug_implementations)]
30
    pub struct PtrInner<'a, T>
31
    where
32
        T: ?Sized,
33
    {
34
        /// # Invariants
35
        ///
36
        /// 0. If `ptr`'s referent is not zero sized, then `ptr` has valid
37
        ///    provenance for its referent, which is entirely contained in some
38
        ///    Rust allocation, `A`.
39
        /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live
40
        ///    for at least `'a`.
41
        ///
42
        /// # Postconditions
43
        ///
44
        /// By virtue of these invariants, code may assume the following, which
45
        /// are logical implications of the invariants:
46
        /// - `ptr`'s referent is not larger than `isize::MAX` bytes \[1\]
47
        /// - `ptr`'s referent does not wrap around the address space \[1\]
48
        ///
49
        /// \[1\] Per <https://doc.rust-lang.org/1.85.0/std/ptr/index.html#allocated-object>:
50
        ///
51
        ///   For any allocated object with `base` address, `size`, and a set of
52
        ///   `addresses`, the following are guaranteed:
53
        ///   ...
54
        ///   - `size <= isize::MAX`
55
        ///
56
        ///   As a consequence of these guarantees, given any address `a` within
57
        ///   the set of addresses of an allocated object:
58
        ///   ...
59
        ///   - It is guaranteed that, given `o = a - base` (i.e., the offset of
60
        ///     `a` within the allocated object), `base + o` will not wrap
61
        ///     around the address space (in other words, will not overflow
62
        ///     `usize`)
63
        ptr: NonNull<T>,
64
        // SAFETY: `&'a UnsafeCell<T>` is covariant in `'a` and invariant in `T`
65
        // [1]. We use this construction rather than the equivalent `&mut T`,
66
        // because our MSRV of 1.65 prohibits `&mut` types in const contexts.
67
        //
68
        // [1] https://doc.rust-lang.org/1.81.0/reference/subtyping.html#variance
69
        _marker: PhantomData<&'a core::cell::UnsafeCell<T>>,
70
    }
71
72
    impl<'a, T: 'a + ?Sized> Copy for PtrInner<'a, T> {}
73
    impl<'a, T: 'a + ?Sized> Clone for PtrInner<'a, T> {
74
        #[inline(always)]
75
0
        fn clone(&self) -> PtrInner<'a, T> {
76
            // SAFETY: None of the invariants on `ptr` are affected by having
77
            // multiple copies of a `PtrInner`.
78
0
            *self
79
0
        }
80
    }
81
82
    impl<'a, T: 'a + ?Sized> PtrInner<'a, T> {
83
        /// Constructs a `Ptr` from a [`NonNull`].
84
        ///
85
        /// # Safety
86
        ///
87
        /// The caller promises that:
88
        ///
89
        /// 0. If `ptr`'s referent is not zero sized, then `ptr` has valid
90
        ///    provenance for its referent, which is entirely contained in some
91
        ///    Rust allocation, `A`.
92
        /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live
93
        ///    for at least `'a`.
94
        #[inline(always)]
95
        #[must_use]
96
1.38M
        pub const unsafe fn new(ptr: NonNull<T>) -> PtrInner<'a, T> {
97
            // SAFETY: The caller has promised to satisfy all safety invariants
98
            // of `PtrInner`.
99
1.38M
            Self { ptr, _marker: PhantomData }
100
1.38M
        }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::new
Line
Count
Source
96
346k
        pub const unsafe fn new(ptr: NonNull<T>) -> PtrInner<'a, T> {
97
            // SAFETY: The caller has promised to satisfy all safety invariants
98
            // of `PtrInner`.
99
346k
            Self { ptr, _marker: PhantomData }
100
346k
        }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::new
Line
Count
Source
96
346k
        pub const unsafe fn new(ptr: NonNull<T>) -> PtrInner<'a, T> {
97
            // SAFETY: The caller has promised to satisfy all safety invariants
98
            // of `PtrInner`.
99
346k
            Self { ptr, _marker: PhantomData }
100
346k
        }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::new
Line
Count
Source
96
346k
        pub const unsafe fn new(ptr: NonNull<T>) -> PtrInner<'a, T> {
97
            // SAFETY: The caller has promised to satisfy all safety invariants
98
            // of `PtrInner`.
99
346k
            Self { ptr, _marker: PhantomData }
100
346k
        }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::new
Line
Count
Source
96
346k
        pub const unsafe fn new(ptr: NonNull<T>) -> PtrInner<'a, T> {
97
            // SAFETY: The caller has promised to satisfy all safety invariants
98
            // of `PtrInner`.
99
346k
            Self { ptr, _marker: PhantomData }
100
346k
        }
Unexecuted instantiation: <zerocopy::pointer::inner::_def::PtrInner<_>>::new
101
102
        /// Converts this `PtrInner<T>` to a [`NonNull<T>`].
103
        ///
104
        /// Note that this method does not consume `self`. The caller should
105
        /// watch out for `unsafe` code which uses the returned `NonNull` in a
106
        /// way that violates the safety invariants of `self`.
107
        #[inline(always)]
108
        #[must_use]
109
693k
        pub const fn as_non_null(&self) -> NonNull<T> {
110
693k
            self.ptr
111
693k
        }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::as_non_null
Line
Count
Source
109
173k
        pub const fn as_non_null(&self) -> NonNull<T> {
110
173k
            self.ptr
111
173k
        }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::as_non_null
Line
Count
Source
109
346k
        pub const fn as_non_null(&self) -> NonNull<T> {
110
346k
            self.ptr
111
346k
        }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::as_non_null
Line
Count
Source
109
173k
        pub const fn as_non_null(&self) -> NonNull<T> {
110
173k
            self.ptr
111
173k
        }
Unexecuted instantiation: <zerocopy::pointer::inner::_def::PtrInner<_>>::as_non_null
112
113
        /// Converts this `PtrInner<T>` to a [`*mut T`].
114
        ///
115
        /// Note that this method does not consume `self`. The caller should
116
        /// watch out for `unsafe` code which uses the returned `*mut T` in a
117
        /// way that violates the safety invariants of `self`.
118
        #[inline(always)]
119
        #[must_use]
120
1.03M
        pub const fn as_ptr(&self) -> *mut T {
121
1.03M
            self.ptr.as_ptr()
122
1.03M
        }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::as_ptr
Line
Count
Source
120
173k
        pub const fn as_ptr(&self) -> *mut T {
121
173k
            self.ptr.as_ptr()
122
173k
        }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::as_ptr
Line
Count
Source
120
173k
        pub const fn as_ptr(&self) -> *mut T {
121
173k
            self.ptr.as_ptr()
122
173k
        }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::as_ptr
Line
Count
Source
120
519k
        pub const fn as_ptr(&self) -> *mut T {
121
519k
            self.ptr.as_ptr()
122
519k
        }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::as_ptr
Line
Count
Source
120
173k
        pub const fn as_ptr(&self) -> *mut T {
121
173k
            self.ptr.as_ptr()
122
173k
        }
Unexecuted instantiation: <zerocopy::pointer::inner::_def::PtrInner<_>>::as_ptr
123
    }
124
}
125
126
impl<'a, T: ?Sized> PtrInner<'a, T> {
127
    /// Constructs a `PtrInner` from a reference.
128
    #[inline]
129
173k
    pub(crate) fn from_ref(ptr: &'a T) -> Self {
130
173k
        let ptr = NonNull::from(ptr);
131
        // SAFETY:
132
        // 0. If `ptr`'s referent is not zero sized, then `ptr`, by invariant on
133
        //    `&'a T` [1], has valid provenance for its referent, which is
134
        //    entirely contained in some Rust allocation, `A`.
135
        // 1. If `ptr`'s referent is not zero sized, then `A`, by invariant on
136
        //    `&'a T`, is guaranteed to live for at least `'a`.
137
        //
138
        // [1] Per https://doc.rust-lang.org/1.85.0/std/primitive.reference.html#safety:
139
        //
140
        //   For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`,
141
        //   when such values cross an API boundary, the following invariants
142
        //   must generally be upheld:
143
        //   ...
144
        //   - if `size_of_val(t) > 0`, then `t` is dereferenceable for
145
        //     `size_of_val(t)` many bytes
146
        //
147
        //   If `t` points at address `a`, being “dereferenceable” for N bytes
148
        //   means that the memory range `[a, a + N)` is all contained within a
149
        //   single allocated object.
150
173k
        unsafe { Self::new(ptr) }
151
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::from_ref
Line
Count
Source
129
173k
    pub(crate) fn from_ref(ptr: &'a T) -> Self {
130
173k
        let ptr = NonNull::from(ptr);
131
        // SAFETY:
132
        // 0. If `ptr`'s referent is not zero sized, then `ptr`, by invariant on
133
        //    `&'a T` [1], has valid provenance for its referent, which is
134
        //    entirely contained in some Rust allocation, `A`.
135
        // 1. If `ptr`'s referent is not zero sized, then `A`, by invariant on
136
        //    `&'a T`, is guaranteed to live for at least `'a`.
137
        //
138
        // [1] Per https://doc.rust-lang.org/1.85.0/std/primitive.reference.html#safety:
139
        //
140
        //   For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`,
141
        //   when such values cross an API boundary, the following invariants
142
        //   must generally be upheld:
143
        //   ...
144
        //   - if `size_of_val(t) > 0`, then `t` is dereferenceable for
145
        //     `size_of_val(t)` many bytes
146
        //
147
        //   If `t` points at address `a`, being “dereferenceable” for N bytes
148
        //   means that the memory range `[a, a + N)` is all contained within a
149
        //   single allocated object.
150
173k
        unsafe { Self::new(ptr) }
151
173k
    }
Unexecuted instantiation: <zerocopy::pointer::inner::_def::PtrInner<_>>::from_ref
152
153
    /// Constructs a `PtrInner` from a mutable reference.
154
    #[inline]
155
173k
    pub(crate) fn from_mut(ptr: &'a mut T) -> Self {
156
173k
        let ptr = NonNull::from(ptr);
157
        // SAFETY:
158
        // 0. If `ptr`'s referent is not zero sized, then `ptr`, by invariant on
159
        //    `&'a mut T` [1], has valid provenance for its referent, which is
160
        //    entirely contained in some Rust allocation, `A`.
161
        // 1. If `ptr`'s referent is not zero sized, then `A`, by invariant on
162
        //    `&'a mut T`, is guaranteed to live for at least `'a`.
163
        //
164
        // [1] Per https://doc.rust-lang.org/1.85.0/std/primitive.reference.html#safety:
165
        //
166
        //   For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`,
167
        //   when such values cross an API boundary, the following invariants
168
        //   must generally be upheld:
169
        //   ...
170
        //   - if `size_of_val(t) > 0`, then `t` is dereferenceable for
171
        //     `size_of_val(t)` many bytes
172
        //
173
        //   If `t` points at address `a`, being “dereferenceable” for N bytes
174
        //   means that the memory range `[a, a + N)` is all contained within a
175
        //   single allocated object.
176
173k
        unsafe { Self::new(ptr) }
177
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::from_mut
Line
Count
Source
155
173k
    pub(crate) fn from_mut(ptr: &'a mut T) -> Self {
156
173k
        let ptr = NonNull::from(ptr);
157
        // SAFETY:
158
        // 0. If `ptr`'s referent is not zero sized, then `ptr`, by invariant on
159
        //    `&'a mut T` [1], has valid provenance for its referent, which is
160
        //    entirely contained in some Rust allocation, `A`.
161
        // 1. If `ptr`'s referent is not zero sized, then `A`, by invariant on
162
        //    `&'a mut T`, is guaranteed to live for at least `'a`.
163
        //
164
        // [1] Per https://doc.rust-lang.org/1.85.0/std/primitive.reference.html#safety:
165
        //
166
        //   For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`,
167
        //   when such values cross an API boundary, the following invariants
168
        //   must generally be upheld:
169
        //   ...
170
        //   - if `size_of_val(t) > 0`, then `t` is dereferenceable for
171
        //     `size_of_val(t)` many bytes
172
        //
173
        //   If `t` points at address `a`, being “dereferenceable” for N bytes
174
        //   means that the memory range `[a, a + N)` is all contained within a
175
        //   single allocated object.
176
173k
        unsafe { Self::new(ptr) }
177
173k
    }
Unexecuted instantiation: <zerocopy::pointer::inner::_def::PtrInner<_>>::from_mut
178
179
    /// # Safety
180
    ///
181
    /// The caller may assume that the resulting `PtrInner` addresses the subset
182
    /// of the bytes of `self`'s referent addressed by `C::project(self)`.
183
    #[must_use]
184
    #[inline(always)]
185
1.03M
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
1.03M
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
1.03M
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
1.03M
        unsafe { PtrInner::new(projected_non_null) }
212
1.03M
    }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::project::<[half::binary16::f16], zerocopy::pointer::cast::IdCast>
Line
Count
Source
185
173k
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
173k
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
173k
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
173k
        unsafe { PtrInner::new(projected_non_null) }
212
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::project::<[u16], zerocopy::layout::cast_from::CastFrom<[u16]>>
Line
Count
Source
185
173k
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
173k
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
173k
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
173k
        unsafe { PtrInner::new(projected_non_null) }
212
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::project::<[u16], zerocopy::pointer::cast::IdCast>
Line
Count
Source
185
173k
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
173k
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
173k
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
173k
        unsafe { PtrInner::new(projected_non_null) }
212
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::project::<[half::binary16::f16], zerocopy::pointer::cast::IdCast>
Line
Count
Source
185
173k
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
173k
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
173k
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
173k
        unsafe { PtrInner::new(projected_non_null) }
212
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[half::binary16::f16]>>::project::<[u16], zerocopy::layout::cast_from::CastFrom<[u16]>>
Line
Count
Source
185
173k
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
173k
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
173k
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
173k
        unsafe { PtrInner::new(projected_non_null) }
212
173k
    }
<zerocopy::pointer::inner::_def::PtrInner<[u16]>>::project::<[u16], zerocopy::pointer::cast::IdCast>
Line
Count
Source
185
173k
    pub fn project<U: ?Sized, C: cast::Project<T, U>>(self) -> PtrInner<'a, U> {
186
173k
        let projected_raw = C::project(self);
187
188
        // SAFETY: `self`'s referent lives at a `NonNull` address, and is either
189
        // zero-sized or lives in an allocation. In either case, it does not
190
        // wrap around the address space [1], and so none of the addresses
191
        // contained in it or one-past-the-end of it are null.
192
        //
193
        // By invariant on `C: Project`, `C::project` is a provenance-preserving
194
        // projection which preserves or shrinks the set of referent bytes, so
195
        // `projected_raw` references a subset of `self`'s referent, and so it
196
        // cannot be null.
197
        //
198
        // [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
199
173k
        let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
200
201
        // SAFETY: As described in the preceding safety comment, `projected_raw`,
202
        // and thus `projected_non_null`, addresses a subset of `self`'s
203
        // referent. Thus, `projected_non_null` either:
204
        // - Addresses zero bytes or,
205
        // - Addresses a subset of the referent of `self`. In this case, `self`
206
        //   has provenance for its referent, which lives in an allocation.
207
        //   Since `projected_non_null` was constructed using a sequence of
208
        //   provenance-preserving operations, it also has provenance for its
209
        //   referent and that referent lives in an allocation. By invariant on
210
        //   `self`, that allocation lives for `'a`.
211
173k
        unsafe { PtrInner::new(projected_non_null) }
212
173k
    }
Unexecuted instantiation: <zerocopy::pointer::inner::_def::PtrInner<_>>::project::<_, _>
213
}
214
215
#[allow(clippy::needless_lifetimes)]
216
impl<'a, T> PtrInner<'a, T>
217
where
218
    T: ?Sized + KnownLayout,
219
{
220
    /// Extracts the metadata of this `ptr`.
221
0
    pub(crate) fn meta(self) -> MetadataOf<T> {
222
0
        let meta = T::pointer_to_metadata(self.as_ptr());
223
        // SAFETY: By invariant on `PtrInner`, `self.as_non_null()` addresses no
224
        // more than `isize::MAX` bytes.
225
0
        unsafe { MetadataOf::new_unchecked(meta) }
226
0
    }
227
228
    /// Produces a `PtrInner` with the same address and provenance as `self` but
229
    /// the given `meta`.
230
    ///
231
    /// # Safety
232
    ///
233
    /// The caller promises that if `self`'s referent is not zero sized, then
234
    /// a pointer constructed from its address with the given `meta` metadata
235
    /// will address a subset of the allocation pointed to by `self`.
236
    #[inline]
237
0
    pub(crate) unsafe fn with_meta(self, meta: T::PointerMetadata) -> Self
238
0
    where
239
0
        T: KnownLayout,
240
    {
241
0
        let raw = T::raw_from_ptr_len(self.as_non_null().cast(), meta);
242
243
        // SAFETY:
244
        //
245
        // Lemma 0: `raw` either addresses zero bytes, or addresses a subset of
246
        //          the allocation pointed to by `self` and has the same
247
        //          provenance as `self`. Proof: `raw` is constructed using
248
        //          provenance-preserving operations, and the caller has
249
        //          promised that, if `self`'s referent is not zero-sized, the
250
        //          resulting pointer addresses a subset of the allocation
251
        //          pointed to by `self`.
252
        //
253
        // 0. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
254
        //    zero sized, then `ptr` is derived from some valid Rust allocation,
255
        //    `A`.
256
        // 1. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
257
        //    zero sized, then `ptr` has valid provenance for `A`.
258
        // 2. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
259
        //    zero sized, then `ptr` addresses a byte range which is entirely
260
        //    contained in `A`.
261
        // 3. Per Lemma 0 and by invariant on `self`, `ptr` addresses a byte
262
        //    range whose length fits in an `isize`.
263
        // 4. Per Lemma 0 and by invariant on `self`, `ptr` addresses a byte
264
        //    range which does not wrap around the address space.
265
        // 5. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
266
        //    zero sized, then `A` is guaranteed to live for at least `'a`.
267
0
        unsafe { PtrInner::new(raw) }
268
0
    }
269
}
270
271
#[allow(clippy::needless_lifetimes)]
272
impl<'a, T> PtrInner<'a, T>
273
where
274
    T: ?Sized + KnownLayout<PointerMetadata = usize>,
275
{
276
    /// Splits `T` in two.
277
    ///
278
    /// # Safety
279
    ///
280
    /// The caller promises that:
281
    ///  - `l_len.get() <= self.meta()`.
282
    ///
283
    /// ## (Non-)Overlap
284
    ///
285
    /// Given `let (left, right) = ptr.split_at(l_len)`, it is guaranteed that
286
    /// `left` and `right` are contiguous and non-overlapping if
287
    /// `l_len.padding_needed_for() == 0`. This is true for all `[T]`.
288
    ///
289
    /// If `l_len.padding_needed_for() != 0`, then the left pointer will overlap
290
    /// the right pointer to satisfy `T`'s padding requirements.
291
0
    pub(crate) unsafe fn split_at_unchecked(
292
0
        self,
293
0
        l_len: crate::util::MetadataOf<T>,
294
0
    ) -> (Self, PtrInner<'a, [T::Elem]>)
295
0
    where
296
0
        T: SplitAt,
297
    {
298
0
        let l_len = l_len.get();
299
300
        // SAFETY: The caller promises that `l_len.get() <= self.meta()`.
301
        // Trivially, `0 <= l_len`.
302
0
        let left = unsafe { self.with_meta(l_len) };
303
304
0
        let right = self.trailing_slice();
305
        // SAFETY: The caller promises that `l_len <= self.meta() = slf.meta()`.
306
        // Trivially, `slf.meta() <= slf.meta()`.
307
0
        let right = unsafe { right.slice_unchecked(l_len..self.meta().get()) };
308
309
        // SAFETY: If `l_len.padding_needed_for() == 0`, then `left` and `right`
310
        // are non-overlapping. Proof: `left` is constructed `slf` with `l_len`
311
        // as its (exclusive) upper bound. If `l_len.padding_needed_for() == 0`,
312
        // then `left` requires no trailing padding following its final element.
313
        // Since `right` is constructed from `slf`'s trailing slice with `l_len`
314
        // as its (inclusive) lower bound, no byte is referred to by both
315
        // pointers.
316
        //
317
        // Conversely, `l_len.padding_needed_for() == N`, where `N
318
        // > 0`, `left` requires `N` bytes of trailing padding following its
319
        // final element. Since `right` is constructed from the trailing slice
320
        // of `slf` with `l_len` as its (inclusive) lower bound, the first `N`
321
        // bytes of `right` are aliased by `left`.
322
0
        (left, right)
323
0
    }
324
325
    /// Produces the trailing slice of `self`.
326
0
    pub(crate) fn trailing_slice(self) -> PtrInner<'a, [T::Elem]>
327
0
    where
328
0
        T: SplitAt,
329
    {
330
0
        let offset = crate::trailing_slice_layout::<T>().offset;
331
332
0
        let bytes = self.as_non_null().cast::<u8>().as_ptr();
333
334
        // SAFETY:
335
        // - By invariant on `T: KnownLayout`, `T::LAYOUT` describes `T`'s
336
        //   layout. `offset` is the offset of the trailing slice within `T`,
337
        //   which is by definition in-bounds or one byte past the end of any
338
        //   `T`, regardless of metadata. By invariant on `PtrInner`, `self`
339
        //   (and thus `bytes`) points to a byte range of size `<= isize::MAX`,
340
        //   and so `offset <= isize::MAX`. Since `size_of::<u8>() == 1`,
341
        //   `offset * size_of::<u8>() <= isize::MAX`.
342
        // - If `offset > 0`, then by invariant on `PtrInner`, `self` (and thus
343
        //   `bytes`) points to a byte range entirely contained within the same
344
        //   allocated object as `self`. As explained above, this offset results
345
        //   in a pointer to or one byte past the end of this allocated object.
346
0
        let bytes = unsafe { bytes.add(offset) };
347
348
        // SAFETY: By the preceding safety argument, `bytes` is within or one
349
        // byte past the end of the same allocated object as `self`, which
350
        // ensures that it is non-null.
351
0
        let bytes = unsafe { NonNull::new_unchecked(bytes) };
352
353
0
        let ptr = KnownLayout::raw_from_ptr_len(bytes, self.meta().get());
354
355
        // SAFETY:
356
        // 0. If `ptr`'s referent is not zero sized, then `ptr` is derived from
357
        //    some valid Rust allocation, `A`, because `ptr` is derived from
358
        //    the same allocated object as `self`.
359
        // 1. If `ptr`'s referent is not zero sized, then `ptr` has valid
360
        //    provenance for `A` because `raw` is derived from the same
361
        //    allocated object as `self` via provenance-preserving operations.
362
        // 2. If `ptr`'s referent is not zero sized, then `ptr` addresses a byte
363
        //    range which is entirely contained in `A`, by previous safety proof
364
        //    on `bytes`.
365
        // 3. `ptr` addresses a byte range whose length fits in an `isize`, by
366
        //    consequence of #2.
367
        // 4. `ptr` addresses a byte range which does not wrap around the
368
        //    address space, by consequence of #2.
369
        // 5. If `ptr`'s referent is not zero sized, then `A` is guaranteed to
370
        //    live for at least `'a`, because `ptr` is derived from `self`.
371
0
        unsafe { PtrInner::new(ptr) }
372
0
    }
373
}
374
375
#[allow(clippy::needless_lifetimes)]
376
impl<'a, T> PtrInner<'a, [T]> {
377
    /// Creates a pointer which addresses the given `range` of self.
378
    ///
379
    /// # Safety
380
    ///
381
    /// `range` is a valid range (`start <= end`) and `end <= self.meta()`.
382
0
    pub(crate) unsafe fn slice_unchecked(self, range: Range<usize>) -> Self {
383
0
        let base = self.as_non_null().cast::<T>().as_ptr();
384
385
        // SAFETY: The caller promises that `start <= end <= self.meta()`. By
386
        // invariant, if `self`'s referent is not zero-sized, then `self` refers
387
        // to a byte range which is contained within a single allocation, which
388
        // is no more than `isize::MAX` bytes long, and which does not wrap
389
        // around the address space. Thus, this pointer arithmetic remains
390
        // in-bounds of the same allocation, and does not wrap around the
391
        // address space. The offset (in bytes) does not overflow `isize`.
392
        //
393
        // If `self`'s referent is zero-sized, then these conditions are
394
        // trivially satisfied.
395
0
        let base = unsafe { base.add(range.start) };
396
397
        // SAFETY: The caller promises that `start <= end`, and so this will not
398
        // underflow.
399
        #[allow(unstable_name_collisions)]
400
0
        let len = unsafe { range.end.unchecked_sub(range.start) };
401
402
0
        let ptr = core::ptr::slice_from_raw_parts_mut(base, len);
403
404
        // SAFETY: By invariant, `self`'s referent is either a ZST or lives
405
        // entirely in an allocation. `ptr` points inside of or one byte past
406
        // the end of that referent. Thus, in either case, `ptr` is non-null.
407
0
        let ptr = unsafe { NonNull::new_unchecked(ptr) };
408
409
        // SAFETY:
410
        //
411
        // Lemma 0: `ptr` addresses a subset of the bytes addressed by `self`,
412
        //          and has the same provenance. Proof: The caller guarantees
413
        //          that `start <= end <= self.meta()`. Thus, `base` is
414
        //          in-bounds of `self`, and `base + (end - start)` is also
415
        //          in-bounds of self. Finally, `ptr` is constructed using
416
        //          provenance-preserving operations.
417
        //
418
        // 0. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
419
        //    zero sized, then `ptr` has valid provenance for its referent,
420
        //    which is entirely contained in some Rust allocation, `A`.
421
        // 1. Per Lemma 0 and by invariant on `self`, if `ptr`'s referent is not
422
        //    zero sized, then `A` is guaranteed to live for at least `'a`.
423
0
        unsafe { PtrInner::new(ptr) }
424
0
    }
425
426
    /// Iteratively projects the elements `PtrInner<T>` from `PtrInner<[T]>`.
427
0
    pub(crate) fn iter(&self) -> impl Iterator<Item = PtrInner<'a, T>> {
428
        // FIXME(#429): Once `NonNull::cast` documents that it preserves
429
        // provenance, cite those docs.
430
0
        let base = self.as_non_null().cast::<T>().as_ptr();
431
0
        (0..self.meta().get()).map(move |i| {
432
            // FIXME(https://github.com/rust-lang/rust/issues/74265): Use
433
            // `NonNull::get_unchecked_mut`.
434
435
            // SAFETY: If the following conditions are not satisfied
436
            // `pointer::cast` may induce Undefined Behavior [1]:
437
            //
438
            // > - The computed offset, `count * size_of::<T>()` bytes, must not
439
            // >   overflow `isize``.
440
            // > - If the computed offset is non-zero, then `self` must be
441
            // >   derived from a pointer to some allocated object, and the
442
            // >   entire memory range between `self` and the result must be in
443
            // >   bounds of that allocated object. In particular, this range
444
            // >   must not “wrap around” the edge of the address space.
445
            //
446
            // [1] https://doc.rust-lang.org/std/primitive.pointer.html#method.add
447
            //
448
            // We satisfy both of these conditions here:
449
            // - By invariant on `Ptr`, `self` addresses a byte range whose
450
            //   length fits in an `isize`. Since `elem` is contained in `self`,
451
            //   the computed offset of `elem` must fit within `isize.`
452
            // - If the computed offset is non-zero, then this means that the
453
            //   referent is not zero-sized. In this case, `base` points to an
454
            //   allocated object (by invariant on `self`). Thus:
455
            //   - By contract, `self.meta()` accurately reflects the number of
456
            //     elements in the slice. `i` is in bounds of `c.meta()` by
457
            //     construction, and so the result of this addition cannot
458
            //     overflow past the end of the allocation referred to by `c`.
459
            //   - By invariant on `Ptr`, `self` addresses a byte range which
460
            //     does not wrap around the address space. Since `elem` is
461
            //     contained in `self`, the computed offset of `elem` must wrap
462
            //     around the address space.
463
            //
464
            // FIXME(#429): Once `pointer::add` documents that it preserves
465
            // provenance, cite those docs.
466
0
            let elem = unsafe { base.add(i) };
467
468
            // SAFETY: `elem` must not be null. `base` is constructed from a
469
            // `NonNull` pointer, and the addition that produces `elem` must not
470
            // overflow or wrap around, so `elem >= base > 0`.
471
            //
472
            // FIXME(#429): Once `NonNull::new_unchecked` documents that it
473
            // preserves provenance, cite those docs.
474
0
            let elem = unsafe { NonNull::new_unchecked(elem) };
475
476
            // SAFETY: The safety invariants of `Ptr::new` (see definition) are
477
            // satisfied:
478
            // 0. If `elem`'s referent is not zero sized, then `elem` has valid
479
            //    provenance for its referent, because it derived from `self`
480
            //    using a series of provenance-preserving operations, and
481
            //    because `self` has valid provenance for its referent. By the
482
            //    same argument, `elem`'s referent is entirely contained within
483
            //    the same allocated object as `self`'s referent.
484
            // 1. If `elem`'s referent is not zero sized, then the allocation of
485
            //    `elem` is guaranteed to live for at least `'a`, because `elem`
486
            //    is entirely contained in `self`, which lives for at least `'a`
487
            //    by invariant on `Ptr`.
488
0
            unsafe { PtrInner::new(elem) }
489
0
        })
490
0
    }
491
}
492
493
impl<'a, T, const N: usize> PtrInner<'a, [T; N]> {
494
    /// Casts this pointer-to-array into a slice.
495
    ///
496
    /// # Safety
497
    ///
498
    /// Callers may assume that the returned `PtrInner` references the same
499
    /// address and length as `self`.
500
    #[allow(clippy::wrong_self_convention)]
501
0
    pub(crate) fn as_slice(self) -> PtrInner<'a, [T]> {
502
0
        let start = self.as_non_null().cast::<T>().as_ptr();
503
0
        let slice = core::ptr::slice_from_raw_parts_mut(start, N);
504
        // SAFETY: `slice` is not null, because it is derived from `start`
505
        // which is non-null.
506
0
        let slice = unsafe { NonNull::new_unchecked(slice) };
507
        // SAFETY: Lemma: In the following safety arguments, note that `slice`
508
        // is derived from `self` in two steps: first, by casting `self: [T; N]`
509
        // to `start: T`, then by constructing a pointer to a slice starting at
510
        // `start` of length `N`. As a result, `slice` references exactly the
511
        // same allocation as `self`, if any.
512
        //
513
        // 0. By the above lemma, if `slice`'s referent is not zero sized, then
514
        //    `slice` has the same referent as `self`. By invariant on `self`,
515
        //    this referent is entirely contained within some allocation, `A`.
516
        //    Because `slice` was constructed using provenance-preserving
517
        //    operations, it has provenance for its entire referent.
518
        // 1. By the above lemma, if `slice`'s referent is not zero sized, then
519
        //    `A` is guaranteed to live for at least `'a`, because it is derived
520
        //    from the same allocation as `self`, which, by invariant on
521
        //    `PtrInner`, lives for at least `'a`.
522
0
        unsafe { PtrInner::new(slice) }
523
0
    }
524
}
525
526
impl<'a> PtrInner<'a, [u8]> {
527
    /// Attempts to cast `self` to a `U` using the given cast type.
528
    ///
529
    /// If `U` is a slice DST and pointer metadata (`meta`) is provided, then
530
    /// the cast will only succeed if it would produce an object with the given
531
    /// metadata.
532
    ///
533
    /// Returns `None` if the resulting `U` would be invalidly-aligned, if no
534
    /// `U` can fit in `self`, or if the provided pointer metadata describes an
535
    /// invalid instance of `U`. On success, returns a pointer to the
536
    /// largest-possible `U` which fits in `self`.
537
    ///
538
    /// # Safety
539
    ///
540
    /// The caller may assume that this implementation is correct, and may rely
541
    /// on that assumption for the soundness of their code. In particular, the
542
    /// caller may assume that, if `try_cast_into` returns `Some((ptr,
543
    /// remainder))`, then `ptr` and `remainder` refer to non-overlapping byte
544
    /// ranges within `self`, and that `ptr` and `remainder` entirely cover
545
    /// `self`. Finally:
546
    /// - If this is a prefix cast, `ptr` has the same address as `self`.
547
    /// - If this is a suffix cast, `remainder` has the same address as `self`.
548
    #[inline]
549
0
    pub(crate) fn try_cast_into<U>(
550
0
        self,
551
0
        cast_type: CastType,
552
0
        meta: Option<U::PointerMetadata>,
553
0
    ) -> Result<(PtrInner<'a, U>, PtrInner<'a, [u8]>), CastError<Self, U>>
554
0
    where
555
0
        U: 'a + ?Sized + KnownLayout,
556
    {
557
        // PANICS: By invariant, the byte range addressed by
558
        // `self.as_non_null()` does not wrap around the address space. This
559
        // implies that the sum of the address (represented as a `usize`) and
560
        // length do not overflow `usize`, as required by
561
        // `validate_cast_and_convert_metadata`. Thus, this call to
562
        // `validate_cast_and_convert_metadata` will only panic if `U` is a DST
563
        // whose trailing slice element is zero-sized.
564
0
        let maybe_metadata = MetadataOf::<U>::validate_cast_and_convert_metadata(
565
0
            AsAddress::addr(self.as_ptr()),
566
0
            self.meta(),
567
0
            cast_type,
568
0
            meta,
569
        );
570
571
0
        let (elems, split_at) = match maybe_metadata {
572
0
            Ok((elems, split_at)) => (elems, split_at),
573
            Err(MetadataCastError::Alignment) => {
574
                // SAFETY: Since `validate_cast_and_convert_metadata` returned
575
                // an alignment error, `U` must have an alignment requirement
576
                // greater than one.
577
0
                let err = unsafe { AlignmentError::<_, U>::new_unchecked(self) };
578
0
                return Err(CastError::Alignment(err));
579
            }
580
0
            Err(MetadataCastError::Size) => return Err(CastError::Size(SizeError::new(self))),
581
        };
582
583
        // SAFETY: `validate_cast_and_convert_metadata` promises to return
584
        // `split_at <= self.meta()`.
585
        //
586
        // Lemma 0: `l_slice` and `r_slice` are non-overlapping. Proof: By
587
        // contract on `PtrInner::split_at_unchecked`, the produced `PtrInner`s
588
        // are always non-overlapping if `self` is a `[T]`; here it is a `[u8]`.
589
0
        let (l_slice, r_slice) = unsafe { self.split_at_unchecked(split_at) };
590
591
0
        let (target, remainder) = match cast_type {
592
0
            CastType::Prefix => (l_slice, r_slice),
593
0
            CastType::Suffix => (r_slice, l_slice),
594
        };
595
596
0
        let base = target.as_non_null().cast::<u8>();
597
598
0
        let ptr = U::raw_from_ptr_len(base, elems.get());
599
600
        // SAFETY:
601
        // 0. By invariant, if `target`'s referent is not zero sized, then
602
        //    `target` has provenance valid for some Rust allocation, `A`.
603
        //    Because `ptr` is derived from `target` via provenance-preserving
604
        //    operations, `ptr` will also have provenance valid for its entire
605
        //    referent.
606
        // 1. `validate_cast_and_convert_metadata` promises that the object
607
        //    described by `elems` and `split_at` lives at a byte range which is
608
        //    a subset of the input byte range. Thus, by invariant, if
609
        //    `target`'s referent is not zero sized, then `target` refers to an
610
        //    allocation which is guaranteed to live for at least `'a`, and thus
611
        //    so does `ptr`.
612
0
        Ok((unsafe { PtrInner::new(ptr) }, remainder))
613
0
    }
614
}
615
616
#[cfg(test)]
617
mod tests {
618
    use super::*;
619
    use crate::*;
620
621
    #[test]
622
    fn test_meta() {
623
        let arr = [1; 16];
624
        let dst = <[u8]>::ref_from_bytes(&arr[..]).unwrap();
625
        let ptr = PtrInner::from_ref(dst);
626
        assert_eq!(ptr.meta().get(), 16);
627
628
        // SAFETY: 8 is less than 16
629
        let ptr = unsafe { ptr.with_meta(8) };
630
631
        assert_eq!(ptr.meta().get(), 8);
632
    }
633
634
    #[test]
635
    fn test_split_at() {
636
        fn test_split_at<const OFFSET: usize, const BUFFER_SIZE: usize>() {
637
            #[derive(FromBytes, KnownLayout, SplitAt, Immutable)]
638
            #[repr(C)]
639
            struct SliceDst<const OFFSET: usize> {
640
                prefix: [u8; OFFSET],
641
                trailing: [u8],
642
            }
643
644
            let n: usize = BUFFER_SIZE - OFFSET;
645
            let arr = [1; BUFFER_SIZE];
646
            let dst = SliceDst::<OFFSET>::ref_from_bytes(&arr[..]).unwrap();
647
            let ptr = PtrInner::from_ref(dst);
648
            for i in 0..=n {
649
                assert_eq!(ptr.meta().get(), n);
650
                // SAFETY: `i` is in bounds by construction.
651
                let i = unsafe { MetadataOf::new_unchecked(i) };
652
                // SAFETY: `i` is in bounds by construction.
653
                let (l, r) = unsafe { ptr.split_at_unchecked(i) };
654
                // SAFETY: Points to a valid value by construction.
655
                #[allow(clippy::undocumented_unsafe_blocks, clippy::as_conversions)]
656
                // Clippy false positive
657
                let l_sum: usize = l
658
                    .trailing_slice()
659
                    .iter()
660
                    .map(
661
                        #[inline(always)]
662
                        |ptr| unsafe { core::ptr::read_unaligned(ptr.as_ptr()) } as usize,
663
                    )
664
                    .sum();
665
                // SAFETY: Points to a valid value by construction.
666
                #[allow(clippy::undocumented_unsafe_blocks, clippy::as_conversions)]
667
                // Clippy false positive
668
                let r_sum: usize = r
669
                    .iter()
670
                    .map(
671
                        #[inline(always)]
672
                        |ptr| unsafe { core::ptr::read_unaligned(ptr.as_ptr()) } as usize,
673
                    )
674
                    .sum();
675
                assert_eq!(l_sum, i.get());
676
                assert_eq!(r_sum, n - i.get());
677
                assert_eq!(l_sum + r_sum, n);
678
            }
679
        }
680
681
        test_split_at::<0, 16>();
682
        test_split_at::<1, 17>();
683
        test_split_at::<2, 18>();
684
    }
685
686
    #[test]
687
    fn test_trailing_slice() {
688
        fn test_trailing_slice<const OFFSET: usize, const BUFFER_SIZE: usize>() {
689
            #[derive(FromBytes, KnownLayout, SplitAt, Immutable)]
690
            #[repr(C)]
691
            struct SliceDst<const OFFSET: usize> {
692
                prefix: [u8; OFFSET],
693
                trailing: [u8],
694
            }
695
696
            let n: usize = BUFFER_SIZE - OFFSET;
697
            let arr = [1; BUFFER_SIZE];
698
            let dst = SliceDst::<OFFSET>::ref_from_bytes(&arr[..]).unwrap();
699
            let ptr = PtrInner::from_ref(dst);
700
701
            assert_eq!(ptr.meta().get(), n);
702
            let trailing = ptr.trailing_slice();
703
            assert_eq!(trailing.meta().get(), n);
704
705
            assert_eq!(
706
                // SAFETY: We assume this to be sound for the sake of this test,
707
                // which will fail, here, in miri, if the safety precondition of
708
                // `offset_of` is not satisfied.
709
                unsafe {
710
                    #[allow(clippy::as_conversions)]
711
                    let offset = (trailing.as_ptr() as *mut u8).offset_from(ptr.as_ptr() as *mut _);
712
                    offset
713
                },
714
                isize::try_from(OFFSET).unwrap(),
715
            );
716
717
            // SAFETY: Points to a valid value by construction.
718
            #[allow(clippy::undocumented_unsafe_blocks, clippy::as_conversions)]
719
            // Clippy false positive
720
            let trailing: usize = trailing
721
                .iter()
722
                .map(|ptr| unsafe { core::ptr::read_unaligned(ptr.as_ptr()) } as usize)
723
                .sum();
724
725
            assert_eq!(trailing, n);
726
        }
727
728
        test_trailing_slice::<0, 16>();
729
        test_trailing_slice::<1, 17>();
730
        test_trailing_slice::<2, 18>();
731
    }
732
    #[test]
733
    fn test_ptr_inner_clone() {
734
        let mut x = 0u8;
735
        let p = PtrInner::from_mut(&mut x);
736
        #[allow(clippy::clone_on_copy)]
737
        let p2 = p.clone();
738
        assert_eq!(p.as_non_null(), p2.as_non_null());
739
    }
740
}