Coverage Report

Created: 2026-01-17 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.33/src/pointer/mod.rs
Line
Count
Source
1
// Copyright 2023 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
//! Abstractions over raw pointers.
10
11
mod inner;
12
#[doc(hidden)]
13
pub mod invariant;
14
mod ptr;
15
mod transmute;
16
17
#[doc(hidden)]
18
pub use {inner::PtrInner, transmute::*};
19
#[doc(hidden)]
20
pub use {
21
    invariant::{BecauseExclusive, BecauseImmutable, Read},
22
    ptr::Ptr,
23
};
24
25
/// A shorthand for a maybe-valid, maybe-aligned reference. Used as the argument
26
/// to [`TryFromBytes::is_bit_valid`].
27
///
28
/// [`TryFromBytes::is_bit_valid`]: crate::TryFromBytes::is_bit_valid
29
pub type Maybe<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Unaligned> =
30
    Ptr<'a, T, (Aliasing, Alignment, invariant::Initialized)>;
31
32
/// Checks if the referent is zeroed.
33
0
pub(crate) fn is_zeroed<T, I>(ptr: Ptr<'_, T, I>) -> bool
34
0
where
35
0
    T: crate::Immutable + crate::KnownLayout,
36
0
    I: invariant::Invariants<Validity = invariant::Initialized>,
37
0
    I::Aliasing: invariant::Reference,
38
{
39
0
    ptr.as_bytes::<BecauseImmutable>().as_ref().iter().all(|&byte| byte == 0)
40
0
}
41
42
#[doc(hidden)]
43
pub mod cast {
44
    use core::{marker::PhantomData, mem};
45
46
    use crate::{
47
        layout::{SizeInfo, TrailingSliceLayout},
48
        HasField, KnownLayout, PtrInner,
49
    };
50
51
    /// A pointer cast or projection.
52
    ///
53
    /// # Safety
54
    ///
55
    /// The implementation of `project` must satisfy its safety post-condition.
56
    pub unsafe trait Project<Src: ?Sized, Dst: ?Sized> {
57
        /// Projects a pointer from `Src` to `Dst`.
58
        ///
59
        /// # Safety
60
        ///
61
        /// The returned pointer refers to a non-strict subset of the bytes of
62
        /// `src`'s referent, and has the same provenance as `src`.
63
        fn project(src: PtrInner<'_, Src>) -> *mut Dst;
64
    }
65
66
    /// A [`Project`] which preserves the address of the referent – a pointer
67
    /// cast.
68
    ///
69
    /// # Safety
70
    ///
71
    /// A `Cast` projection must preserve the address of the referent. It may
72
    /// shrink the set of referent bytes, and it may change the referent's type.
73
    pub unsafe trait Cast<Src: ?Sized, Dst: ?Sized>: Project<Src, Dst> {}
74
75
    /// A no-op pointer cast.
76
    #[derive(Default, Copy, Clone)]
77
    #[allow(missing_debug_implementations)]
78
    pub struct IdCast;
79
80
    // SAFETY: `project` returns its argument unchanged, and so it is a
81
    // provenance-preserving projection which preserves the set of referent
82
    // bytes.
83
    unsafe impl<T: ?Sized> Project<T, T> for IdCast {
84
        #[inline(always)]
85
565k
        fn project(src: PtrInner<'_, T>) -> *mut T {
86
565k
            src.as_ptr()
87
565k
        }
<zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>>>::project
Line
Count
Source
85
141k
        fn project(src: PtrInner<'_, T>) -> *mut T {
86
141k
            src.as_ptr()
87
141k
        }
<zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>>>::project
Line
Count
Source
85
141k
        fn project(src: PtrInner<'_, T>) -> *mut T {
86
141k
            src.as_ptr()
87
141k
        }
<zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>>>::project
Line
Count
Source
85
141k
        fn project(src: PtrInner<'_, T>) -> *mut T {
86
141k
            src.as_ptr()
87
141k
        }
<zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>>>::project
Line
Count
Source
85
141k
        fn project(src: PtrInner<'_, T>) -> *mut T {
86
141k
            src.as_ptr()
87
141k
        }
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<_, _>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::IdCast as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>>>::project
88
    }
89
90
    // SAFETY: The `Project::project` impl preserves referent address.
91
    unsafe impl<T: ?Sized> Cast<T, T> for IdCast {}
92
93
    /// A pointer cast which preserves or shrinks the set of referent bytes of
94
    /// a statically-sized referent.
95
    ///
96
    /// # Safety
97
    ///
98
    /// The implementation of [`Project`] uses a compile-time assertion to
99
    /// guarantee that `Dst` is no larger than `Src`. Thus, `CastSized` has a
100
    /// sound implementation of [`Project`] for all `Src` and `Dst` – the caller
101
    /// may pass any `Src` and `Dst` without being responsible for soundness.
102
    #[allow(missing_debug_implementations, missing_copy_implementations)]
103
    pub enum CastSized {}
104
105
    // SAFETY: By the `static_assert!`, `Dst` is no larger than `Src`,
106
    // and so all casts preserve or shrink the set of referent bytes. All
107
    // operations preserve provenance.
108
    unsafe impl<Src, Dst> Project<Src, Dst> for CastSized {
109
        #[inline(always)]
110
0
        fn project(src: PtrInner<'_, Src>) -> *mut Dst {
111
0
            static_assert!(Src, Dst => mem::size_of::<Src>() >= mem::size_of::<Dst>());
112
0
            src.as_ptr().cast::<Dst>()
113
0
        }
114
    }
115
116
    // SAFETY: The `Project::project` impl preserves referent address.
117
    unsafe impl<Src, Dst> Cast<Src, Dst> for CastSized {}
118
119
    /// A pointer cast which preserves or shrinks the set of referent bytes of
120
    /// a dynamically-sized referent.
121
    ///
122
    /// # Safety
123
    ///
124
    /// The implementation of [`Project`] uses a compile-time assertion to
125
    /// guarantee that the cast preserves the set of referent bytes. Thus,
126
    /// `CastUnsized` has a sound implementation of [`Project`] for all `Src`
127
    /// and `Dst` – the caller may pass any `Src` and `Dst` without being
128
    /// responsible for soundness.
129
    #[allow(missing_debug_implementations, missing_copy_implementations)]
130
    pub enum CastUnsized {}
131
132
    // SAFETY: The `static_assert!` ensures that `Src` and `Dst` have the same
133
    // `SizeInfo`. Thus, casting preserves the set of referent bytes. All
134
    // operations are provenance-preserving.
135
    unsafe impl<Src, Dst> Project<Src, Dst> for CastUnsized
136
    where
137
        Src: ?Sized + KnownLayout,
138
        Dst: ?Sized + KnownLayout<PointerMetadata = Src::PointerMetadata>,
139
    {
140
        #[inline(always)]
141
0
        fn project(src: PtrInner<'_, Src>) -> *mut Dst {
142
            // FIXME:
143
            // - Is the alignment check necessary for soundness? It's not
144
            //   necessary for the soundness of the `Project` impl, but what
145
            //   about the soundness of particular use sites?
146
            // - Do we want this to support shrinking casts as well?
147
0
            static_assert!(Src: ?Sized + KnownLayout, Dst: ?Sized + KnownLayout => {
148
                let t = <Src as KnownLayout>::LAYOUT;
149
                let u = <Dst as KnownLayout>::LAYOUT;
150
                t.align.get() >= u.align.get() && match (t.size_info, u.size_info) {
151
                    (SizeInfo::Sized { size: t }, SizeInfo::Sized { size: u }) => t == u,
152
                    (
153
                        SizeInfo::SliceDst(TrailingSliceLayout { offset: t_offset, elem_size: t_elem_size }),
154
                        SizeInfo::SliceDst(TrailingSliceLayout { offset: u_offset, elem_size: u_elem_size })
155
                    ) => t_offset == u_offset && t_elem_size == u_elem_size,
156
                    _ => false,
157
                }
158
            });
159
160
0
            let metadata = Src::pointer_to_metadata(src.as_ptr());
161
0
            Dst::raw_from_ptr_len(src.as_non_null().cast::<u8>(), metadata).as_ptr()
162
0
        }
163
    }
164
165
    // SAFETY: The `Project::project` impl preserves referent address.
166
    unsafe impl<Src, Dst> Cast<Src, Dst> for CastUnsized
167
    where
168
        Src: ?Sized + KnownLayout,
169
        Dst: ?Sized + KnownLayout<PointerMetadata = Src::PointerMetadata>,
170
    {
171
    }
172
173
    /// A field projection
174
    ///
175
    /// A `Projection` is a [`Project`] which implements projection by
176
    /// delegating to an implementation of [`HasField::project`].
177
    #[allow(missing_debug_implementations, missing_copy_implementations)]
178
    pub struct Projection<F: ?Sized, const VARIANT_ID: i128, const FIELD_ID: i128> {
179
        _never: core::convert::Infallible,
180
        _phantom: PhantomData<F>,
181
    }
182
183
    // SAFETY: `HasField::project` has the same safety post-conditions as
184
    // `Project::project`.
185
    unsafe impl<T: ?Sized, F, const VARIANT_ID: i128, const FIELD_ID: i128> Project<T, T::Type>
186
        for Projection<F, VARIANT_ID, FIELD_ID>
187
    where
188
        T: HasField<F, VARIANT_ID, FIELD_ID>,
189
    {
190
        #[inline(always)]
191
0
        fn project(src: PtrInner<'_, T>) -> *mut T::Type {
192
0
            T::project(src)
193
0
        }
194
    }
195
196
    /// A transitive sequence of projections.
197
    ///
198
    /// Given `TU: Project` and `UV: Project`, `TransitiveProject<_, TU, UV>` is
199
    /// a [`Project`] which projects by applying `TU` followed by `UV`.
200
    ///
201
    /// If `TU: Cast` and `UV: Cast`, then `TransitiveProject<_, TU, UV>: Cast`.
202
    #[allow(missing_debug_implementations)]
203
    pub struct TransitiveProject<U: ?Sized, TU, UV> {
204
        _never: core::convert::Infallible,
205
        _projections: PhantomData<(TU, UV)>,
206
        // On our MSRV (1.56), the debuginfo for a tuple containing both an
207
        // uninhabited type and a DST causes an ICE. We split `U` from `TU` and
208
        // `UV` to avoid this situation.
209
        _u: PhantomData<U>,
210
    }
211
212
    // SAFETY: Since `TU::project` and `UV::project` are each
213
    // provenance-preserving operations which preserve or shrink the set of
214
    // referent bytes, so is their composition.
215
    unsafe impl<T, U, V, TU, UV> Project<T, V> for TransitiveProject<U, TU, UV>
216
    where
217
        T: ?Sized,
218
        U: ?Sized,
219
        V: ?Sized,
220
        TU: Project<T, U>,
221
        UV: Project<U, V>,
222
    {
223
        #[inline(always)]
224
565k
        fn project(t: PtrInner<'_, T>) -> *mut V {
225
565k
            t.project::<_, TU>().project::<_, UV>().as_ptr()
226
565k
        }
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, [u16]>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, [u16]>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[u16], zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::DstCast> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[u16], zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::DstCast> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>>>::project
<zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, [u16]>>::project
Line
Count
Source
224
141k
        fn project(t: PtrInner<'_, T>) -> *mut V {
225
141k
            t.project::<_, TU>().project::<_, UV>().as_ptr()
226
141k
        }
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, [u16]>>::project
<zerocopy::pointer::cast::TransitiveProject<[u16], zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::DstCast> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>>>::project
Line
Count
Source
224
141k
        fn project(t: PtrInner<'_, T>) -> *mut V {
225
141k
            t.project::<_, TU>().project::<_, UV>().as_ptr()
226
141k
        }
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[u16], zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::DstCast> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>>>::project
<zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, [u16]>>::project
Line
Count
Source
224
141k
        fn project(t: PtrInner<'_, T>) -> *mut V {
225
141k
            t.project::<_, TU>().project::<_, UV>().as_ptr()
226
141k
        }
<zerocopy::pointer::cast::TransitiveProject<[u16], zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::DstCast> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&mut _, &mut _> as zerocopy::util::macro_util::TransmuteMutDst>::transmute_mut::D<[u16]>>>::project
Line
Count
Source
224
141k
        fn project(t: PtrInner<'_, T>) -> *mut V {
225
141k
            t.project::<_, TU>().project::<_, UV>().as_ptr()
226
141k
        }
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<_, _, _> as zerocopy::pointer::cast::Project<_, _>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, [u16]>>::project
Unexecuted instantiation: <zerocopy::pointer::cast::TransitiveProject<[u16], zerocopy::pointer::cast::TransitiveProject<[half::binary16::f16], <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::SrcCast, zerocopy::layout::cast_from::CastFrom<[u16]>>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::DstCast> as zerocopy::pointer::cast::Project<<zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::S<[half::binary16::f16]>, <zerocopy::util::macro_util::Wrap<&_, &_> as zerocopy::util::macro_util::TransmuteRefDst>::transmute_ref::D<[u16]>>>::project
227
    }
228
229
    // SAFETY: Since the `Project::project` impl delegates to `TU::project` and
230
    // `UV::project`, and since `TU` and `UV` are `Cast`, the `Project::project`
231
    // impl preserves the address of the referent.
232
    unsafe impl<T, U, V, TU, UV> Cast<T, V> for TransitiveProject<U, TU, UV>
233
    where
234
        T: ?Sized,
235
        U: ?Sized,
236
        V: ?Sized,
237
        TU: Cast<T, U>,
238
        UV: Cast<U, V>,
239
    {
240
    }
241
242
    /// A cast from `T` to `[u8]`.
243
    pub(crate) struct AsBytesCast;
244
245
    // SAFETY: `project` constructs a pointer with the same address as `src`
246
    // and with a referent of the same size as `*src`. It does this using
247
    // provenance-preserving operations.
248
    //
249
    // FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/594):
250
    // Technically, this proof assumes that `*src` is contiguous (the same is
251
    // true of other proofs in this codebase). Is this guaranteed anywhere?
252
    unsafe impl<T: ?Sized + KnownLayout> Project<T, [u8]> for AsBytesCast {
253
        #[inline(always)]
254
0
        fn project(src: PtrInner<'_, T>) -> *mut [u8] {
255
0
            let bytes = match T::size_of_val_raw(src.as_non_null()) {
256
0
                Some(bytes) => bytes,
257
                // SAFETY: `KnownLayout::size_of_val_raw` promises to always
258
                // return `Some` so long as the resulting size fits in a
259
                // `usize`. By invariant on `PtrInner`, `src` refers to a range
260
                // of bytes whose size fits in an `isize`, which implies that it
261
                // also fits in a `usize`.
262
0
                None => unsafe { core::hint::unreachable_unchecked() },
263
            };
264
265
0
            core::ptr::slice_from_raw_parts_mut(src.as_ptr().cast::<u8>(), bytes)
266
0
        }
267
    }
268
269
    // SAFETY: The `Project::project` impl preserves referent address.
270
    unsafe impl<T: ?Sized + KnownLayout> Cast<T, [u8]> for AsBytesCast {}
271
}