1 use std::future::{join, Future};
4 use std::task::{Context, Poll, Wake};
13 impl Future for PollN {
16 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
19 if self.polled == self.num {
20 return Poll::Ready(self.val);
23 cx.waker().wake_by_ref();
28 fn poll_n(val: usize, num: usize) -> PollN {
29 PollN { val, num, polled: 0 }
33 #[cfg_attr(miri, ignore)] // self-referential generators do not work with Miri's aliasing checks
36 let x = join!(async { 0 }).await;
39 let x = join!(async { 0 }, async { 1 }).await;
40 assert_eq!(x, (0, 1));
42 let x = join!(async { 0 }, async { 1 }, async { 2 }).await;
43 assert_eq!(x, (0, 1, 2));
56 assert_eq!(x, (0, 1, 2, 3, 4, 5, 6, 7));
58 let y = String::new();
68 /// Tests that `join!(…)` behaves "like a function": evaluating its arguments
69 /// before applying any of its own logic.
71 /// _e.g._, `join!(async_fn(&borrowed), …)` does not consume `borrowed`;
72 /// and `join!(opt_fut?, …)` does let that `?` refer to the callsite scope.
73 mod test_join_function_like_value_arg_semantics {
76 async fn async_fn(_: impl Sized) {}
78 // no need to _run_ this test, just to compile it.
79 fn _join_does_not_unnecessarily_move_mentioned_bindings() {
80 let not_copy = vec![()];
81 let _ = join!(async_fn(¬_copy)); // should not move `not_copy`
82 let _ = ¬_copy; // OK
86 fn join_lets_control_flow_effects_such_as_try_flow_through() {
89 *&mut { maybe_fut } = Some(async {});
92 assert!(Option::is_none(&try { join!(maybe_fut?, async { unreachable!() }) }));
96 fn join_is_able_to_handle_temporaries() {
97 let _ = join!(async_fn(&String::from("temporary")));
98 let () = block_on(join!(async_fn(&String::from("temporary"))));
102 fn block_on(fut: impl Future) {
104 impl Wake for Waker {
105 fn wake(self: Arc<Self>) {
106 thread::current().unpark()
110 let waker = Arc::new(Waker).into();
111 let mut cx = Context::from_waker(&waker);
112 let mut fut = Box::pin(fut);
115 match fut.as_mut().poll(&mut cx) {
116 Poll::Ready(_) => break,
117 Poll::Pending => thread::park(),
122 // just tests by whether or not this compiles
123 fn _pending_impl_all_auto_traits<T>() {
124 use std::panic::{RefUnwindSafe, UnwindSafe};
125 fn all_auto_traits<T: Send + Sync + Unpin + UnwindSafe + RefUnwindSafe>() {}
127 all_auto_traits::<std::future::Pending<T>>();