1macro_rules! unsafe_impl {
25 ($(#[$attr:meta])* $ty:ty: $trait:ident $(; |$candidate:ident| $is_bit_valid:expr)?) => {{
27 crate::util::macros::__unsafe();
28
29 $(#[$attr])*
30 unsafe impl $trait for $ty {
32 unsafe_impl!(@method $trait $(; |$candidate| $is_bit_valid)?);
33 }
34 }};
35
36 ($(#[$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 (
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 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
169macro_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 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 <$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 };
249}
250
251macro_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
303macro_rules! opt_extern_c_fn {
306 ($($args:ident),* -> $ret:ident) => { Option<extern "C" fn($($args),*) -> $ret> };
307}
308
309macro_rules! opt_unsafe_extern_c_fn {
312 ($($args:ident),* -> $ret:ident) => { Option<unsafe extern "C" fn($($args),*) -> $ret> };
313}
314
315macro_rules! opt_fn {
318 ($($args:ident),* -> $ret:ident) => { Option<fn($($args),*) -> $ret> };
319}
320
321macro_rules! opt_unsafe_fn {
324 ($($args:ident),* -> $ret:ident) => { Option<unsafe fn($($args),*) -> $ret> };
325}
326
327#[allow(rustdoc::private_intra_doc_links)]
330#[cfg_attr(__ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE, macro_export)] #[doc(hidden)]
381macro_rules! impl_or_verify {
382 (
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 #[allow(dead_code)]
419 trait Subtrait: $trait {}
420 $impl_block
421 };
422 };
423}
424
425macro_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 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 type MaybeUninit = core::mem::MaybeUninit<Self>;
458
459 const LAYOUT: crate::DstLayout = crate::DstLayout::for_type::<$ty>();
460
461 #[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
478macro_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 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 #[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 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
530macro_rules! assert_unaligned {
535 ($($tys:ty),*) => {
536 $(
537 #[cfg(test)]
541 static_assertions::const_assert_eq!(core::mem::align_of::<$tys>(), 1);
542 )*
543 };
544}
545
546macro_rules! maybe_const_trait_bounded_fn {
550 ($(#[$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
562macro_rules! const_panic {
569 (@non_panic $($_arg:tt)+) => {{
570 let panic: [_; 0] = [];
573 #[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
585macro_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
614macro_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 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
634macro_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
646macro_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 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
682macro_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#[macro_export]
708#[doc(hidden)]
709macro_rules! define_cast {
710 (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 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 unsafe impl $(<$tyvar $(: ?$optbound)?>)? $crate::pointer::cast::Cast<$src, $dst> for $name {}
730 };
731}
732
733macro_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 unsafe impl<T $(: ?$optbound)?> TransmuteFrom<T, Valid, Valid> for $wrapper<T> {}
751 unsafe impl<T $(: ?$optbound)?> TransmuteFrom<$wrapper<T>, Valid, Valid> for T {}
753 define_cast!(unsafe { $vis CastToWrapper<T $(: ?$optbound)? > = T => $wrapper<T> });
756 unsafe impl<T $(: ?$optbound)?> CastExact<T, $wrapper<T>> for CastToWrapper {}
759 define_cast!(unsafe { $vis CastFromWrapper<T $(: ?$optbound)? > = $wrapper<T> => T });
762 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
805macro_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 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#[inline(always)]
840pub(crate) const unsafe fn __unsafe() {}
841
842#[allow(unused)]
844macro_rules! docstring {
845 ($(#[doc = $content:expr])*) => {
846 concat!($($content, "\n",)*)
847 }
848}
849
850#[allow(unused)]
853macro_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#[rustfmt::skip]
876#[allow(unused)]
877macro_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#[allow(unused)]
904macro_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 #[doc = include_str!(concat!("../benches/formats/", $format, ".rs"))]
914 ],
916 [
917 @index 2
918 @title "Benchmark"
919 #[doc = include_str!(concat!("../benches/", $bench, ".rs"))]
921 ],
923 [
924 open
925 @index 3
926 @title "Assembly"
927 #[doc = include_str!(concat!("../benches/", $bench, ".x86-64"))]
929 ],
931 [
932 @index 4
933 @title "Machine Code Analysis"
934 #[doc = include_str!(concat!("../benches/", $bench, ".x86-64.mca"))]
936 ]
938 )
939 }
940}
941
942#[allow(unused)]
944macro_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#[allow(unused)]
974macro_rules! codegen_preamble {
975 () => {
976 docstring!(
977 )
984 }
985}
986
987#[allow(unused)]
990#[cfg(not(doc))]
991macro_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#[allow(unused)]
1017#[cfg(doc)]
1018macro_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 ),
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}