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