monoio/macros/pin.rs
1/// Pins a value on the stack.
2///
3/// Calls to `async fn` return anonymous [`Future`] values that are `!Unpin`.
4/// These values must be pinned before they can be polled. Calling `.await` will
5/// handle this, but consumes the future. If it is required to call `.await` on
6/// a `&mut _` reference, the caller is responsible for pinning the future.
7///
8/// Pinning may be done by allocating with [`Box::pin`] or by using the stack
9/// with the `pin!` macro.
10///
11/// The following will **fail to compile**:
12///
13/// ```compile_fail
14/// use monoio::pin;
15/// async fn my_async_fn() {
16/// // async logic here
17/// }
18///
19/// #[monoio::main]
20/// async fn main() {
21/// let mut future = pin!(my_async_fn());
22/// (&mut future).await;
23/// }
24/// ```
25///
26/// To make this work requires pinning:
27///
28/// ```
29/// use monoio::pin;
30///
31/// async fn my_async_fn() {
32/// // async logic here
33/// }
34///
35/// #[monoio::main]
36/// async fn main() {
37/// let future = my_async_fn();
38/// pin!(future);
39///
40/// (&mut future).await;
41/// }
42/// ```
43///
44/// Pinning is useful when using `select!` and stream operators that require `T:
45/// Stream + Unpin`.
46///
47/// [`Future`]: trait@std::future::Future
48/// [`Box::pin`]: std::boxed::Box::pin
49///
50/// # Usage
51///
52/// The `pin!` macro takes **identifiers** as arguments. It does **not** work
53/// with expressions.
54///
55/// The following does not compile as an expression is passed to `pin!`.
56///
57/// ```compile_fail
58/// use monoio::pin;
59/// async fn my_async_fn() {
60/// // async logic here
61/// }
62///
63/// #[monoio::main]
64/// async fn main() {
65/// let mut future = pin!(my_async_fn());
66/// (&mut future).await;
67/// }
68/// ```
69///
70/// Because assigning to a variable followed by pinning is common, there is also
71/// a variant of the macro that supports doing both in one go.
72///
73/// ```
74/// use monoio::{pin, select};
75///
76/// async fn my_async_fn() {
77/// // async logic here
78/// }
79///
80/// #[monoio::main]
81/// async fn main() {
82/// pin! {
83/// let future1 = my_async_fn();
84/// let future2 = my_async_fn();
85/// }
86///
87/// select! {
88/// _ = &mut future1 => {}
89/// _ = &mut future2 => {}
90/// }
91/// }
92/// ```
93#[deprecated(note = "use std::pin::pin instead")]
94#[macro_export]
95macro_rules! pin {
96 ($($x:ident),*) => { $(
97 // Move the value to ensure that it is owned
98 let mut $x = $x;
99 // Shadow the original binding so that it can't be directly accessed
100 // ever again.
101 #[allow(unused_mut)]
102 let mut $x = unsafe {
103 $crate::macros::support::Pin::new_unchecked(&mut $x)
104 };
105 )* };
106 ($(
107 let $x:ident = $init:expr;
108 )*) => {
109 $(
110 let $x = $init;
111 $crate::pin!($x);
112 )*
113 };
114}