1#![no_std]
2
3#[doc(hidden)]
5pub const fn __manually_drop_inner_ref<T>(slot: &core::mem::ManuallyDrop<T>) -> &T {
6 unsafe { ::core::mem::transmute(slot) }
8}
9
10#[doc(hidden)]
12pub const fn __unimplemented_to_owned<T>(_: &T) -> T {
13 panic!("no valid implementation exists for this function and it should not be invoked")
14}
15
16#[macro_export]
17macro_rules! const_destructure {
18 (let $S:path { $($field_spec:tt)* } = $value:expr) => {
20 $crate::const_destructure!(@struct ($($field_spec)*) => let $S {} = $value);
21 };
22 (let ($($var:pat_param),* $(,)?) = $value:expr) => {
24 $crate::const_destructure!(@tuple ($($var),*); (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) => (); let () = $value);
25 };
26 (@struct ()
27 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
28 ) => {
29 let value = $value;
30 let value = ::core::mem::ManuallyDrop::new(value);
31 let value = $crate::__manually_drop_inner_ref(&value);
32 let __assert_valid_destructure = || {
33 #[allow(unused)]
34 let $S { $($field: $var),* } = $crate::__unimplemented_to_owned(value);
35 };
36 $(
38 let $var = unsafe { ::core::ptr::addr_of!(value.$field).read() };
39 )*
40 };
41 (@struct ($next_field:ident: $next_var:pat_param $(,)?)
42 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
43 ) => {
44 $crate::const_destructure!(@struct () => let $S { $($field: $var,)* $next_field: $next_var } = $value);
45 };
46 (@struct ($next_field:ident $(,)?)
47 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
48 ) => {
49 $crate::const_destructure!(@struct () => let $S { $($field: $var,)* $next_field: $next_field } = $value);
50 };
51 (@struct ($next_field:ident: $next_var:pat_param, $($rest:tt)*)
52 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
53 ) => {
54 $crate::const_destructure!(@struct ($($rest)*) => let $S { $($field: $var,)* $next_field: $next_var } = $value);
55 };
56 (@struct ($next_field:ident, $($rest:tt)*)
57 => let $S:path { $($field:ident: $var:pat_param),* } = $value:expr
58 ) => {
59 $crate::const_destructure!(@struct ($($rest)*) => let $S { $($field: $var,)* $next_field: $next_field } = $value);
60 };
61 (@tuple (); ($($index_rest:tt),*)
62 => ($($ty:tt),*); let ($($index:tt: $var:pat_param),*) = $value:expr
63 ) => {
64 let value: ($($ty,)*) = $value; let value = ::core::mem::ManuallyDrop::new(value);
66 let value = $crate::__manually_drop_inner_ref(&value);
67 $(
69 let $var = unsafe { ::core::ptr::addr_of!(value.$index).read() };
70 )*
71 };
72 (@tuple ($var_head:pat_param $(,$var_tail:pat_param)*); ()
73 => ($($ty:tt),*); let ($($index:tt: $var:pat_param),*) = $value:expr
74 ) => {
75 compile_error!("tuple arity is larger than the maximum supported arity 12")
76 };
77 (@tuple ($var_head:pat_param $(,$var_tail:pat_param)*); ($index_head:tt $(,$index_tail:tt)*)
78 => ($($ty:tt),*); let ($($index:tt: $var:pat_param),*) = $value:expr
79 ) => {
80 $crate::const_destructure!(@tuple ($($var_tail),*); ($($index_tail),*) => ($($ty,)* _); let ($($index: $var,)* $index_head: $var_head) = $value);
81 };
82}