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