Coverage Report

Created: 2024-07-06 06:44

/rust/registry/src/index.crates.io-6f17d22bba15001f/zerocopy-0.7.35/src/macros.rs
Line
Count
Source (jump to first uncovered line)
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
/// Documents multiple unsafe blocks with a single safety comment.
10
///
11
/// Invoked as:
12
///
13
/// ```rust,ignore
14
/// safety_comment! {
15
///     // Non-doc comments come first.
16
///     /// SAFETY:
17
///     /// Safety comment starts on its own line.
18
///     macro_1!(args);
19
///     macro_2! { args };
20
///     /// SAFETY:
21
///     /// Subsequent safety comments are allowed but not required.
22
///     macro_3! { args };
23
/// }
24
/// ```
25
///
26
/// The macro invocations are emitted, each decorated with the following
27
/// attribute: `#[allow(clippy::undocumented_unsafe_blocks)]`.
28
macro_rules! safety_comment {
29
    (#[doc = r" SAFETY:"] $($(#[$attr:meta])* $macro:ident!$args:tt;)*) => {
30
        #[allow(clippy::undocumented_unsafe_blocks, unused_attributes)]
31
        const _: () = { $($(#[$attr])* $macro!$args;)* };
32
    }
33
}
34
35
/// Unsafely implements trait(s) for a type.
36
///
37
/// # Safety
38
///
39
/// The trait impl must be sound.
40
///
41
/// When implementing `TryFromBytes`:
42
/// - If no `is_bit_valid` impl is provided, then it must be valid for
43
///   `is_bit_valid` to unconditionally return `true`. In other words, it must
44
///   be the case that any initialized sequence of bytes constitutes a valid
45
///   instance of `$ty`.
46
/// - If an `is_bit_valid` impl is provided, then:
47
///   - Regardless of whether the provided closure takes a `Ptr<$repr>` or
48
///     `&$repr` argument, it must be the case that, given `t: *mut $ty` and
49
///     `let r = t as *mut $repr`, `r` refers to an object of equal or lesser
50
///     size than the object referred to by `t`.
51
///   - If the provided closure takes a `&$repr` argument, then given a `Ptr<'a,
52
///     $ty>` which satisfies the preconditions of
53
///     `TryFromBytes::<$ty>::is_bit_valid`, it must be guaranteed that the
54
///     memory referenced by that `Ptr` always contains a valid `$repr`.
55
///   - The alignment of `$repr` is less than or equal to the alignment of
56
///     `$ty`.
57
///   - The impl of `is_bit_valid` must only return `true` for its argument
58
///     `Ptr<$repr>` if the original `Ptr<$ty>` refers to a valid `$ty`.
59
macro_rules! unsafe_impl {
60
    // Implement `$trait` for `$ty` with no bounds.
61
    ($(#[$attr:meta])* $ty:ty: $trait:ident $(; |$candidate:ident: &$repr:ty| $is_bit_valid:expr)?) => {
62
        $(#[$attr])*
63
        unsafe impl $trait for $ty {
64
            unsafe_impl!(@method $trait $(; |$candidate: &$repr| $is_bit_valid)?);
65
        }
66
    };
67
    // Implement all `$traits` for `$ty` with no bounds.
68
    ($ty:ty: $($traits:ident),*) => {
69
        $( unsafe_impl!($ty: $traits); )*
70
    };
71
    // This arm is identical to the following one, except it contains a
72
    // preceding `const`. If we attempt to handle these with a single arm, there
73
    // is an inherent ambiguity between `const` (the keyword) and `const` (the
74
    // ident match for `$tyvar:ident`).
75
    //
76
    // To explain how this works, consider the following invocation:
77
    //
78
    //   unsafe_impl!(const N: usize, T: ?Sized + Copy => Clone for Foo<T>);
79
    //
80
    // In this invocation, here are the assignments to meta-variables:
81
    //
82
    //   |---------------|------------|
83
    //   | Meta-variable | Assignment |
84
    //   |---------------|------------|
85
    //   | $constname    |  N         |
86
    //   | $constty      |  usize     |
87
    //   | $tyvar        |  T         |
88
    //   | $optbound     |  Sized     |
89
    //   | $bound        |  Copy      |
90
    //   | $trait        |  Clone     |
91
    //   | $ty           |  Foo<T>    |
92
    //   |---------------|------------|
93
    //
94
    // The following arm has the same behavior with the exception of the lack of
95
    // support for a leading `const` parameter.
96
    (
97
        $(#[$attr:meta])*
98
        const $constname:ident : $constty:ident $(,)?
99
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
100
        => $trait:ident for $ty:ty $(; |$candidate:ident $(: &$ref_repr:ty)? $(: Ptr<$ptr_repr:ty>)?| $is_bit_valid:expr)?
101
    ) => {
102
        unsafe_impl!(
103
            @inner
104
            $(#[$attr])*
105
            @const $constname: $constty,
106
            $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
107
            => $trait for $ty $(; |$candidate $(: &$ref_repr)? $(: Ptr<$ptr_repr>)?| $is_bit_valid)?
108
        );
109
    };
110
    (
111
        $(#[$attr:meta])*
112
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
113
        => $trait:ident for $ty:ty $(; |$candidate:ident $(: &$ref_repr:ty)? $(: Ptr<$ptr_repr:ty>)?| $is_bit_valid:expr)?
114
    ) => {
115
        unsafe_impl!(
116
            @inner
117
            $(#[$attr])*
118
            $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
119
            => $trait for $ty $(; |$candidate $(: &$ref_repr)? $(: Ptr<$ptr_repr>)?| $is_bit_valid)?
120
        );
121
    };
122
    (
123
        @inner
124
        $(#[$attr:meta])*
125
        $(@const $constname:ident : $constty:ident,)*
126
        $($tyvar:ident $(: $(? $optbound:ident +)* + $($bound:ident +)* )?,)*
127
        => $trait:ident for $ty:ty $(; |$candidate:ident $(: &$ref_repr:ty)? $(: Ptr<$ptr_repr:ty>)?| $is_bit_valid:expr)?
128
    ) => {
129
        $(#[$attr])*
130
        unsafe impl<$(const $constname: $constty,)* $($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> $trait for $ty {
131
            unsafe_impl!(@method $trait $(; |$candidate: $(&$ref_repr)? $(Ptr<$ptr_repr>)?| $is_bit_valid)?);
132
        }
133
    };
134
135
    (@method TryFromBytes ; |$candidate:ident: &$repr:ty| $is_bit_valid:expr) => {
136
        #[inline]
137
0
        unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool {
138
0
            // SAFETY:
139
0
            // - The argument to `cast_unsized` is `|p| p as *mut _` as required
140
0
            //   by that method's safety precondition.
141
0
            // - The caller has promised that the cast results in an object of
142
0
            //   equal or lesser size.
143
0
            // - The caller has promised that `$repr`'s alignment is less than
144
0
            //   or equal to `Self`'s alignment.
145
0
            #[allow(clippy::as_conversions)]
146
0
            let candidate = unsafe { candidate.cast_unsized::<$repr, _>(|p| p as *mut _) };
Unexecuted instantiation: <bool as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <char as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <str as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<u8> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<i8> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<u16> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<i16> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<u32> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<i32> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<u64> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<i64> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<u128> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<i128> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<usize> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <core::num::nonzero::NonZero<isize> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
147
0
            // SAFETY:
148
0
            // - The caller has promised that the referenced memory region will
149
0
            //   contain a valid `$repr` for `'a`.
150
0
            // - The memory may not be referenced by any mutable references.
151
0
            //   This is a precondition of `is_bit_valid`.
152
0
            // - The memory may not be mutated even via `UnsafeCell`s. This is a
153
0
            //   precondition of `is_bit_valid`.
154
0
            // - There must not exist any references to the same memory region
155
0
            //   which contain `UnsafeCell`s at byte ranges which are not
156
0
            //   identical to the byte ranges at which `T` contains
157
0
            //   `UnsafeCell`s. This is a precondition of `is_bit_valid`.
158
0
            let $candidate: &$repr = unsafe { candidate.as_ref() };
159
0
            $is_bit_valid
160
0
        }
Unexecuted instantiation: <bool as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <char as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <str as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<u8> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<i8> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<u16> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<i16> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<u32> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<i32> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<u64> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<i64> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<u128> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<i128> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<usize> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::num::nonzero::NonZero<isize> as zerocopy::TryFromBytes>::is_bit_valid
161
    };
162
    (@method TryFromBytes ; |$candidate:ident: Ptr<$repr:ty>| $is_bit_valid:expr) => {
163
        #[inline]
164
0
        unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool {
165
0
            // SAFETY:
166
0
            // - The argument to `cast_unsized` is `|p| p as *mut _` as required
167
0
            //   by that method's safety precondition.
168
0
            // - The caller has promised that the cast results in an object of
169
0
            //   equal or lesser size.
170
0
            // - The caller has promised that `$repr`'s alignment is less than
171
0
            //   or equal to `Self`'s alignment.
172
0
            #[allow(clippy::as_conversions)]
173
0
            let $candidate = unsafe { candidate.cast_unsized::<$repr, _>(|p| p as *mut _) };
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
Unexecuted instantiation: <[_] as zerocopy::TryFromBytes>::is_bit_valid::{closure#0}
174
0
            $is_bit_valid
175
0
        }
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <[_] as zerocopy::TryFromBytes>::is_bit_valid
176
    };
177
0
    (@method TryFromBytes) => { #[inline(always)] unsafe fn is_bit_valid(_: Ptr<'_, Self>) -> bool { true } };
Unexecuted instantiation: <() as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <u8 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <i8 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <u16 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <i16 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <u32 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <i32 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <u64 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <i64 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <u128 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <i128 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <usize as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <isize as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <f32 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <f64 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u8>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i8>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u16>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i16>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u32>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i32>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u64>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i64>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u128>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i128>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<usize>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<isize>> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::mem::maybe_uninit::MaybeUninit<_> as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::core_arch::x86::__m128 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::core_arch::x86::__m128d as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::core_arch::x86::__m128i as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::core_arch::x86::__m256 as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::core_arch::x86::__m256d as zerocopy::TryFromBytes>::is_bit_valid
Unexecuted instantiation: <core::core_arch::x86::__m256i as zerocopy::TryFromBytes>::is_bit_valid
178
    (@method $trait:ident) => {
179
        #[allow(clippy::missing_inline_in_public_items)]
180
0
        fn only_derive_is_allowed_to_implement_this_trait() {}
Unexecuted instantiation: <() as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <() as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <() as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <() as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u8 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u8 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u8 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u8 as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i8 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i8 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i8 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i8 as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u16 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u16 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u16 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i16 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i16 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i16 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u32 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u32 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u32 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i32 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i32 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i32 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u64 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u64 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u64 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i64 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i64 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i64 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u128 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u128 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u128 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i128 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i128 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i128 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <usize as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <usize as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <usize as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <isize as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <isize as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <isize as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f32 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f32 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f32 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f64 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f64 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f64 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <bool as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <bool as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <bool as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <char as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <char as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <str as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <str as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <str as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u8> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u8> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i8> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i8> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u16> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i16> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u32> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i32> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u64> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i64> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u128> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i128> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<usize> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<isize> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u8>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u8>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u8>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u8>> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i8>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i8>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i8>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i8>> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u16>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u16>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u16>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i16>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i16>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i16>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u32>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u32>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u32>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i32>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i32>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i32>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u64>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u64>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u64>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i64>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i64>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i64>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u128>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u128>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u128>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i128>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i128>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<i128>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<usize>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<usize>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<usize>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<isize>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<isize>> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<isize>> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128d as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128d as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128d as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128i as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128i as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128i as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256 as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256 as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256 as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256d as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256d as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256d as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256i as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256i as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256i as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <zerocopy::wrappers::Unalign<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <zerocopy::wrappers::Unalign<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <zerocopy::wrappers::Unalign<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <zerocopy::wrappers::Unalign<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<&_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<&mut _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<core::ptr::non_null::NonNull<_>> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::maybe_uninit::MaybeUninit<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::maybe_uninit::MaybeUninit<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::maybe_uninit::MaybeUninit<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::manually_drop::ManuallyDrop<_> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::manually_drop::ManuallyDrop<_> as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::manually_drop::ManuallyDrop<_> as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::manually_drop::ManuallyDrop<_> as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_; _] as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_; _] as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_; _] as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_; _] as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_] as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_] as zerocopy::FromBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_] as zerocopy::AsBytes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_] as zerocopy::Unaligned>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <*const _ as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <*mut _ as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
181
    };
182
    (@method $trait:ident; |$_candidate:ident $(: &$_ref_repr:ty)? $(: NonNull<$_ptr_repr:ty>)?| $_is_bit_valid:expr) => {
183
        compile_error!("Can't provide `is_bit_valid` impl for trait other than `TryFromBytes`");
184
    };
185
}
186
187
/// Implements a trait for a type, bounding on each memeber of the power set of
188
/// a set of type variables. This is useful for implementing traits for tuples
189
/// or `fn` types.
190
///
191
/// The last argument is the name of a macro which will be called in every
192
/// `impl` block, and is expected to expand to the name of the type for which to
193
/// implement the trait.
194
///
195
/// For example, the invocation:
196
/// ```ignore
197
/// unsafe_impl_for_power_set!(A, B => Foo for type!(...))
198
/// ```
199
/// ...expands to:
200
/// ```ignore
201
/// unsafe impl       Foo for type!()     { ... }
202
/// unsafe impl<B>    Foo for type!(B)    { ... }
203
/// unsafe impl<A, B> Foo for type!(A, B) { ... }
204
/// ```
205
macro_rules! unsafe_impl_for_power_set {
206
    ($first:ident $(, $rest:ident)* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)) => {
207
        unsafe_impl_for_power_set!($($rest),* $(-> $ret)? => $trait for $macro!(...));
208
        unsafe_impl_for_power_set!(@impl $first $(, $rest)* $(-> $ret)? => $trait for $macro!(...));
209
    };
210
    ($(-> $ret:ident)? => $trait:ident for $macro:ident!(...)) => {
211
        unsafe_impl_for_power_set!(@impl $(-> $ret)? => $trait for $macro!(...));
212
    };
213
    (@impl $($vars:ident),* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)) => {
214
        unsafe impl<$($vars,)* $($ret)?> $trait for $macro!($($vars),* $(-> $ret)?) {
215
            #[allow(clippy::missing_inline_in_public_items)]
216
0
            fn only_derive_is_allowed_to_implement_this_trait() {}
Unexecuted instantiation: <core::option::Option<fn() -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<fn(_, _, _, _, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn() -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<extern "C" fn(_, _, _, _, _, _, _, _, _, _, _, _) -> _> as zerocopy::FromZeroes>::only_derive_is_allowed_to_implement_this_trait
217
        }
218
    };
219
}
220
221
/// Expands to an `Option<extern "C" fn>` type with the given argument types and
222
/// return type. Designed for use with `unsafe_impl_for_power_set`.
223
macro_rules! opt_extern_c_fn {
224
    ($($args:ident),* -> $ret:ident) => { Option<extern "C" fn($($args),*) -> $ret> };
225
}
226
227
/// Expands to a `Option<fn>` type with the given argument types and return
228
/// type. Designed for use with `unsafe_impl_for_power_set`.
229
macro_rules! opt_fn {
230
    ($($args:ident),* -> $ret:ident) => { Option<fn($($args),*) -> $ret> };
231
}
232
233
/// Implements trait(s) for a type or verifies the given implementation by
234
/// referencing an existing (derived) implementation.
235
///
236
/// This macro exists so that we can provide zerocopy-derive as an optional
237
/// dependency and still get the benefit of using its derives to validate that
238
/// our trait impls are sound.
239
///
240
/// When compiling without `--cfg 'feature = "derive"` and without `--cfg test`,
241
/// `impl_or_verify!` emits the provided trait impl. When compiling with either
242
/// of those cfgs, it is expected that the type in question is deriving the
243
/// traits instead. In this case, `impl_or_verify!` emits code which validates
244
/// that the given trait impl is at least as restrictive as the the impl emitted
245
/// by the custom derive. This has the effect of confirming that the impl which
246
/// is emitted when the `derive` feature is disabled is actually sound (on the
247
/// assumption that the impl emitted by the custom derive is sound).
248
///
249
/// The caller is still required to provide a safety comment (e.g. using the
250
/// `safety_comment!` macro) . The reason for this restriction is that, while
251
/// `impl_or_verify!` can guarantee that the provided impl is sound when it is
252
/// compiled with the appropriate cfgs, there is no way to guarantee that it is
253
/// ever compiled with those cfgs. In particular, it would be possible to
254
/// accidentally place an `impl_or_verify!` call in a context that is only ever
255
/// compiled when the `derive` feature is disabled. If that were to happen,
256
/// there would be nothing to prevent an unsound trait impl from being emitted.
257
/// Requiring a safety comment reduces the likelihood of emitting an unsound
258
/// impl in this case, and also provides useful documentation for readers of the
259
/// code.
260
///
261
/// ## Example
262
///
263
/// ```rust,ignore
264
/// // Note that these derives are gated by `feature = "derive"`
265
/// #[cfg_attr(any(feature = "derive", test), derive(FromZeroes, FromBytes, AsBytes, Unaligned))]
266
/// #[repr(transparent)]
267
/// struct Wrapper<T>(T);
268
///
269
/// safety_comment! {
270
///     /// SAFETY:
271
///     /// `Wrapper<T>` is `repr(transparent)`, so it is sound to implement any
272
///     /// zerocopy trait if `T` implements that trait.
273
///     impl_or_verify!(T: FromZeroes => FromZeroes for Wrapper<T>);
274
///     impl_or_verify!(T: FromBytes => FromBytes for Wrapper<T>);
275
///     impl_or_verify!(T: AsBytes => AsBytes for Wrapper<T>);
276
///     impl_or_verify!(T: Unaligned => Unaligned for Wrapper<T>);
277
/// }
278
/// ```
279
macro_rules! impl_or_verify {
280
    // The following two match arms follow the same pattern as their
281
    // counterparts in `unsafe_impl!`; see the documentation on those arms for
282
    // more details.
283
    (
284
        const $constname:ident : $constty:ident $(,)?
285
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
286
        => $trait:ident for $ty:ty
287
    ) => {
288
        impl_or_verify!(@impl { unsafe_impl!(
289
            const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
290
        ); });
291
        impl_or_verify!(@verify $trait, {
292
            impl<const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
293
        });
294
    };
295
    (
296
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
297
        => $trait:ident for $ty:ty
298
    ) => {
299
        impl_or_verify!(@impl { unsafe_impl!(
300
            $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
301
        ); });
302
        impl_or_verify!(@verify $trait, {
303
            impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
304
        });
305
    };
306
    (
307
        $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
308
        => $trait:ident for $ty:ty
309
    ) => {
310
        unsafe_impl!(
311
            @inner
312
            $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
313
            => $trait for $ty
314
        );
315
    };
316
    (@impl $impl_block:tt) => {
317
        #[cfg(not(any(feature = "derive", test)))]
318
        const _: () = { $impl_block };
319
    };
320
    (@verify $trait:ident, $impl_block:tt) => {
321
        #[cfg(any(feature = "derive", test))]
322
        const _: () = {
323
            trait Subtrait: $trait {}
324
            $impl_block
325
        };
326
    };
327
}
328
329
/// Implements `KnownLayout` for a sized type.
330
macro_rules! impl_known_layout {
331
    ($(const $constvar:ident : $constty:ty, $tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
332
        $(impl_known_layout!(@inner const $constvar: $constty, $tyvar $(: ?$optbound)? => $ty);)*
333
    };
334
    ($($tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
335
        $(impl_known_layout!(@inner , $tyvar $(: ?$optbound)? => $ty);)*
336
    };
337
    ($($ty:ty),*) => { $(impl_known_layout!(@inner , => $ty);)* };
338
    (@inner $(const $constvar:ident : $constty:ty)? , $($tyvar:ident $(: ?$optbound:ident)?)? => $ty:ty) => {
339
        const _: () = {
340
            use core::ptr::NonNull;
341
342
            // SAFETY: Delegates safety to `DstLayout::for_type`.
343
            unsafe impl<$(const $constvar : $constty,)? $($tyvar $(: ?$optbound)?)?> KnownLayout for $ty {
344
                #[allow(clippy::missing_inline_in_public_items)]
345
0
                fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized {}
Unexecuted instantiation: <() as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u8 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i8 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u16 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i16 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u32 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i32 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u64 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i64 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <u128 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <i128 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <usize as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <isize as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f32 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <f64 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <bool as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <char as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u8> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i8> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u16> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i16> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u32> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i32> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u64> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i64> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<u128> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<i128> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<usize> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::nonzero::NonZero<isize> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128d as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m128i as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256 as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256d as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::core_arch::x86::__m256i as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <zerocopy::wrappers::Unalign<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::option::Option<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::maybe_uninit::MaybeUninit<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <*const _ as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <*mut _ as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <[_; _] as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
346
347
                const LAYOUT: DstLayout = DstLayout::for_type::<$ty>();
348
349
                // SAFETY: `.cast` preserves address and provenance.
350
                //
351
                // TODO(#429): Add documentation to `.cast` that promises that
352
                // it preserves provenance.
353
                #[inline(always)]
354
0
                fn raw_from_ptr_len(bytes: NonNull<u8>, _elems: usize) -> NonNull<Self> {
355
0
                    bytes.cast::<Self>()
356
0
                }
Unexecuted instantiation: <zerocopy::wrappers::Unalign<_> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <() as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <u8 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <i8 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <u16 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <i16 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <u32 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <i32 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <u64 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <i64 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <u128 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <i128 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <usize as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <isize as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <f32 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <f64 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <bool as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <char as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<u8> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<i8> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<u16> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<i16> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<u32> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<i32> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<u64> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<i64> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<u128> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<i128> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<usize> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::nonzero::NonZero<isize> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::option::Option<_> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::marker::PhantomData<_> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::num::wrapping::Wrapping<_> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::mem::maybe_uninit::MaybeUninit<_> as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <*const _ as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <*mut _ as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <[_; _] as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::core_arch::x86::__m128 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::core_arch::x86::__m128d as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::core_arch::x86::__m128i as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::core_arch::x86::__m256 as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::core_arch::x86::__m256d as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::core_arch::x86::__m256i as zerocopy::KnownLayout>::raw_from_ptr_len
357
            }
358
        };
359
    };
360
}
361
362
/// Implements `KnownLayout` for a type in terms of the implementation of
363
/// another type with the same representation.
364
///
365
/// # Safety
366
///
367
/// - `$ty` and `$repr` must have the same:
368
///   - Fixed prefix size
369
///   - Alignment
370
///   - (For DSTs) trailing slice element size
371
/// - It must be valid to perform an `as` cast from `*mut $repr` to `*mut $ty`,
372
///   and this operation must preserve referent size (ie, `size_of_val_raw`).
373
macro_rules! unsafe_impl_known_layout {
374
    ($($tyvar:ident: ?Sized + KnownLayout =>)? #[repr($repr:ty)] $ty:ty) => {
375
        const _: () = {
376
            use core::ptr::NonNull;
377
378
            unsafe impl<$($tyvar: ?Sized + KnownLayout)?> KnownLayout for $ty {
379
                #[allow(clippy::missing_inline_in_public_items)]
380
0
                fn only_derive_is_allowed_to_implement_this_trait() {}
Unexecuted instantiation: <str as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
Unexecuted instantiation: <core::mem::manually_drop::ManuallyDrop<_> as zerocopy::KnownLayout>::only_derive_is_allowed_to_implement_this_trait
381
382
                const LAYOUT: DstLayout = <$repr as KnownLayout>::LAYOUT;
383
384
                // SAFETY: All operations preserve address and provenance.
385
                // Caller has promised that the `as` cast preserves size.
386
                //
387
                // TODO(#429): Add documentation to `NonNull::new_unchecked`
388
                // that it preserves provenance.
389
                #[inline(always)]
390
0
                fn raw_from_ptr_len(bytes: NonNull<u8>, elems: usize) -> NonNull<Self> {
391
0
                    #[allow(clippy::as_conversions)]
392
0
                    let ptr = <$repr>::raw_from_ptr_len(bytes, elems).as_ptr() as *mut Self;
393
0
                    // SAFETY: `ptr` was converted from `bytes`, which is non-null.
394
0
                    unsafe { NonNull::new_unchecked(ptr) }
395
0
                }
Unexecuted instantiation: <str as zerocopy::KnownLayout>::raw_from_ptr_len
Unexecuted instantiation: <core::mem::manually_drop::ManuallyDrop<_> as zerocopy::KnownLayout>::raw_from_ptr_len
396
            }
397
        };
398
    };
399
}
400
401
/// Uses `align_of` to confirm that a type or set of types have alignment 1.
402
///
403
/// Note that `align_of<T>` requires `T: Sized`, so this macro doesn't work for
404
/// unsized types.
405
macro_rules! assert_unaligned {
406
    ($ty:ty) => {
407
        // We only compile this assertion under `cfg(test)` to avoid taking an
408
        // extra non-dev dependency (and making this crate more expensive to
409
        // compile for our dependents).
410
        #[cfg(test)]
411
        static_assertions::const_assert_eq!(core::mem::align_of::<$ty>(), 1);
412
    };
413
    ($($ty:ty),*) => {
414
        $(assert_unaligned!($ty);)*
415
    };
416
}