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)]
__unsafe()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