1#[macro_export]
14macro_rules! assume {
15 (false) => {
16 assume!(false, "assumption failed")
17 };
18 (false $(, $fmtarg:expr)* $(,)?) => {{
19 if cfg!(not(debug_assertions)) {
20 core::hint::unreachable_unchecked();
21 }
22
23 panic!($($fmtarg),*)
24 }};
25 ($cond:expr) => {
26 $crate::assume!($cond, "assumption failed: {}", stringify!($cond));
27 };
28 ($cond:expr $(, $fmtarg:expr)* $(,)?) => {
29 let v = $cond;
30
31 debug_assert!(v $(, $fmtarg)*);
32 if cfg!(not(debug_assertions)) && !v {
33 core::hint::unreachable_unchecked();
34 }
35 };
36}
37
38#[macro_export]
39#[doc(hidden)]
40macro_rules! __tracing_noop__ {
41 ($($fmt:tt)*) => {};
42}
43
44#[doc(hidden)]
45#[cfg(feature = "branch-tracing")]
46pub use tracing::trace as _trace_branch;
47
48#[doc(hidden)]
49#[cfg(not(feature = "branch-tracing"))]
50pub use __tracing_noop__ as _trace_branch;
51
52#[macro_export]
54macro_rules! branch {
55 ($cond:expr) => {{
56 let result = $cond;
57 $crate::macros::_trace_branch!(
58 branch = stringify!($cond),
59 result,
60 file = file!(),
61 line = line!(),
62 );
63 result
64 }};
65 ($cond:expr, $outcome:expr) => {
66 $crate::branch!($cond, stringify!($cond), stringify!($outcome))
67 };
68 ($cond:expr, $branch:expr, $outcome:expr) => {{
69 let result = $cond;
70 if result {
71 $crate::macros::_trace_branch!(
72 branch = $branch,
73 result,
74 file = file!(),
75 line = line!(),
76 );
77 } else {
78 $crate::macros::_trace_branch!(
79 branch = $branch,
80 result,
81 outcome = $outcome,
82 file = file!(),
83 line = line!(),
84 );
85 }
86 result
87 }};
88}
89
90#[macro_export]
91macro_rules! ready {
92 ($expr:expr) => {
93 match $expr {
94 ::core::task::Poll::Pending => {
95 $crate::branch!(false, stringify!($expr), "return Poll::Pending");
96 return ::core::task::Poll::Pending;
97 }
98 ::core::task::Poll::Ready(v) => {
99 $crate::branch!(true, stringify!($expr), "");
100 v
101 }
102 }
103 };
104}
105
106#[macro_export]
108macro_rules! ensure {
109 (let $pat:pat = $expr:expr, continue) => {
110 let $pat = $expr else {
111 $crate::branch!(false, stringify!(let $pat = $expr), stringify!(continue));
112 continue;
113 };
114 $crate::branch!(true, stringify!(let $pat = $expr), "");
115 };
116 (let $pat:pat = $expr:expr, break $($ret:expr)?) => {
117 let $pat = $expr else {
118 $crate::branch!(false, stringify!(let $pat = $expr), stringify!(break $($ret)?));
119 break $($ret)?;
120 };
121 $crate::branch!(true, stringify!(let $pat = $expr), "");
122 };
123 (let $pat:pat = $expr:expr, return $($ret:expr)?) => {
124 let $pat = $expr else {
125 $crate::branch!(false, stringify!(let $pat = $expr), stringify!(return $($ret)?));
126 return $($ret)?;
127 };
128 $crate::branch!(true, stringify!(let $pat = $expr), "");
129 };
130 (let $pat:pat = $expr:expr $(, $ret:expr)?) => {
131 $crate::ensure!(let $pat = $expr, return $($ret)?)
132 };
133 ($cond:expr, continue) => {
134 if !$crate::branch!($cond, continue) {
135 continue;
136 }
137 };
138 ($cond:expr, break $($expr:expr)?) => {
139 if !$crate::branch!($cond, break $($expr)?) {
140 break $($expr)?;
141 }
142 };
143 ($cond:expr, return $($expr:expr)?) => {
144 if !$crate::branch!($cond, return $($expr)?) {
145 return $($expr)?;
146 }
147 };
148 ($cond:expr $(, $ret:expr)?) => {
149 $crate::ensure!($cond, return $($ret)?);
150 };
151}
152
153macro_rules! impl_ready_future {
155 ($name:ident, $fut:ident, $output:ty) => {
156 pub struct $fut<'a, T: ?Sized>(&'a mut T);
157
158 impl<'a, T: $name> core::future::Future for $fut<'a, T> {
159 type Output = $output;
160
161 #[inline]
162 fn poll(
163 mut self: core::pin::Pin<&mut Self>,
164 cx: &mut core::task::Context,
165 ) -> core::task::Poll<Self::Output> {
166 self.0.poll_ready(cx)
167 }
168 }
169 };
170}