maybe_borrow/macros/
mod.rs

1// MARK: Docs
2
3#[cfg(doc)]
4/// Runs the given block, either returning a value borrowing data from `$ptr`'s target, or
5/// continuing by evaluating to a non-borrowing value.
6///
7#[doc = include_str!("./maybe_borrow.md")]
8#[macro_export]
9macro_rules! maybe_borrow {
10    ( $(for<$lt:lifetime>)? |$($ptr:ident),*| -> $Ret:ty $block:block ) => {
11        todo!()
12    };
13}
14
15#[cfg(doc)]
16#[doc = include_str!("./try_maybe_borrow.md")]
17#[macro_export]
18macro_rules! try_maybe_borrow {
19    ( $(for<$lt:lifetime>)? |$($ptr:ident),*| -> $Ret:ty $block:block ) => {
20        todo!()
21    };
22}
23
24#[cfg(doc)]
25#[macro_export]
26/// Return from the containing function with potentially borrowed data from within a
27/// [`maybe_borrow`] or [`try_maybe_borrow`] invocation.
28///
29/// This macro is only available within the aforementioned macros.
30macro_rules! return_borrowed {
31    ($return_value:expr) => {};
32}
33
34#[cfg(doc)]
35#[macro_export]
36/// Behaves like [`core::task::ready!`], but uses [`return_borrowed!`] rather than `return` so it can be used within [`maybe_borrow!`] or [`try_maybe_borrow!`].
37///
38/// This macro is only available within the aforementioned macros.
39macro_rules! ready {
40    ($return_value:expr) => {};
41}
42
43#[cfg(doc)]
44pub use return_borrowed;
45
46// MARK: Public
47
48/// Runs the given block, either returning a value borrowing data from `$ptr`'s target, or
49/// continuing by evaluating to a non-borrowing value.
50///
51#[cfg(not(doc))]
52#[doc = include_str!("./maybe_borrow.md")]
53#[macro_export]
54macro_rules! maybe_borrow {
55    ($(for<$($lt:lifetime),* $(,)?>)? |$($ptr:ident),+ $(,)?| -> $Ret:ty $block:block $(,)?) => {{
56        $crate::_m::__maybe_borrow! {
57            $Ret,
58            [$($($lt)*)?],
59            |[$($ptr)+]| { $crate::_m::ControlFlow::Continue({
60                $crate::_m::__import_contextual_macros! { __return_borrowed, $block }
61            }) }
62        }
63    }};
64
65    ($(for<$lt:lifetime $(,)?>)? |$ptr:ident $(,)?| $block:expr $(,)?) => {
66        $crate::_m::compile_error!("Explicit return type required in maybe_borrow!");
67    }
68
69}
70
71pub use maybe_borrow;
72
73#[cfg(not(doc))]
74#[doc = include_str!("./try_maybe_borrow.md")]
75#[macro_export]
76macro_rules! try_maybe_borrow {
77    ($(for<$lt:lifetime $(,)?>)? |$($ptr:ident),+ $(,)?| -> $Ret:ty $block:block $(,)?) => {
78        $crate::_m::__maybe_borrow! {
79            $Ret,
80            [$($lt)?],
81            |[$($ptr)+]| { $crate::_m::try_maybe_borrow_helper(|w| w.wrap(
82                $crate::_m::__import_contextual_macros! { __return_borrowed_try, $block }
83            )) }
84        }
85    };
86
87    ($(for<$lt:lifetime $(,)?>)? |$ptr:ident $(,)?| $block:expr $(,)?) => {
88        $crate::_m::compile_error!("Explicit return type required in try_maybe_borrow!");
89    }
90}
91
92pub use try_maybe_borrow;
93
94// MARK: Internal
95
96#[doc(hidden)]
97#[macro_export]
98macro_rules! __actual_combined_with_lt {
99    (=> $Ret:ty) => { $Ret };
100    ($lt0:lifetime $($lt:lifetime)* => $Ret:ty) => {
101        $crate::_m::Actual<
102            $crate::_m::WithLt![
103                $lt0 -> $crate::_m::__actual_combined_with_lt![$($lt)* => $Ret]
104            ]
105        >
106    };
107}
108
109pub use __actual_combined_with_lt;
110
111#[doc(hidden)]
112#[macro_export]
113macro_rules! __import_contextual_macros {
114    ($return_borrowed:ident, $block:expr) => {{
115        #[allow(unused)]
116        use $crate::_m::__ready as ready;
117        #[allow(unused)]
118        use $crate::_m::$return_borrowed as return_borrowed;
119        $block
120    }};
121}
122
123pub use __import_contextual_macros;
124
125#[doc(hidden)]
126#[macro_export]
127macro_rules! __maybe_borrow {
128    ($Ret:ty, $lt:tt, |$ptr:tt| $block:block) => {{
129        let _pairs = match $crate::_m::__maybe_borrow_nested! {
130            $Ret, [], $lt, [], |$ptr| $block
131        } {
132            $crate::_m::ControlFlow::Break(_ret) => return _ret,
133            $crate::_m::ControlFlow::Continue(_pairs) => _pairs,
134        };
135
136        let _out;
137
138        #[allow(unused_assignments)]
139        {
140            $crate::_m::__pointer_assign! { _out $lt $ptr <- _pairs }
141        }
142        _out
143    }};
144}
145
146pub use __maybe_borrow;
147
148#[doc(hidden)]
149#[macro_export]
150macro_rules! __maybe_borrow_nested {
151    // No arguments remaining:
152    ($Ret:ty, $past_lt:tt, $lt:tt, [$($all_ptrs:tt)*], |[]| $block:block) => {{
153        $(
154            let mut $all_ptrs = $all_ptrs.0;
155            $crate::_m::noop_use_mut(&mut $all_ptrs);
156        )*
157        $block
158    }};
159
160    // Only one lifetime parameter remaining:
161    (
162        $Ret:ty,
163        [$($past_lt:lifetime)*], [$($lt0:lifetime)?],
164        [$($past_ptrs:tt)*], |$ptr:tt| $block:block
165    ) => {
166            $crate::_m::maybe_borrow::<
167            _,
168            $crate::_m::WithLt![$($lt0 ->)? $crate::_m::__actual_combined_with_lt![
169                $($past_lt)* => $Ret
170            ]],
171            _,
172        >(
173            $crate::_m::__nest_pattern!(@input <- $ptr),
174            |$crate::_m::__nest_pattern!(@mut <- $ptr), _| {
175                $(
176                    let mut $past_ptrs = $past_ptrs.0;
177                    $crate::_m::noop_use_mut(&mut $past_ptrs);
178                )*
179                let _ = $crate::_m::__nest_pattern!(@noop_use_mut <- $ptr);
180                $block
181            },
182        )
183    };
184
185    (
186        $Ret:ty,
187        [$($past_lt:lifetime)*], [$lt0:lifetime $($lt:lifetime)+],
188        [$($past_ptrs:tt)*], |[$ptr0:ident $($ptr:ident)*]| $block:block
189    ) => {
190            $crate::_m::maybe_borrow::<
191            _,
192            $crate::_m::WithLt![$lt0 -> $crate::_m::__actual_combined_with_lt![
193                $($past_lt)* $($lt)* => $Ret
194            ]],
195            _,
196        >(
197            $ptr0,
198            |$ptr0, _| {
199                let $ptr0 = $crate::_m::ForceMove($ptr0);
200                $crate::_m::__maybe_borrow_nested! {
201                    $Ret,
202                    [$($past_lt)* $lt0], [$($lt)*],
203                    [$($past_ptrs)* $ptr0], |[ $($ptr)* ]| $block
204                }
205            },
206        )
207    };
208}
209
210pub use __maybe_borrow_nested;
211
212#[doc(hidden)]
213#[macro_export]
214macro_rules! __nest_pattern {
215    (@$type:tt <- [$arg0:tt $($arg:tt)+]) => {
216        (
217            $crate::_m::__nest_pattern!(@$type <- [$arg0]),
218            $crate::_m::__nest_pattern!(@$type <- [$($arg)+]),
219        )
220    };
221    (@input <- [$arg:tt]) => { $arg };
222    (@mut <- [$arg:tt]) => { mut $arg };
223    (@noop_use_mut <- [$arg:tt]) => { $crate::_m::noop_use_mut(&mut $arg) };
224    (@type:tt <- []) => { () };
225}
226
227pub use __nest_pattern;
228
229#[doc(hidden)]
230#[macro_export]
231macro_rules! __pointer_assign {
232    ( @final [$ptr0:ident $($ptr:ident)+] <- $value:expr) => {
233        let _value = $value;
234        $ptr0 = _value.0;
235        $crate::_m::__pointer_assign! { @final [$($ptr)*] <- _value.1 }
236    };
237    ( @final [$ptr0:ident] <- $value:expr) => {
238        $ptr0 = $value;
239    };
240    ( @final [] <- $value:expr) => {
241        () = $value;
242    };
243    ($out:ident [$($lt:lifetime)?] $ptr:tt <- $value:expr) => {
244        let (_out, _value) = $value;
245        $out = _out;
246        $crate::_m::__pointer_assign! { @final $ptr <- _value }
247    };
248    ($out:ident [$lt0:lifetime $($lt:lifetime)+] [$ptr0:ident $($ptr:ident)*] <- $value:expr) => {
249        let _value = $value;
250        $ptr0 = _value.1;
251        $crate::_m::__pointer_assign! { $out [$($lt)*] [$($ptr)*] <- _value.0 }
252    };
253    ($out:ident $lt:tt [] <- $value:expr) => {
254        compile_error!(stringify!($out $lt $x));
255        $out = $value;
256    };
257}
258
259pub use __pointer_assign;
260
261#[doc(hidden)]
262#[macro_export]
263macro_rules! __return_borrowed {
264    ($value:expr $(,)?) => {
265        return $crate::_m::ControlFlow::Break($value)
266    };
267}
268
269pub use __return_borrowed;
270
271#[doc(hidden)]
272#[macro_export]
273macro_rules! __return_borrowed_try {
274    ($value:expr $(,)?) => {
275        return $crate::_m::CustomTry::map_continue($value, $crate::_m::Break)
276    };
277}
278
279pub use __return_borrowed_try;
280
281#[doc(hidden)]
282#[macro_export]
283macro_rules! __ready {
284    ($value:expr $(,)?) => {
285        match $value {
286            $crate::_m::Poll::Ready(_value) => _value,
287            $crate::_m::Poll::Pending => return_borrowed!($crate::_m::Poll::Pending),
288        }
289    };
290}
291
292pub use __ready;