@@ -12,10 +12,10 @@ macro_rules! document_select_macro {
12
12
/// passed to `select!` must be `Unpin` and implement `FusedFuture`.
13
13
///
14
14
/// If an expression which yields a `Future` is passed to `select!`
15
- /// (e.g. an `async fn` call) instead of a `Future` directly the `Unpin`
15
+ /// (e.g. an `async fn` call) instead of a `Future` by name the `Unpin`
16
16
/// requirement is relaxed, since the macro will pin the resulting `Future`
17
17
/// on the stack. However the `Future` returned by the expression must
18
- /// still implement `FusedFuture`.
18
+ /// still implement `FusedFuture`. This difference is presented
19
19
///
20
20
/// Futures and streams which are not already fused can be fused using the
21
21
/// `.fuse()` method. Note, though, that fusing a future or stream directly
@@ -24,8 +24,9 @@ macro_rules! document_select_macro {
24
24
/// `select!`ing in a loop, users should take care to `fuse()` outside of
25
25
/// the loop.
26
26
///
27
- /// `select!` can select over futures with different output types, but each
28
- /// branch has to have the same return type.
27
+ /// `select!` can be used as an expression and will return the return
28
+ /// value of the selected branch. For this reason the return type of every
29
+ /// branch in a `select!` must be the same.
29
30
///
30
31
/// This macro is only usable inside of async functions, closures, and blocks.
31
32
/// It is also gated behind the `async-await` feature of this library, which is
@@ -63,11 +64,67 @@ macro_rules! document_select_macro {
63
64
/// # });
64
65
/// ```
65
66
///
67
+ /// As described earlier, `select` can directly select on expressions
68
+ /// which return `Future`s - even if those do not implement `Unpin`:
69
+ ///
70
+ /// ```
71
+ /// # futures::executor::block_on(async {
72
+ /// use futures::future::FutureExt;
73
+ /// use futures::select;
74
+ ///
75
+ /// // Calling the following async fn returns a Future which does not
76
+ /// // implement Unpin
77
+ /// async fn async_identity_fn(arg: usize) -> usize {
78
+ /// arg
79
+ /// }
80
+ ///
81
+ /// let res = select! {
82
+ /// a_res = async_identity_fn(62).fuse() => a_res + 1,
83
+ /// b_res = async_identity_fn(13).fuse() => b_res,
84
+ /// };
85
+ /// assert!(res == 63 || res == 12);
86
+ /// # });
87
+ /// ```
88
+ ///
89
+ /// If a similar async function is called outside of `select` to produce
90
+ /// a `Future`, the `Future` must be pinned in order to be able to pass
91
+ /// it to `select`. This can be achieved via `Box::pin` for pinning a
92
+ /// `Future` on the heap or the `pin_mut!` macro for pinning a `Future`
93
+ /// on the stack.
94
+ ///
95
+ /// ```
96
+ /// # futures::executor::block_on(async {
97
+ /// use futures::future::FutureExt;
98
+ /// use futures::select;
99
+ /// use pin_utils::pin_mut;
100
+ ///
101
+ /// // Calling the following async fn returns a Future which does not
102
+ /// // implement Unpin
103
+ /// async fn async_identity_fn(arg: usize) -> usize {
104
+ /// arg
105
+ /// }
106
+ ///
107
+ /// let fut_1 = async_identity_fn(1).fuse();
108
+ /// let fut_2 = async_identity_fn(2).fuse();
109
+ /// let mut fut_1 = Box::pin(fut_1); // Pins the Future on the heap
110
+ /// pin_mut!(fut_2); // Pins the Future on the stack
111
+ ///
112
+ /// let res = select! {
113
+ /// a_res = fut_1 => a_res,
114
+ /// b_res = fut_2 => b_res,
115
+ /// };
116
+ /// assert!(res == 1 || res == 2);
117
+ /// # });
118
+ /// ```
119
+ ///
66
120
/// `select` also accepts a `complete` branch and a `default` branch.
67
121
/// `complete` will run if all futures and streams have already been
68
122
/// exhausted. `default` will run if no futures or streams are
69
123
/// immediately ready. `complete` takes priority over `default` in
70
124
/// the case where all futures have completed.
125
+ /// A motivating use-case for passing `Future`s by name as well as for
126
+ /// `complete` blocks is to call `select!` in a loop, which is
127
+ /// demonstrated in the following example:
71
128
///
72
129
/// ```
73
130
/// # futures::executor::block_on(async {
0 commit comments