1#[doc(hidden)]
2pub const fn __manually_drop_inner_ref<T>(slot: &core::mem::ManuallyDrop<T>) -> &T {
4 unsafe { core::mem::transmute(slot) }
6}
7
8#[macro_export]
9macro_rules! const_destructure {
10 (let $S:path { $($field_spec:tt)* } = $value:expr) => {
12 $crate::const_destructure!(@struct ($($field_spec)*) => let $S {} = $value);
13 };
14 (let ($($var:pat_param),* $(,)?) = $value:expr) => {
16 $crate::const_destructure!(@tuple ($($var),*); (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => (); let () = $value);
17 };
18 (@struct ()
19 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
20 ) => {
21 let value = $value;
22 let __destructures_all_fields_and_fields_are_unique = || {
23 let $S { $($field: _),* } = &value;
24 };
25 let value = ::core::mem::ManuallyDrop::new(value);
26 let value = $crate::__manually_drop_inner_ref(&value);
27 $(
29 let $var = unsafe { ::core::ptr::addr_of!(value.$field).read() };
30 )*
31 };
32 (@struct ($next_field:ident: $next_var:pat_param $(,)?)
33 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
34 ) => {
35 $crate::const_destructure!(@struct () => let $S { $($field: $var,)* $next_field: $next_var } = $value);
36 };
37 (@struct ($next_field:ident $(,)?)
38 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
39 ) => {
40 $crate::const_destructure!(@struct () => let $S { $($field: $var,)* $next_field: $next_field } = $value);
41 };
42 (@struct ($next_field:ident: $next_var:pat_param, $($rest:tt)*)
43 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
44 ) => {
45 $crate::const_destructure!(@struct ($($rest)*) => let $S { $($field: $var,)* $next_field: $next_var } = $value);
46 };
47 (@struct ($next_field:ident, $($rest:tt)*)
48 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
49 ) => {
50 $crate::const_destructure!(@struct ($($rest)*) => let $S { $($field: $var,)* $next_field: $next_field } = $value);
51 };
52 (@tuple (); ($($index_rest:tt),*)
53 => ($($ty:tt),*); let ($($index:tt: $var:pat_param),*) = $value:expr
54 ) => {
55 let value: ($($ty,)*) = $value; let value = ::core::mem::ManuallyDrop::new(value);
57 let value = $crate::__manually_drop_inner_ref(&value);
58 $(
60 let $var = unsafe { ::core::ptr::addr_of!(value.$index).read() };
61 )*
62 };
63 (@tuple ($var_head:pat_param $(,$var_tail:pat_param)*); ()
64 => ($($ty:tt),*); let ($($index:tt: $var:pat_param),*) = $value:expr
65 ) => {
66 compile_error!("tuple arity is larger than the maximum supported arity 12")
67 };
68 (@tuple ($var_head:pat_param $(,$var_tail:pat_param)*); ($index_head:tt $(,$index_tail:tt)*)
69 => ($($ty:tt),*); let ($($index:tt: $var:pat_param),*) = $value:expr
70 ) => {
71 $crate::const_destructure!(@tuple ($($var_tail),*); ($($index_tail),*) => ($($ty,)* _); let ($($index: $var,)* $index_head: $var_head) = $value);
72 };
73}