• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// async fn my_async_fn() {
15 ///     // async logic here
16 /// }
17 ///
18 /// #[tokio::main]
19 /// async fn main() {
20 ///     let mut future = my_async_fn();
21 ///     (&mut future).await;
22 /// }
23 /// ```
24 ///
25 /// To make this work requires pinning:
26 ///
27 /// ```
28 /// use tokio::pin;
29 ///
30 /// async fn my_async_fn() {
31 ///     // async logic here
32 /// }
33 ///
34 /// #[tokio::main]
35 /// async fn main() {
36 ///     let future = my_async_fn();
37 ///     pin!(future);
38 ///
39 ///     (&mut future).await;
40 /// }
41 /// ```
42 ///
43 /// Pinning is useful when using `select!` and stream operators that require `T:
44 /// Stream + Unpin`.
45 ///
46 /// [`Future`]: trait@std::future::Future
47 /// [`Box::pin`]: std::boxed::Box::pin
48 ///
49 /// # Usage
50 ///
51 /// The `pin!` macro takes **identifiers** as arguments. It does **not** work
52 /// with expressions.
53 ///
54 /// The following does not compile as an expression is passed to `pin!`.
55 ///
56 /// ```compile_fail
57 /// async fn my_async_fn() {
58 ///     // async logic here
59 /// }
60 ///
61 /// #[tokio::main]
62 /// async fn main() {
63 ///     let mut future = pin!(my_async_fn());
64 ///     (&mut future).await;
65 /// }
66 /// ```
67 ///
68 /// # Examples
69 ///
70 /// Using with select:
71 ///
72 /// ```
73 /// use tokio::{pin, select};
74 /// use tokio_stream::{self as stream, StreamExt};
75 ///
76 /// async fn my_async_fn() {
77 ///     // async logic here
78 /// }
79 ///
80 /// #[tokio::main]
81 /// async fn main() {
82 ///     let mut stream = stream::iter(vec![1, 2, 3, 4]);
83 ///
84 ///     let future = my_async_fn();
85 ///     pin!(future);
86 ///
87 ///     loop {
88 ///         select! {
89 ///             _ = &mut future => {
90 ///                 // Stop looping `future` will be polled after completion
91 ///                 break;
92 ///             }
93 ///             Some(val) = stream.next() => {
94 ///                 println!("got value = {}", val);
95 ///             }
96 ///         }
97 ///     }
98 /// }
99 /// ```
100 ///
101 /// Because assigning to a variable followed by pinning is common, there is also
102 /// a variant of the macro that supports doing both in one go.
103 ///
104 /// ```
105 /// use tokio::{pin, select};
106 ///
107 /// async fn my_async_fn() {
108 ///     // async logic here
109 /// }
110 ///
111 /// #[tokio::main]
112 /// async fn main() {
113 ///     pin! {
114 ///         let future1 = my_async_fn();
115 ///         let future2 = my_async_fn();
116 ///     }
117 ///
118 ///     select! {
119 ///         _ = &mut future1 => {}
120 ///         _ = &mut future2 => {}
121 ///     }
122 /// }
123 /// ```
124 #[macro_export]
125 macro_rules! pin {
126     ($($x:ident),*) => { $(
127         // Move the value to ensure that it is owned
128         let mut $x = $x;
129         // Shadow the original binding so that it can't be directly accessed
130         // ever again.
131         #[allow(unused_mut)]
132         let mut $x = unsafe {
133             $crate::macros::support::Pin::new_unchecked(&mut $x)
134         };
135     )* };
136     ($(
137             let $x:ident = $init:expr;
138     )*) => {
139         $(
140             let $x = $init;
141             $crate::pin!($x);
142         )*
143     };
144 }
145