devela/sys/mem/size/expr/
mod.rs
1#[doc(hidden)]
8pub const fn __size_of_expr<T>(_zero_len_fn_ptr_array: [impl FnOnce() -> [T; 0]; 0]) -> usize {
9 crate::Mem::size_of::<T>()
10}
11
12#[doc = crate::doc_!(vendor: "size_of_trait")]
31#[macro_export]
32#[cfg_attr(cargo_primary_package, doc(hidden))]
33macro_rules! size_of_expr {
34 ($expr: expr) => {
35 $crate::sys::mem::__size_of_expr(
36 if true {
39 []
40 } else {
41 #[cfg(any(feature = "safe_mem", not(feature = "unsafe_hint")))]
42 loop {}
43 #[cfg(all(not(feature = "safe_mem"), feature = "unsafe_hint"))]
44 unsafe {
45 $crate::unreachable_unchecked()
46 }
47
48 #[expect(unreachable_code, reason = "avoid evaluating this branch")]
49 {
50 [|| [$expr; 0]; 0]
51 }
52 },
53 )
54 };
55}
56#[doc(inline)]
57pub use size_of_expr;
58
59#[cfg(all(test, feature = "nightly_coro", feature = "alloc"))]
63mod test_coro;
64
65#[cfg(test)]
66mod tests {
67 use super::size_of_expr;
68
69 async fn f() {
70 let _x = 1;
71 core::future::ready(()).await;
72 let _y = 2;
73 }
74
75 #[test]
76 fn api() {
77 const C: usize = size_of_expr!(f());
78 const D: usize = size_of_expr!(0_u8);
79 const E: usize = size_of_expr!(());
80 const F: usize = size_of_expr!(0_usize);
81
82 assert_eq!(C, 2);
83 assert_eq!(D, 1);
84 assert_eq!(E, 0);
85 assert_eq!(F, size_of::<usize>());
86 }
87
88 #[test]
89 fn edge_cases() {
90 const _: [(); size_of_expr!(&Some(42))] = [(); size_of::<*const ()>()];
92 let _ = size_of_expr!(&Some(42));
93
94 #[allow(dropping_copy_types)]
96 const _: [(); size_of_expr!(Some(drop(())).as_ref())] = [(); size_of::<*const ()>()];
97 #[allow(dropping_copy_types)]
98 let _ = size_of_expr!(Some(drop(())).as_ref());
99
100 struct NotCopy {}
102 let it = NotCopy {};
103 assert_eq!(size_of_expr!(it), 0);
104 drop(it);
105
106 let mut it = ();
108 let r = &mut it;
109 assert_eq!(size_of_expr!(it), 0);
110 #[allow(dropping_references)]
111 drop(r);
112 }
113}