macro_rules! unsafe_impl {
($(#[$attr:meta])* $ty:ty: $trait:ident $(; |$candidate:ident| $is_bit_valid:expr)?) => {{
crate::util::macros::__unsafe();
$(#[$attr])*
unsafe impl $trait for $ty {
unsafe_impl!(@method $trait $(; |$candidate| $is_bit_valid)?);
}
}};
($(#[$attrs:meta])* $ty:ty: $($traits:ident),*) => {
unsafe_impl!(@impl_traits_with_packed_attrs { $(#[$attrs])* } $ty: $($traits),*)
};
(@impl_traits_with_packed_attrs $attrs:tt $ty:ty: $($traits:ident),*) => {{
$( unsafe_impl!(@unpack_attrs $attrs $ty: $traits); )*
}};
(@unpack_attrs { $(#[$attrs:meta])* } $ty:ty: $traits:ident) => {
unsafe_impl!($(#[$attrs])* $ty: $traits);
};
(
$(#[$attr:meta])*
const $constname:ident : $constty:ident $(,)?
$($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
=> $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
) => {
unsafe_impl!(
@inner
$(#[$attr])*
@const $constname: $constty,
$($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
=> $trait for $ty $(; |$candidate| $is_bit_valid)?
);
};
(
$(#[$attr:meta])*
$($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
=> $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
) => {{
unsafe_impl!(
@inner
$(#[$attr])*
$($tyvar $(: $(? $optbound +)* + $($bound +)*)?,)*
=> $trait for $ty $(; |$candidate| $is_bit_valid)?
);
}};
(
@inner
$(#[$attr:meta])*
$(@const $constname:ident : $constty:ident,)*
$($tyvar:ident $(: $(? $optbound:ident +)* + $($bound:ident +)* )?,)*
=> $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
) => {{
crate::util::macros::__unsafe();
$(#[$attr])*
#[allow(non_local_definitions)]
unsafe impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?),* $(, const $constname: $constty,)*> $trait for $ty {
unsafe_impl!(@method $trait $(; |$candidate| $is_bit_valid)?);
}
}};
(@method TryFromBytes ; |$candidate:ident| $is_bit_valid:expr) => {
#[allow(clippy::missing_inline_in_public_items, dead_code)]
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn only_derive_is_allowed_to_implement_this_trait() {}
#[inline]
fn is_bit_valid<AA: crate::pointer::invariant::Reference>($candidate: Maybe<'_, Self, AA>) -> bool {
$is_bit_valid
}
};
(@method TryFromBytes) => {
#[allow(clippy::missing_inline_in_public_items)]
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn only_derive_is_allowed_to_implement_this_trait() {}
#[inline(always)] fn is_bit_valid<AA: crate::pointer::invariant::Reference>(_: Maybe<'_, Self, AA>) -> bool { true }
};
(@method $trait:ident) => {
#[allow(clippy::missing_inline_in_public_items, dead_code)]
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn only_derive_is_allowed_to_implement_this_trait() {}
};
(@method $trait:ident; |$_candidate:ident| $_is_bit_valid:expr) => {
compile_error!("Can't provide `is_bit_valid` impl for trait other than `TryFromBytes`");
};
}
macro_rules! impl_for_transmute_from {
(
$(#[$attr:meta])*
$($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?)?
=> $trait:ident for $ty:ty [$($unsafe_cell:ident)? <$repr:ty>]
) => {
const _: () = {
$(#[$attr])*
#[allow(non_local_definitions)]
unsafe impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?)?> $trait for $ty {
#[allow(dead_code, clippy::missing_inline_in_public_items)]
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn only_derive_is_allowed_to_implement_this_trait() {
use crate::pointer::{*, invariant::Valid};
impl_for_transmute_from!(@assert_is_supported_trait $trait);
fn is_trait<T, R>()
where
T: TransmuteFrom<R, Valid, Valid> + ?Sized,
R: TransmuteFrom<T, Valid, Valid> + ?Sized,
R: $trait,
{
}
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn f<$($tyvar $(: $(? $optbound +)* $($bound +)*)?)?>() {
is_trait::<$ty, $repr>();
}
}
impl_for_transmute_from!(
@is_bit_valid
$(<$tyvar $(: $(? $optbound +)* $($bound +)*)?>)?
$trait for $ty [$($unsafe_cell)? <$repr>]
);
}
};
};
(@assert_is_supported_trait TryFromBytes) => {};
(@assert_is_supported_trait FromZeros) => {};
(@assert_is_supported_trait FromBytes) => {};
(@assert_is_supported_trait IntoBytes) => {};
(
@is_bit_valid
$(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
TryFromBytes for $ty:ty [UnsafeCell<$repr:ty>]
) => {
#[inline]
fn is_bit_valid<A: crate::pointer::invariant::Reference>(candidate: Maybe<'_, Self, A>) -> bool {
let c: Maybe<'_, Self, crate::pointer::invariant::Exclusive> = candidate.into_exclusive_or_pme();
let c: Maybe<'_, $repr, _> = c.transmute::<_, _, (_, (_, (BecauseExclusive, BecauseExclusive)))>();
<$repr as TryFromBytes>::is_bit_valid(c)
}
};
(
@is_bit_valid
$(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
TryFromBytes for $ty:ty [<$repr:ty>]
) => {
#[inline]
fn is_bit_valid<A: crate::pointer::invariant::Reference>(candidate: $crate::Maybe<'_, Self, A>) -> bool {
<$repr as TryFromBytes>::is_bit_valid(candidate.transmute())
}
};
(
@is_bit_valid
$(<$tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?>)?
$trait:ident for $ty:ty [$($unsafe_cell:ident)? <$repr:ty>]
) => {
};
}
macro_rules! unsafe_impl_for_power_set {
(
$first:ident $(, $rest:ident)* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)
$(; |$candidate:ident| $is_bit_valid:expr)?
) => {
unsafe_impl_for_power_set!(
$($rest),* $(-> $ret)? => $trait for $macro!(...)
$(; |$candidate| $is_bit_valid)?
);
unsafe_impl_for_power_set!(
@impl $first $(, $rest)* $(-> $ret)? => $trait for $macro!(...)
$(; |$candidate| $is_bit_valid)?
);
};
(
$(-> $ret:ident)? => $trait:ident for $macro:ident!(...)
$(; |$candidate:ident| $is_bit_valid:expr)?
) => {
unsafe_impl_for_power_set!(
@impl $(-> $ret)? => $trait for $macro!(...)
$(; |$candidate| $is_bit_valid)?
);
};
(
@impl $($vars:ident),* $(-> $ret:ident)? => $trait:ident for $macro:ident!(...)
$(; |$candidate:ident| $is_bit_valid:expr)?
) => {
unsafe_impl!(
$($vars,)* $($ret)? => $trait for $macro!($($vars),* $(-> $ret)?)
$(; |$candidate| $is_bit_valid)?
);
};
}
macro_rules! opt_extern_c_fn {
($($args:ident),* -> $ret:ident) => { Option<extern "C" fn($($args),*) -> $ret> };
}
macro_rules! opt_unsafe_extern_c_fn {
($($args:ident),* -> $ret:ident) => { Option<unsafe extern "C" fn($($args),*) -> $ret> };
}
macro_rules! opt_fn {
($($args:ident),* -> $ret:ident) => { Option<fn($($args),*) -> $ret> };
}
macro_rules! opt_unsafe_fn {
($($args:ident),* -> $ret:ident) => { Option<unsafe fn($($args),*) -> $ret> };
}
macro_rules! impl_or_verify {
(
const $constname:ident : $constty:ident $(,)?
$($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
=> $trait:ident for $ty:ty
) => {
impl_or_verify!(@impl { unsafe_impl!(
const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
); });
impl_or_verify!(@verify $trait, {
impl<const $constname: $constty, $($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
});
};
(
$($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),*
=> $trait:ident for $ty:ty $(; |$candidate:ident| $is_bit_valid:expr)?
) => {
impl_or_verify!(@impl { unsafe_impl!(
$($tyvar $(: $(? $optbound +)* $($bound +)*)?),* => $trait for $ty
$(; |$candidate| $is_bit_valid)?
); });
impl_or_verify!(@verify $trait, {
impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?),*> Subtrait for $ty {}
});
};
(@impl $impl_block:tt) => {
#[cfg(not(any(feature = "derive", test)))]
{ $impl_block };
};
(@verify $trait:ident, $impl_block:tt) => {
#[cfg(any(feature = "derive", test))]
{
#[allow(dead_code)]
trait Subtrait: $trait {}
$impl_block
};
};
}
macro_rules! impl_known_layout {
($(const $constvar:ident : $constty:ty, $tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
$(impl_known_layout!(@inner const $constvar: $constty, $tyvar $(: ?$optbound)? => $ty);)*
};
($($tyvar:ident $(: ?$optbound:ident)? => $ty:ty),* $(,)?) => {
$(impl_known_layout!(@inner , $tyvar $(: ?$optbound)? => $ty);)*
};
($($(#[$attrs:meta])* $ty:ty),*) => { $(impl_known_layout!(@inner , => $(#[$attrs])* $ty);)* };
(@inner $(const $constvar:ident : $constty:ty)? , $($tyvar:ident $(: ?$optbound:ident)?)? => $(#[$attrs:meta])* $ty:ty) => {
const _: () = {
use core::ptr::NonNull;
#[allow(non_local_definitions)]
$(#[$attrs])*
unsafe impl<$($tyvar $(: ?$optbound)?)? $(, const $constvar : $constty)?> KnownLayout for $ty {
#[allow(clippy::missing_inline_in_public_items)]
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized {}
type PointerMetadata = ();
type MaybeUninit = core::mem::MaybeUninit<Self>;
const LAYOUT: crate::DstLayout = crate::DstLayout::for_type::<$ty>();
#[inline(always)]
fn raw_from_ptr_len(bytes: NonNull<u8>, _meta: ()) -> NonNull<Self> {
bytes.cast::<Self>()
}
#[inline(always)]
fn pointer_to_metadata(_ptr: *mut Self) -> () {
}
}
};
};
}
macro_rules! unsafe_impl_known_layout {
($($tyvar:ident: ?Sized + KnownLayout =>)? #[repr($repr:ty)] $ty:ty) => {{
use core::ptr::NonNull;
crate::util::macros::__unsafe();
#[allow(non_local_definitions)]
unsafe impl<$($tyvar: ?Sized + KnownLayout)?> KnownLayout for $ty {
#[allow(clippy::missing_inline_in_public_items, dead_code)]
#[cfg_attr(all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), coverage(off))]
fn only_derive_is_allowed_to_implement_this_trait() {}
type PointerMetadata = <$repr as KnownLayout>::PointerMetadata;
type MaybeUninit = <$repr as KnownLayout>::MaybeUninit;
const LAYOUT: DstLayout = <$repr as KnownLayout>::LAYOUT;
#[inline(always)]
fn raw_from_ptr_len(bytes: NonNull<u8>, meta: <$repr as KnownLayout>::PointerMetadata) -> NonNull<Self> {
#[allow(clippy::as_conversions)]
let ptr = <$repr>::raw_from_ptr_len(bytes, meta).as_ptr() as *mut Self;
unsafe { NonNull::new_unchecked(ptr) }
}
#[inline(always)]
fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
#[allow(clippy::as_conversions)]
let ptr = ptr as *mut $repr;
<$repr>::pointer_to_metadata(ptr)
}
}
}};
}
macro_rules! assert_unaligned {
($($tys:ty),*) => {
$(
#[cfg(test)]
static_assertions::const_assert_eq!(core::mem::align_of::<$tys>(), 1);
)*
};
}
macro_rules! maybe_const_trait_bounded_fn {
($(#[$attr:meta])* $vis:vis const fn $name:ident($($args:ident $(: $arg_tys:ty)?),* $(,)?) $(-> $ret_ty:ty)? $body:block) => {
#[cfg(not(no_zerocopy_generic_bounds_in_const_fn_1_61_0))]
$(#[$attr])* $vis const fn $name($($args $(: $arg_tys)?),*) $(-> $ret_ty)? $body
#[cfg(no_zerocopy_generic_bounds_in_const_fn_1_61_0)]
$(#[$attr])* $vis fn $name($($args $(: $arg_tys)?),*) $(-> $ret_ty)? $body
};
}
macro_rules! const_panic {
(@non_panic $($_arg:tt)+) => {{
let panic: [_; 0] = [];
#[allow(unconditional_panic)]
panic[0]
}};
($($arg:tt)+) => {{
#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
panic!($($arg)+);
#[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
const_panic!(@non_panic $($arg)+)
}};
}
macro_rules! const_assert {
($e:expr) => {{
#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
assert!($e);
#[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
{
let e = $e;
if !e {
let _: () = const_panic!(@non_panic concat!("assertion failed: ", stringify!($e)));
}
}
}};
($e:expr, $($args:tt)+) => {{
#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
assert!($e, $($args)+);
#[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
{
let e = $e;
if !e {
let _: () = const_panic!(@non_panic concat!("assertion failed: ", stringify!($e), ": ", stringify!($arg)), $($args)*);
}
}
}};
}
macro_rules! const_debug_assert {
($e:expr $(, $msg:expr)?) => {{
#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
debug_assert!($e $(, $msg)?);
#[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
{
if cfg!(debug_assertions) {
let e = $e;
if !e {
let _: () = const_panic!(@non_panic concat!("assertion failed: ", stringify!($e) $(, ": ", $msg)?));
}
}
}
}}
}
macro_rules! const_unreachable {
() => {{
#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
unreachable!();
#[cfg(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
loop {}
}};
}
macro_rules! static_assert {
(Self $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )? => $condition:expr $(, $args:tt)*) => {{
trait StaticAssert {
const ASSERT: bool;
}
impl<T $(: $(? $optbound +)* $($bound +)*)?> StaticAssert for T {
const ASSERT: bool = {
const_assert!($condition $(, $args)*);
$condition
};
}
const_assert!(<Self as StaticAssert>::ASSERT);
}};
($($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?),* => $condition:expr $(, $args:tt)*) => {{
trait StaticAssert {
const ASSERT: bool;
}
impl<$($tyvar $(: $(? $optbound +)* $($bound +)*)?,)*> StaticAssert for ($(core::marker::PhantomData<$tyvar>,)*) {
const ASSERT: bool = {
const_assert!($condition $(, $args)*);
$condition
};
}
const_assert!(<($(core::marker::PhantomData<$tyvar>,)*) as StaticAssert>::ASSERT);
}};
}
macro_rules! static_assert_dst_is_not_zst {
($tyvar:ident) => {{
use crate::KnownLayout;
static_assert!($tyvar: ?Sized + KnownLayout => {
let dst_is_zst = match $tyvar::LAYOUT.size_info {
crate::SizeInfo::Sized { .. } => false,
crate::SizeInfo::SliceDst(TrailingSliceLayout { elem_size, .. }) => {
elem_size == 0
}
};
!dst_is_zst
}, "cannot call this method on a dynamically-sized type whose trailing slice element is zero-sized");
}}
}
#[macro_export]
#[doc(hidden)]
macro_rules! define_cast {
(unsafe { $vis:vis $name:ident $(<$tyvar:ident $(: ?$optbound:ident)?>)? = $src:ty => $dst:ty }) => {
#[allow(missing_debug_implementations, missing_copy_implementations, unreachable_pub)]
$vis enum $name {}
unsafe impl $(<$tyvar $(: ?$optbound)?>)? $crate::pointer::cast::Project<$src, $dst> for $name {
fn project(src: $crate::pointer::PtrInner<'_, $src>) -> *mut $dst {
#[allow(clippy::as_conversions)]
return src.as_ptr() as *mut $dst;
}
}
unsafe impl $(<$tyvar $(: ?$optbound)?>)? $crate::pointer::cast::Cast<$src, $dst> for $name {}
};
}
macro_rules! unsafe_impl_for_transparent_wrapper {
($vis:vis T $(: ?$optbound:ident)? => $wrapper:ident<T>) => {{
crate::util::macros::__unsafe();
use crate::pointer::{TransmuteFrom, SizeEq, invariant::Valid};
unsafe impl<T $(: ?$optbound)?> TransmuteFrom<T, Valid, Valid> for $wrapper<T> {}
unsafe impl<T $(: ?$optbound)?> TransmuteFrom<$wrapper<T>, Valid, Valid> for T {}
define_cast!(unsafe { $vis CastA<T $(: ?$optbound)? > = T => $wrapper<T> });
unsafe impl<T $(: ?$optbound)?> SizeEq<T> for $wrapper<T> {
type CastFrom = CastA;
}
define_cast!(unsafe { $vis CastB<T $(: ?$optbound)? > = $wrapper<T> => T });
unsafe impl<T $(: ?$optbound)?> SizeEq<$wrapper<T>> for T {
type CastFrom = CastB;
}
}};
}
macro_rules! impl_transitive_transmute_from {
($($tyvar:ident $(: ?$optbound:ident)?)? => $t:ty => $u:ty => $v:ty) => {
const _: () = {
use crate::pointer::{TransmuteFrom, SizeEq, invariant::Valid};
unsafe impl<$($tyvar $(: ?$optbound)?)?> SizeEq<$t> for $v
where
$u: SizeEq<$t>,
$v: SizeEq<$u>,
{
type CastFrom = cast::TransitiveProject<
$u,
<$u as SizeEq<$t>>::CastFrom,
<$v as SizeEq<$u>>::CastFrom
>;
}
unsafe impl<$($tyvar $(: ?$optbound)?)?> TransmuteFrom<$t, Valid, Valid> for $v
where
$u: TransmuteFrom<$t, Valid, Valid>,
$v: TransmuteFrom<$u, Valid, Valid>,
{}
};
};
}
#[rustfmt::skip]
macro_rules! impl_size_eq {
($t:ty, $u:ty) => {
const _: () = {
use $crate::{pointer::{cast::CastUnsized, SizeEq}};
unsafe impl SizeEq<$t> for $u {
type CastFrom = CastUnsized;
}
unsafe impl SizeEq<$u> for $t {
type CastFrom = CastUnsized;
}
};
};
}
macro_rules! unsafe_with_size_eq {
(<$src:ident<$t:ident>, $dst:ident<$u:ident>> $blk:expr) => {{
crate::util::macros::__unsafe();
use crate::{KnownLayout, pointer::cast::TransitiveProject};
#[repr(transparent)]
struct $src<T: ?Sized>(T);
#[repr(transparent)]
struct $dst<U: ?Sized>(U);
unsafe_impl_for_transparent_wrapper!(T: ?Sized => $src<T>);
unsafe_impl_for_transparent_wrapper!(T: ?Sized => $dst<T>);
unsafe impl<T: ?Sized> InvariantsEq<$src<T>> for T {}
unsafe impl<T: ?Sized> InvariantsEq<$dst<T>> for T {}
define_cast!(unsafe { SrcCast<T: ?Sized> = $src<T> => T });
define_cast!(unsafe { DstCast<U: ?Sized> = U => $dst<U> });
unsafe impl<T: ?Sized, U: ?Sized> SizeEq<$src<T>> for $dst<U>
where
T: KnownLayout<PointerMetadata = usize>,
U: KnownLayout<PointerMetadata = usize>,
{
type CastFrom = TransitiveProject<U, TransitiveProject<
T,
SrcCast,
crate::layout::CastFrom<U>,
>, DstCast>;
}
if 1 == 0 {
use crate::pointer::cast::Project as _;
let ptr = <$t as KnownLayout>::raw_dangling();
#[allow(unused_unsafe, clippy::missing_transmute_annotations)]
let ptr = unsafe { core::mem::transmute(ptr) };
let _ = <$dst<$u> as SizeEq<$src<$t>>>::CastFrom::project(ptr);
}
impl_for_transmute_from!(T: ?Sized + TryFromBytes => TryFromBytes for $src<T>[<T>]);
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for $src<T>[<T>]);
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for $src<T>[<T>]);
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for $src<T>[<T>]);
impl_for_transmute_from!(U: ?Sized + TryFromBytes => TryFromBytes for $dst<U>[<U>]);
impl_for_transmute_from!(U: ?Sized + FromBytes => FromBytes for $dst<U>[<U>]);
impl_for_transmute_from!(U: ?Sized + FromZeros => FromZeros for $dst<U>[<U>]);
impl_for_transmute_from!(U: ?Sized + IntoBytes => IntoBytes for $dst<U>[<U>]);
unsafe_impl!(T: ?Sized + Immutable => Immutable for $src<T>);
unsafe_impl!(T: ?Sized + Immutable => Immutable for $dst<T>);
$blk
}};
}
#[inline(always)]
pub(crate) const unsafe fn __unsafe() {}