xref: /linux/rust/zerocopy/src/util/macros.rs (revision 056a5087d87ead77dedbe9cf5bde53b7cd4b4651)
1 // SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
2 
3 // Copyright 2023 The Fuchsia Authors
4 //
5 // Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
6 // <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
7 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
8 // This file may not be copied, modified, or distributed except according to
9 // those terms.
10 
11 /// Unsafely implements trait(s) for a type.
12 ///
13 /// # Safety
14 ///
15 /// The trait impl must be sound.
16 ///
17 /// When implementing `TryFromBytes`:
18 /// - If no `is_bit_valid` impl is provided, then it must be valid for
19 ///   `is_bit_valid` to unconditionally return `true`. In other words, it must
20 ///   be the case that any initialized sequence of bytes constitutes a valid
21 ///   instance of `$ty`.
22 /// - If an `is_bit_valid` impl is provided, then the impl of `is_bit_valid`
23 ///   must only return `true` if its argument refers to a valid `$ty`.
24 macro_rules! unsafe_impl {
25     // Implement `$trait` for `$ty` with no bounds.
26     ($(#[$attr:meta])* $ty:ty: $trait:ident $(; |$candidate:ident| $is_bit_valid:expr)?) => {{
27         crate::util::macros::__unsafe();
28 
29         $(#[$attr])*
30         // SAFETY: The caller promises that this is sound.
31         unsafe impl $trait for $ty {
32             unsafe_impl!(@method $trait $(; |$candidate| $is_bit_valid)?);
33         }
34     }};
35 
36     // Implement all `$traits` for `$ty` with no bounds.
37     //
38     // The 2 arms under this one are there so we can apply
39     // N attributes for each one of M trait implementations.
40     // The simple solution of:
41     //
42     // ($(#[$attrs:meta])* $ty:ty: $($traits:ident),*) => {
43     //     $( unsafe_impl!( $(#[$attrs])* $ty: $traits ) );*
44     // }
45     //
46     // Won't work. The macro processor sees that the outer repetition
47     // contains both $attrs and $traits and expects them to match the same
48     // amount of fragments.
49     //
50     // To solve this we must:
51     // 1. Pack the attributes into a single token tree fragment we can match over.
52     // 2. Expand the traits.
53     // 3. Unpack and expand the attributes.
54     ($(#[$attrs:meta])* $ty:ty: $($traits:ident),*) => {
55         unsafe_impl!(@impl_traits_with_packed_attrs { $(#[$attrs])* } $ty: $($traits),*)
56     };
57 
58     (@impl_traits_with_packed_attrs $attrs:tt $ty:ty: $($traits:ident),*) => {{
59         $( unsafe_impl!(@unpack_attrs $attrs $ty: $traits); )*
60     }};
61 
62     (@unpack_attrs { $(#[$attrs:meta])* } $ty:ty: $traits:ident) => {
63         unsafe_impl!($(#[$attrs])* $ty: $traits);
64     };
65 
66     // This arm is identical to the following one, except it contains a
67     // preceding `const`. If we attempt to handle these with a single arm, there
68     // is an inherent ambiguity between `const` (the keyword) and `const` (the
69     // ident match for `$tyvar:ident`).
70     //
71     // To explain how this works, consider the following invocation:
72     //
73     //   unsafe_impl!(const N: usize, T: ?Sized + Copy => Clone for Foo<T>);
74     //
75     // In this invocation, here are the assignments to meta-variables:
76     //
77     //   |---------------|------------|
78     //   | Meta-variable | Assignment |
79     //   |---------------|------------|
80     //   | $constname    |  N         |
81     //   | $constty      |  usize     |
82     //   | $tyvar        |  T         |
83     //   | $optbound     |  Sized     |
84     //   | $bound        |  Copy      |
85     //   | $trait        |  Clone     |
86     //   | $ty           |  Foo<T>    |
87     //   |---------------|------------|
88     //
89     // The following arm has the same behavior with the exception of the lack of
90     // support for a leading `const` parameter.
91     (
92         $(#[$attr:meta])*
93         const $constname:ident : $constty:ident $(,)?
94         $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
95         => $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
96     ) => {
97         unsafe_impl!(
98             @inner
99             $(#[$attr])*
100             @const $constname: $constty,
101             $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
102             => $trait for $ty $(; |$candidate| $is_bit_valid)?
103         );
104     };
105     (
106         $(#[$attr:meta])*
107         $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
108         => $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
109     ) => {{
110         unsafe_impl!(
111             @inner
112             $(#[$attr])*
113             $($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
114             => $trait for $ty $(; |$candidate| $is_bit_valid)?
115         );
116     }};
117     (
118         @inner
119         $(#[$attr:meta])*
120         $(@const $constname:ident : $constty:ident,)*
121         $($tyvar:ident $(: $(? $optbound:ident +)* + $($bound:ident +)* )?,)*
122         => $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
123     ) => {{
124         crate::util::macros::__unsafe();
125 
126         $(#[$attr])*
127         #[allow(non_local_definitions)]
128         // SAFETY: The caller promises that this is sound.
129         unsafe impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?),* $(, const $constname: $constty,)*> $trait for $ty {
130             unsafe_impl!(@method $trait $(; |$candidate| $is_bit_valid)?);
131         }
132     }};
133 
134     (@method TryFromBytes ; |$candidate:ident| $is_bit_valid:expr) => {
135         #[allow(clippy::missing_inline_in_public_items, dead_code)]
136         #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
137         fn only_derive_is_allowed_to_implement_this_trait() {}
138 
139         #[inline]
140         fn is_bit_valid<Alignment>($candidate: Maybe<'_, Self, Alignment>) -> bool
141         where
142             Alignment: crate::invariant::Alignment,
143         {
144             $is_bit_valid
145         }
146     };
147     (@method TryFromBytes) => {
148         #[allow(clippy::missing_inline_in_public_items)]
149         #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
150         fn only_derive_is_allowed_to_implement_this_trait() {}
151         #[inline(always)]
152         fn is_bit_valid<Alignment>(_candidate: Maybe<'_, Self, Alignment>) -> bool
153         where
154             Alignment: crate::invariant::Alignment,
155         {
156             true
157         }
158     };
159     (@method $trait:ident) => {
160         #[allow(clippy::missing_inline_in_public_items, dead_code)]
161         #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
162         fn only_derive_is_allowed_to_implement_this_trait() {}
163     };
164     (@method $trait:ident; |$_candidate:ident| $_is_bit_valid:expr) => {
165         compile_error!("Can't provide `is_bit_valid` impl for trait other than `TryFromBytes`");
166     };
167 }
168 
169 /// Implements `$trait` for `$ty` where `$ty: TransmuteFrom<$repr>` (and
170 /// vice-versa).
171 ///
172 /// Calling this macro is safe; the internals of the macro emit appropriate
173 /// trait bounds which ensure that the given impl is sound.
174 macro_rules! impl_for_transmute_from {
175     (
176         $(#[$attr:meta])*
177         $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?)?
178         => $trait:ident for $ty:ty [$repr:ty]
179     ) => {
180         const _: () = {
181             $(#[$attr])*
182             #[allow(non_local_definitions)]
183 
184             // SAFETY: `is_trait<T, R>` (defined and used below) requires `T:
185             // TransmuteFrom<R>`, `R: TransmuteFrom<T>`, and `R: $trait`. It is
186             // called using `$ty` and `$repr`, ensuring that `$ty` and `$repr`
187             // have equivalent bit validity, and ensuring that `$repr: $trait`.
188             // The supported traits - `TryFromBytes`, `FromZeros`, `FromBytes`,
189             // and `IntoBytes` - are defined only in terms of the bit validity
190             // of a type. Therefore, `$repr: $trait` ensures that `$ty: $trait`
191             // is sound.
192             unsafe impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?)?> $trait for $ty {
193                 #[allow(dead_code, clippy::missing_inline_in_public_items)]
194                 #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
195                 fn only_derive_is_allowed_to_implement_this_trait() {
196                     use crate::pointer::{*, invariant::Valid};
197 
198                     impl_for_transmute_from!(@assert_is_supported_trait $trait);
199 
200                     fn is_trait<T, R>()
201                     where
202                         T: TransmuteFrom<R, Valid, Valid> + ?Sized,
203                         R: TransmuteFrom<T, Valid, Valid> + ?Sized,
204                         R: $trait,
205                     {
206                     }
207 
208                     #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
209                     fn f<$($tyvar $(: $(? $optbound +)* $($bound +)*)?)?>() {
210                         is_trait::<$ty, $repr>();
211                     }
212                 }
213 
214                 impl_for_transmute_from!(
215                     @is_bit_valid
216                     $(<$tyvar $(: $(? $optbound +)* $($bound +)*)?>)?
217                     $trait for $ty [$repr]
218                 );
219             }
220         };
221     };
222     (@assert_is_supported_trait TryFromBytes) => {};
223     (@assert_is_supported_trait FromZeros) => {};
224     (@assert_is_supported_trait FromBytes) => {};
225     (@assert_is_supported_trait IntoBytes) => {};
226     (
227         @is_bit_valid
228         $(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
229         TryFromBytes for $ty:ty [$repr:ty]
230     ) => {
231         #[inline(always)]
232         fn is_bit_valid<Alignment>(candidate: $crate::Maybe<'_, Self, Alignment>) -> bool
233         where
234             Alignment: $crate::invariant::Alignment,
235         {
236             // SAFETY: This macro ensures that `$repr` and `Self` have the same
237             // size and bit validity. Thus, a bit-valid instance of `$repr` is
238             // also a bit-valid instance of `Self`.
239             <$repr as TryFromBytes>::is_bit_valid(candidate.transmute::<_, _, BecauseImmutable>())
240         }
241     };
242     (
243         @is_bit_valid
244         $(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
245         $trait:ident for $ty:ty [$repr:ty]
246     ) => {
247         // Trait other than `TryFromBytes`; no `is_bit_valid` impl.
248     };
249 }
250 
251 /// Implements a trait for a type, bounding on each member of the power set of
252 /// a set of type variables. This is useful for implementing traits for tuples
253 /// or `fn` types.
254 ///
255 /// The last argument is the name of a macro which will be called in every
256 /// `impl` block, and is expected to expand to the name of the type for which to
257 /// implement the trait.
258 ///
259 /// For example, the invocation:
260 /// ```ignore
261 /// unsafe_impl_for_power_set!(A, B => Foo for type!(...))
262 /// ```
263 /// ...expands to:
264 /// ```ignore
265 /// unsafe impl       Foo for type!()     { ... }
266 /// unsafe impl<B>    Foo for type!(B)    { ... }
267 /// unsafe impl<A, B> Foo for type!(A, B) { ... }
268 /// ```
269 macro_rules! unsafe_impl_for_power_set {
270     (
271         $first:ident $(, $rest:ident)* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)
272         $(; |$candidate:ident| $is_bit_valid:expr)?
273     ) => {
274         unsafe_impl_for_power_set!(
275             $($rest),* $(-> $ret)? => $trait for $macro!(...)
276             $(; |$candidate| $is_bit_valid)?
277         );
278         unsafe_impl_for_power_set!(
279             @impl $first $(, $rest)* $(-> $ret)? => $trait for $macro!(...)
280             $(; |$candidate| $is_bit_valid)?
281         );
282     };
283     (
284         $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)
285         $(; |$candidate:ident| $is_bit_valid:expr)?
286     ) => {
287         unsafe_impl_for_power_set!(
288             @impl $(-> $ret)? => $trait for $macro!(...)
289             $(; |$candidate| $is_bit_valid)?
290         );
291     };
292     (
293         @impl $($vars:ident),* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)
294         $(; |$candidate:ident| $is_bit_valid:expr)?
295     ) => {
296         unsafe_impl!(
297             $($vars,)* $($ret)? => $trait for $macro!($($vars),* $(-> $ret)?)
298             $(; |$candidate| $is_bit_valid)?
299         );
300     };
301 }
302 
303 /// Expands to an `Option<extern "C" fn>` type with the given argument types and
304 /// return type. Designed for use with `unsafe_impl_for_power_set`.
305 macro_rules! opt_extern_c_fn {
306     ($($args:ident),* -> $ret:ident) => { Option<extern "C" fn($($args),*) -> $ret> };
307 }
308 
309 /// Expands to an `Option<unsafe extern "C" fn>` type with the given argument
310 /// types and return type. Designed for use with `unsafe_impl_for_power_set`.
311 macro_rules! opt_unsafe_extern_c_fn {
312     ($($args:ident),* -> $ret:ident) => { Option<unsafe extern "C" fn($($args),*) -> $ret> };
313 }
314 
315 /// Expands to an `Option<fn>` type with the given argument types and return
316 /// type. Designed for use with `unsafe_impl_for_power_set`.
317 macro_rules! opt_fn {
318     ($($args:ident),* -> $ret:ident) => { Option<fn($($args),*) -> $ret> };
319 }
320 
321 /// Expands to an `Option<unsafe fn>` type with the given argument types and
322 /// return type. Designed for use with `unsafe_impl_for_power_set`.
323 macro_rules! opt_unsafe_fn {
324     ($($args:ident),* -> $ret:ident) => { Option<unsafe fn($($args),*) -> $ret> };
325 }
326 
327 // This `allow` is needed because, when testing, we export this macro so it can
328 // be used in `doctests`.
329 #[allow(rustdoc::private_intra_doc_links)]
330 /// Implements trait(s) for a type or verifies the given implementation by
331 /// referencing an existing (derived) implementation.
332 ///
333 /// This macro exists so that we can provide zerocopy-derive as an optional
334 /// dependency and still get the benefit of using its derives to validate that
335 /// our trait impls are sound.
336 ///
337 /// When compiling without `--cfg 'feature = "derive"` and without `--cfg test`,
338 /// `impl_or_verify!` emits the provided trait impl. When compiling with either
339 /// of those cfgs, it is expected that the type in question is deriving the
340 /// traits instead. In this case, `impl_or_verify!` emits code which validates
341 /// that the given trait impl is at least as restrictive as the the impl emitted
342 /// by the custom derive. This has the effect of confirming that the impl which
343 /// is emitted when the `derive` feature is disabled is actually sound (on the
344 /// assumption that the impl emitted by the custom derive is sound).
345 ///
346 /// The caller is still required to provide a safety comment (e.g. using the
347 /// `const _: () = unsafe` macro). The reason for this restriction is that,
348 /// while `impl_or_verify!` can guarantee that the provided impl is sound when
349 /// it is compiled with the appropriate cfgs, there is no way to guarantee that
350 /// it is ever compiled with those cfgs. In particular, it would be possible to
351 /// accidentally place an `impl_or_verify!` call in a context that is only ever
352 /// compiled when the `derive` feature is disabled. If that were to happen,
353 /// there would be nothing to prevent an unsound trait impl from being emitted.
354 /// Requiring a safety comment reduces the likelihood of emitting an unsound
355 /// impl in this case, and also provides useful documentation for readers of the
356 /// code.
357 ///
358 /// Finally, if a `TryFromBytes::is_bit_valid` impl is provided, it must adhere
359 /// to the safety preconditions of [`unsafe_impl!`].
360 ///
361 /// ## Example
362 ///
363 /// ```rust,ignore
364 /// // Note that these derives are gated by `feature = "derive"`
365 /// #[cfg_attr(any(feature = "derive", test), derive(FromZeros, FromBytes, IntoBytes, Unaligned))]
366 /// #[repr(transparent)]
367 /// struct Wrapper<T>(T);
368 ///
369 /// const _: () = unsafe {
370 ///     /// SAFETY:
371 ///     /// `Wrapper<T>` is `repr(transparent)`, so it is sound to implement any
372 ///     /// zerocopy trait if `T` implements that trait.
373 ///     impl_or_verify!(T: FromZeros => FromZeros for Wrapper<T>);
374 ///     impl_or_verify!(T: FromBytes => FromBytes for Wrapper<T>);
375 ///     impl_or_verify!(T: IntoBytes => IntoBytes for Wrapper<T>);
376 ///     impl_or_verify!(T: Unaligned => Unaligned for Wrapper<T>);
377 /// }
378 /// ```
379 #[cfg_attr(__ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE, macro_export)] // Used in `doctests.rs`
380 #[doc(hidden)]
381 macro_rules! impl_or_verify {
382     // The following two match arms follow the same pattern as their
383     // counterparts in `unsafe_impl!`; see the documentation on those arms for
384     // more details.
385     (
386         const $constname:ident : $constty:ident $(,)?
387         $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
388         => $trait:ident for $ty:ty
389     ) => {
390         impl_or_verify!(@impl { unsafe_impl!(
391             const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
392         ); });
393         impl_or_verify!(@verify $trait, {
394             impl<const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
395         });
396     };
397     (
398         $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
399         => $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
400     ) => {
401         impl_or_verify!(@impl { unsafe_impl!(
402             $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
403             $(; |$candidate| $is_bit_valid)?
404         ); });
405         impl_or_verify!(@verify $trait, {
406             impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
407         });
408     };
409     (@impl $impl_block:tt) => {
410         #[cfg(not(any(feature = "derive", test)))]
411         { $impl_block };
412     };
413     (@verify $trait:ident, $impl_block:tt) => {
414         #[cfg(any(feature = "derive", test))]
415         {
416             // On some toolchains, `Subtrait` triggers the `dead_code` lint
417             // because it is implemented but never used.
418             #[allow(dead_code)]
419             trait Subtrait: $trait {}
420             $impl_block
421         };
422     };
423 }
424 
425 /// Implements `KnownLayout` for a sized type.
426 macro_rules! impl_known_layout {
427     ($(const $constvar:ident : $constty:ty, $tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
428         $(impl_known_layout!(@inner const $constvar: $constty, $tyvar $(: ?$optbound)? => $ty);)*
429     };
430     ($($tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
431         $(impl_known_layout!(@inner , $tyvar $(: ?$optbound)? => $ty);)*
432     };
433     ($($(#[$attrs:meta])* $ty:ty),*) => { $(impl_known_layout!(@inner , => $(#[$attrs])* $ty);)* };
434     (@inner $(const $constvar:ident : $constty:ty)? , $($tyvar:ident $(: ?$optbound:ident)?)? => $(#[$attrs:meta])* $ty:ty) => {
435         const _: () = {
436             use core::ptr::NonNull;
437 
438             #[allow(non_local_definitions)]
439             $(#[$attrs])*
440             // SAFETY: Delegates safety to `DstLayout::for_type`.
441             unsafe impl<$($tyvar $(: ?$optbound)?)? $(, const $constvar : $constty)?> KnownLayout for $ty {
442                 #[allow(clippy::missing_inline_in_public_items)]
443                 #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
444                 fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized {}
445 
446                 type PointerMetadata = ();
447 
448                 // SAFETY: `CoreMaybeUninit<T>::LAYOUT` and `T::LAYOUT` are
449                 // identical because `CoreMaybeUninit<T>` has the same size and
450                 // alignment as `T` [1], and `CoreMaybeUninit` admits
451                 // uninitialized bytes in all positions.
452                 //
453                 // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/union.MaybeUninit.html#layout-1:
454                 //
455                 //   `MaybeUninit<T>` is guaranteed to have the same size,
456                 //   alignment, and ABI as `T`
457                 type MaybeUninit = core::mem::MaybeUninit<Self>;
458 
459                 const LAYOUT: crate::DstLayout = crate::DstLayout::for_type::<$ty>();
460 
461                 // SAFETY: `.cast` preserves address and provenance.
462                 //
463                 // FIXME(#429): Add documentation to `.cast` that promises that
464                 // it preserves provenance.
465                 #[inline(always)]
466                 fn raw_from_ptr_len(bytes: NonNull<u8>, _meta: ()) -> NonNull<Self> {
467                     bytes.cast::<Self>()
468                 }
469 
470                 #[inline(always)]
471                 fn pointer_to_metadata(_ptr: *mut Self) -> () {
472                 }
473             }
474         };
475     };
476 }
477 
478 /// Implements `KnownLayout` for a type in terms of the implementation of
479 /// another type with the same representation.
480 ///
481 /// # Safety
482 ///
483 /// - `$ty` and `$repr` must have the same:
484 ///   - Fixed prefix size
485 ///   - Alignment
486 ///   - (For DSTs) trailing slice element size
487 /// - It must be valid to perform an `as` cast from `*mut $repr` to `*mut $ty`,
488 ///   and this operation must preserve referent size (ie, `size_of_val_raw`).
489 macro_rules! unsafe_impl_known_layout {
490     ($($tyvar:ident: ?Sized + KnownLayout =>)? #[repr($repr:ty)] $ty:ty) => {{
491         use core::ptr::NonNull;
492 
493         crate::util::macros::__unsafe();
494 
495         #[allow(non_local_definitions)]
496         // SAFETY: The caller promises that this is sound.
497         unsafe impl<$($tyvar: ?Sized + KnownLayout)?> KnownLayout for $ty {
498             #[allow(clippy::missing_inline_in_public_items, dead_code)]
499             #[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
500             fn only_derive_is_allowed_to_implement_this_trait() {}
501 
502             type PointerMetadata = <$repr as KnownLayout>::PointerMetadata;
503             type MaybeUninit = <$repr as KnownLayout>::MaybeUninit;
504 
505             const LAYOUT: DstLayout = <$repr as KnownLayout>::LAYOUT;
506 
507             // SAFETY: All operations preserve address and provenance. Caller
508             // has promised that the `as` cast preserves size.
509             //
510             // FIXME(#429): Add documentation to `NonNull::new_unchecked` that
511             // it preserves provenance.
512             #[inline(always)]
513             fn raw_from_ptr_len(bytes: NonNull<u8>, meta: <$repr as KnownLayout>::PointerMetadata) -> NonNull<Self> {
514                 #[allow(clippy::as_conversions)]
515                 let ptr = <$repr>::raw_from_ptr_len(bytes, meta).as_ptr() as *mut Self;
516                 // SAFETY: `ptr` was converted from `bytes`, which is non-null.
517                 unsafe { NonNull::new_unchecked(ptr) }
518             }
519 
520             #[inline(always)]
521             fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
522                 #[allow(clippy::as_conversions)]
523                 let ptr = ptr as *mut $repr;
524                 <$repr>::pointer_to_metadata(ptr)
525             }
526         }
527     }};
528 }
529 
530 /// Uses `align_of` to confirm that a type or set of types have alignment 1.
531 ///
532 /// Note that `align_of<T>` requires `T: Sized`, so this macro doesn't work for
533 /// unsized types.
534 macro_rules! assert_unaligned {
535     ($($tys:ty),*) => {
536         $(
537             // We only compile this assertion under `cfg(test)` to avoid taking
538             // an extra non-dev dependency (and making this crate more expensive
539             // to compile for our dependents).
540             #[cfg(test)]
541             static_assertions::const_assert_eq!(core::mem::align_of::<$tys>(), 1);
542         )*
543     };
544 }
545 
546 /// Emits a function definition as either `const fn` or `fn` depending on
547 /// whether the current toolchain version supports `const fn` with generic trait
548 /// bounds.
549 macro_rules! maybe_const_trait_bounded_fn {
550     // This case handles both `self` methods (where `self` is by value) and
551     // non-method functions. Each `$args` may optionally be followed by `:
552     // $arg_tys:ty`, which can be omitted for `self`.
553     ($(#[$attr:meta])* $vis:vis const fn $name:ident($($args:ident $(: $arg_tys:ty)?),* $(,)?) $(-> $ret_ty:ty)? $body:block) => {
554         #[cfg(not(no_zerocopy_generic_bounds_in_const_fn_1_61_0))]
555         $(#[$attr])* $vis const fn $name($($args $(: $arg_tys)?),*) $(-> $ret_ty)? $body
556 
557         #[cfg(no_zerocopy_generic_bounds_in_const_fn_1_61_0)]
558         $(#[$attr])* $vis fn $name($($args $(: $arg_tys)?),*) $(-> $ret_ty)? $body
559     };
560 }
561 
562 /// Either panic (if the current Rust toolchain supports panicking in `const
563 /// fn`) or evaluate a constant that will cause an array indexing error whose
564 /// error message will include the format string.
565 ///
566 /// The type that this expression evaluates to must be `Copy`, or else the
567 /// non-panicking desugaring will fail to compile.
568 macro_rules! const_panic {
569     (@non_panic $($_arg:tt)+) => {{
570         // This will type check to whatever type is expected based on the call
571         // site.
572         let panic: [_; 0] = [];
573         // This will always fail (since we're indexing into an array of size 0.
574         #[allow(unconditional_panic)]
575         panic[0]
576     }};
577     ($($arg:tt)+) => {{
578         #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
579         panic!($($arg)+);
580         #[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
581         const_panic!(@non_panic $($arg)+)
582     }};
583 }
584 
585 /// Either assert (if the current Rust toolchain supports panicking in `const
586 /// fn`) or evaluate the expression and, if it evaluates to `false`, call
587 /// `const_panic!`. This is used in place of `assert!` in const contexts to
588 /// accommodate old toolchains.
589 macro_rules! const_assert {
590     ($e:expr) => {{
591         #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
592         assert!($e);
593         #[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
594         {
595             let e = $e;
596             if !e {
597                 let _: () = const_panic!(@non_panic concat!("assertion failed: ", stringify!($e)));
598             }
599         }
600     }};
601     ($e:expr, $($args:tt)+) => {{
602         #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
603         assert!($e, $($args)+);
604         #[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
605         {
606             let e = $e;
607             if !e {
608                 let _: () = const_panic!(@non_panic concat!("assertion failed: ", stringify!($e), ": ", stringify!($arg)), $($args)*);
609             }
610         }
611     }};
612 }
613 
614 /// Like `const_assert!`, but relative to `debug_assert!`.
615 macro_rules! const_debug_assert {
616     ($e:expr $(, $msg:expr)?) => {{
617         #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
618         debug_assert!($e $(, $msg)?);
619         #[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
620         {
621             // Use this (rather than `#[cfg(debug_assertions)]`) to ensure that
622             // `$e` is always compiled even if it will never be evaluated at
623             // runtime.
624             if cfg!(debug_assertions) {
625                 let e = $e;
626                 if !e {
627                     let _: () = const_panic!(@non_panic concat!("assertion failed: ", stringify!($e) $(, ": ", $msg)?));
628                 }
629             }
630         }
631     }}
632 }
633 
634 /// Either invoke `unreachable!()` or `loop {}` depending on whether the Rust
635 /// toolchain supports panicking in `const fn`.
636 macro_rules! const_unreachable {
637     () => {{
638         #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
639         unreachable!();
640 
641         #[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
642         loop {}
643     }};
644 }
645 
646 /// Asserts at compile time that `$condition` is true for `Self` or the given
647 /// `$tyvar`s. Unlike `const_assert`, this is *strictly* a compile-time check;
648 /// it cannot be evaluated in a runtime context. The condition is checked after
649 /// monomorphization and, upon failure, emits a compile error.
650 macro_rules! static_assert {
651     (Self $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )? => $condition:expr $(, $args:tt)*) => {{
652         trait StaticAssert {
653             const ASSERT: bool;
654         }
655 
656         impl<T $(: $(? $optbound +)* $($bound +)*)?> StaticAssert for T {
657             const ASSERT: bool = {
658                 const_assert!($condition $(, $args)*);
659                 $condition
660             };
661         }
662 
663         const_assert!(<Self as StaticAssert>::ASSERT);
664     }};
665     ($($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),* => $condition:expr $(, $args:tt)*) => {{
666         trait StaticAssert {
667             const ASSERT: bool;
668         }
669 
670         // NOTE: We use `PhantomData` so we can support unsized types.
671         impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?,)*> StaticAssert for ($(core::marker::PhantomData<$tyvar>,)*) {
672             const ASSERT: bool = {
673                 const_assert!($condition $(, $args)*);
674                 $condition
675             };
676         }
677 
678         const_assert!(<($(core::marker::PhantomData<$tyvar>,)*) as StaticAssert>::ASSERT);
679     }};
680 }
681 
682 /// Assert at compile time that `tyvar` does not have a zero-sized DST
683 /// component.
684 macro_rules! static_assert_dst_is_not_zst {
685     ($tyvar:ident) => {{
686         use crate::KnownLayout;
687         static_assert!($tyvar: ?Sized + KnownLayout => {
688             let dst_is_zst = match $tyvar::LAYOUT.size_info {
689                 crate::SizeInfo::Sized { .. } => false,
690                 crate::SizeInfo::SliceDst(TrailingSliceLayout { elem_size, .. }) => {
691                     elem_size == 0
692                 }
693             };
694             !dst_is_zst
695         }, "cannot call this method on a dynamically-sized type whose trailing slice element is zero-sized");
696     }}
697 }
698 
699 /// Defines a named [`Cast`] implementation.
700 ///
701 /// # Safety
702 ///
703 /// The caller must ensure that, given `src: *mut $src`, `src as *mut $dst` is a
704 /// size-preserving or size-shrinking cast.
705 ///
706 /// [`Cast`]: crate::pointer::cast::Cast
707 #[macro_export]
708 #[doc(hidden)]
709 macro_rules! define_cast {
710     // We require the caller to provide an `unsafe` block as part of the input
711     // syntax since a call to `define_cast!` is useless inside of an `unsafe`
712     // block (since it would introduce a type which can't be named outside of
713     // the context of that block).
714     (unsafe { $vis:vis $name:ident $(<$tyvar:ident $(: ?$optbound:ident)?>)? = $src:ty => $dst:ty }) => {
715         #[allow(missing_debug_implementations, missing_copy_implementations, unreachable_pub)]
716         $vis enum $name {}
717 
718         // SAFETY: The caller promises that `src as *mut $src` is a size-
719         // preserving or size-shrinking cast. All operations preserve
720         // provenance.
721         unsafe impl $(<$tyvar $(: ?$optbound)?>)? $crate::pointer::cast::Project<$src, $dst> for $name {
722             fn project(src: $crate::pointer::PtrInner<'_, $src>) -> *mut $dst {
723                 #[allow(clippy::as_conversions)]
724                 return src.as_ptr() as *mut $dst;
725             }
726         }
727 
728         // SAFETY: The impl of `Project::project` preserves referent address.
729         unsafe impl $(<$tyvar $(: ?$optbound)?>)? $crate::pointer::cast::Cast<$src, $dst> for $name {}
730     };
731 }
732 
733 /// Implements `TransmuteFrom` and `SizeEq` for `T` and `$wrapper<T>`.
734 ///
735 /// # Safety
736 ///
737 /// `T` and `$wrapper<T>` must have the same bit validity, and must have the
738 /// same size in the sense of `CastExact` (specifically, both a
739 /// `T`-to-`$wrapper<T>` cast and a `$wrapper<T>`-to-`T` cast must be
740 /// size-preserving).
741 macro_rules! unsafe_impl_for_transparent_wrapper {
742     ($vis:vis T $(: ?$optbound:ident)? => $wrapper:ident<T>) => {{
743         crate::util::macros::__unsafe();
744 
745         use crate::pointer::{TransmuteFrom, cast::{CastExact, TransitiveProject}, SizeEq, invariant::Valid};
746         use crate::wrappers::ReadOnly;
747 
748         // SAFETY: The caller promises that `T` and `$wrapper<T>` have the same
749         // bit validity.
750         unsafe impl<T $(: ?$optbound)?> TransmuteFrom<T, Valid, Valid> for $wrapper<T> {}
751         // SAFETY: See previous safety comment.
752         unsafe impl<T $(: ?$optbound)?> TransmuteFrom<$wrapper<T>, Valid, Valid> for T {}
753         // SAFETY: The caller promises that a `T` to `$wrapper<T>` cast is
754         // size-preserving.
755         define_cast!(unsafe { $vis CastToWrapper<T $(: ?$optbound)? > = T => $wrapper<T> });
756         // SAFETY: The caller promises that a `T` to `$wrapper<T>` cast is
757         // size-preserving.
758         unsafe impl<T $(: ?$optbound)?> CastExact<T, $wrapper<T>> for CastToWrapper {}
759         // SAFETY: The caller promises that a `$wrapper<T>` to `T` cast is
760         // size-preserving.
761         define_cast!(unsafe { $vis CastFromWrapper<T $(: ?$optbound)? > = $wrapper<T> => T });
762         // SAFETY: The caller promises that a `$wrapper<T>` to `T` cast is
763         // size-preserving.
764         unsafe impl<T $(: ?$optbound)?> CastExact<$wrapper<T>, T> for CastFromWrapper {}
765 
766         impl<T $(: ?$optbound)?> SizeEq<T> for $wrapper<T> {
767             type CastFrom = CastToWrapper;
768         }
769         impl<T $(: ?$optbound)?> SizeEq<$wrapper<T>> for T {
770             type CastFrom = CastFromWrapper;
771         }
772 
773         impl<T $(: ?$optbound)?> SizeEq<ReadOnly<T>> for $wrapper<T> {
774             type CastFrom = TransitiveProject<
775                 T,
776                 <T as SizeEq<ReadOnly<T>>>::CastFrom,
777                 CastToWrapper,
778             >;
779         }
780         impl<T $(: ?$optbound)?> SizeEq<$wrapper<T>> for ReadOnly<T> {
781             type CastFrom = TransitiveProject<
782                 T,
783                 CastFromWrapper,
784                 <ReadOnly<T> as SizeEq<T>>::CastFrom,
785             >;
786         }
787 
788         impl<T $(: ?$optbound)?> SizeEq<ReadOnly<T>> for ReadOnly<$wrapper<T>> {
789             type CastFrom = TransitiveProject<
790                 $wrapper<T>,
791                 <$wrapper<T> as SizeEq<ReadOnly<T>>>::CastFrom,
792                 <ReadOnly<$wrapper<T>> as SizeEq<$wrapper<T>>>::CastFrom,
793             >;
794         }
795         impl<T $(: ?$optbound)?> SizeEq<ReadOnly<$wrapper<T>>> for ReadOnly<T> {
796             type CastFrom = TransitiveProject<
797                 $wrapper<T>,
798                 <$wrapper<T> as SizeEq<ReadOnly<$wrapper<T>>>>::CastFrom,
799                 <ReadOnly<T> as SizeEq<$wrapper<T>>>::CastFrom,
800             >;
801         }
802     }};
803 }
804 
805 macro_rules! impl_transitive_transmute_from {
806     ($($tyvar:ident $(: ?$optbound:ident)?)? => $t:ty => $u:ty => $v:ty) => {
807         const _: () = {
808             use crate::pointer::{TransmuteFrom, SizeEq, invariant::Valid};
809 
810             impl<$($tyvar $(: ?$optbound)?)?> SizeEq<$t> for $v
811             where
812                 $u: SizeEq<$t>,
813                 $v: SizeEq<$u>,
814             {
815                 type CastFrom = cast::TransitiveProject<
816                     $u,
817                     <$u as SizeEq<$t>>::CastFrom,
818                     <$v as SizeEq<$u>>::CastFrom
819                 >;
820             }
821 
822             // SAFETY: Since `$u: TransmuteFrom<$t, Valid, Valid>`, it is sound
823             // to transmute a bit-valid `$t` to a bit-valid `$u`. Since `$v:
824             // TransmuteFrom<$u, Valid, Valid>`, it is sound to transmute that
825             // bit-valid `$u` to a bit-valid `$v`.
826             unsafe impl<$($tyvar $(: ?$optbound)?)?> TransmuteFrom<$t, Valid, Valid> for $v
827             where
828                 $u: TransmuteFrom<$t, Valid, Valid>,
829                 $v: TransmuteFrom<$u, Valid, Valid>,
830             {}
831         };
832     };
833 }
834 
835 /// A no-op `unsafe fn` for use in macro expansions.
836 ///
837 /// Calling this function in a macro expansion ensures that the macro's caller
838 /// must wrap the call in `unsafe { ... }`.
839 #[inline(always)]
840 pub(crate) const unsafe fn __unsafe() {}
841 
842 /// Extracts the contents of doc comments.
843 #[allow(unused)]
844 macro_rules! docstring {
845     ($(#[doc = $content:expr])*) => {
846         concat!($($content, "\n",)*)
847     }
848 }
849 
850 /// Generate a rustdoc-style header with `$name` as the HTML ID for the 'Code
851 /// Generation' section of documentation.
852 #[allow(unused)]
853 macro_rules! codegen_header {
854     ($level:expr, $name:expr) => {
855         concat!(
856             "
857 <",
858             $level,
859             " id='method.",
860             $name,
861             ".codegen'>
862     <a class='doc-anchor' href='#method.",
863             $name,
864             ".codegen'>§</a>
865     Code Generation
866 </",
867             $level,
868             ">
869 "
870         )
871     };
872 }
873 
874 /// Generates HTML tabs.
875 #[rustfmt::skip]
876 #[allow(unused)]
877 macro_rules! tabs {
878     (
879         name = $name:expr,
880         arity = $arity:literal,
881         $([
882             $($open:ident)?
883             @index $n:literal
884             @title $title:literal
885             $(#[doc = $content:expr])*
886         ]),*
887     ) => {
888         concat!("
889 <div class='codegen-tabs' style='--arity: ", $arity ,"'>", $(concat!("
890     <details name='tab-", $name,"' style='--n: ", $n ,"'", $(stringify!($open),)*">
891         <summary><h6>", $title, "</h6></summary>
892         <div>
893 
894 ", $($content, "\n",)* "
895 \
896         </div>
897     </details>"),)*
898 "</div>")
899     }
900 }
901 
902 /// Generates the HTML for a single benchmark example.
903 #[allow(unused)]
904 macro_rules! codegen_example {
905     (format = $format:expr, bench = $bench:expr) => {
906         tabs!(
907             name = $bench,
908             arity = 4,
909             [
910                 @index 1
911                 @title "Format"
912                 /// ```ignore
913                 #[doc = include_str!(concat!("../benches/formats/", $format, ".rs"))]
914                 /// ```
915             ],
916             [
917                 @index 2
918                 @title "Benchmark"
919                 /// ```ignore
920                 #[doc = include_str!(concat!("../benches/", $bench, ".rs"))]
921                 /// ```
922             ],
923             [
924                 open
925                 @index 3
926                 @title "Assembly"
927                 /// ```plain
928                 #[doc = include_str!(concat!("../benches/", $bench, ".x86-64"))]
929                 /// ```
930             ],
931             [
932                 @index 4
933                 @title "Machine Code Analysis"
934                 /// ```plain
935                 #[doc = include_str!(concat!("../benches/", $bench, ".x86-64.mca"))]
936                 /// ```
937             ]
938         )
939     }
940 }
941 
942 /// Generate the HTML for a suite of benchmark examples.
943 #[allow(unused)]
944 macro_rules! codegen_example_suite {
945     (
946         bench = $bench:expr,
947         format = $format:expr,
948         arity = $arity:literal,
949         $([
950             $($open:ident)?
951             @index $index:literal
952             @title $title:literal
953             @variant $variant:literal
954         ]),*
955     ) => {
956         tabs!(
957             name = $bench,
958             arity = $arity,
959             $([
960                 $($open)*
961                 @index $index
962                 @title $title
963                 #[doc = codegen_example!(
964                     format = concat!($format, "_", $variant),
965                     bench = concat!($bench, "_", $variant)
966                 )]
967             ]),*
968         )
969     }
970 }
971 
972 /// Generates the string for code generation preamble.
973 #[allow(unused)]
974 macro_rules! codegen_preamble {
975     () => {
976         docstring!(
977             ///
978             /// This abstraction is safe and cheap, but does not necessarily
979             /// have zero runtime cost. The codegen you experience in practice
980             /// will depend on optimization level, the layout of the destination
981             /// type, and what the compiler can prove about the source.
982             ///
983         )
984     }
985 }
986 
987 /// Stub for rendering codegen documentation; used to break build dependency
988 /// between benches and zerocopy when re-blessing codegen tests.
989 #[allow(unused)]
990 #[cfg(not(doc))]
991 macro_rules! codegen_section {
992     (
993         header = $level:expr,
994         bench = $bench:expr,
995         format = $format:expr,
996         arity = $arity:literal,
997         $([
998             $($open:ident)?
999             @index $index:literal
1000             @title $title:literal
1001             @variant $variant:literal
1002         ]),*
1003     ) => {
1004         ""
1005     };
1006     (
1007         header = $level:expr,
1008         bench = $bench:expr,
1009         format = $format:expr,
1010     ) => {
1011         ""
1012     };
1013 }
1014 
1015 /// Generates the HTML for code generation documentation.
1016 #[allow(unused)]
1017 #[cfg(doc)]
1018 macro_rules! codegen_section {
1019     (
1020         header = $level:expr,
1021         bench = $bench:expr,
1022         format = $format:expr,
1023         arity = $arity:literal,
1024         $([
1025             $($open:ident)?
1026             @index $index:literal
1027             @title $title:literal
1028             @variant $variant:literal
1029         ]),*
1030     ) => {
1031         concat!(
1032             codegen_header!($level, $bench),
1033             codegen_preamble!(),
1034             docstring!(
1035                 ///
1036                 /// The below examples illustrate typical codegen for
1037                 /// increasingly complex types:
1038                 ///
1039             ),
1040             codegen_example_suite!(
1041                 bench = $bench,
1042                 format = $format,
1043                 arity = $arity,
1044                 $([
1045                     $($open)*
1046                     @index $index
1047                     @title $title
1048                     @variant $variant
1049                 ]),*
1050             )
1051         )
1052     };
1053     (
1054         header = $level:expr,
1055         bench = $bench:expr,
1056         format = $format:expr,
1057     ) => {
1058         concat!(
1059             codegen_header!($level, $bench),
1060             codegen_preamble!(),
1061             codegen_example!(
1062                 format = $format,
1063                 bench = $bench
1064             )
1065         )
1066     }
1067 }
1068