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