#[doc(hidden)]
pub const fn __size_of_expr<T>(_zero_len_fn_ptr_array: [impl FnOnce() -> [T; 0]; 0]) -> usize {
crate::Mem::size_of::<T>()
}
#[doc = crate::_tags!(code mem)]
#[doc = crate::_doc_location!("sys/mem")]
#[doc = crate::_doc!(vendor: "size_of_trait")]
#[macro_export]
#[cfg_attr(cargo_primary_package, doc(hidden))]
macro_rules! size_of_expr {
($expr: expr) => {
$crate::sys::mem::__size_of_expr(
if true {
[]
} else {
#[cfg(any(feature = "safe_mem", not(feature = "unsafe_hint")))]
loop {}
#[cfg(all(not(feature = "safe_mem"), feature = "unsafe_hint"))]
unsafe {
$crate::unreachable_unchecked()
}
#[expect(unreachable_code, reason = "avoid evaluating this branch")]
{
[|| [$expr; 0]; 0]
}
},
)
};
}
#[doc(inline)]
pub use size_of_expr;
#[cfg(all(test, nightly_coro))]
mod test_coro;
#[cfg(test)]
mod tests {
async fn f() {
let _x = 1;
core::future::ready(()).await;
let _y = 2;
}
#[test]
fn api() {
const C: usize = size_of_expr!(f());
const D: usize = size_of_expr!(0_u8);
const E: usize = size_of_expr!(());
const F: usize = size_of_expr!(0_usize);
assert_eq!(C, 2);
assert_eq!(D, 1);
assert_eq!(E, 0);
assert_eq!(F, size_of::<usize>());
}
#[test]
fn edge_cases() {
const _: [(); size_of_expr!(&Some(42))] = [(); size_of::<*const ()>()];
let _ = size_of_expr!(&Some(42));
#[allow(dropping_copy_types)]
const _: [(); size_of_expr!(Some(drop(())).as_ref())] = [(); size_of::<*const ()>()];
#[allow(dropping_copy_types)]
let _ = size_of_expr!(Some(drop(())).as_ref());
struct NotCopy {}
let it = NotCopy {};
assert_eq!(size_of_expr!(it), 0);
drop(it);
let mut it = ();
let r = &mut it;
assert_eq!(size_of_expr!(it), 0);
#[allow(dropping_references)]
drop(r);
}
}