1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
/// Poll multiple futures concurrently, and return a tuple of returned values /// from each future. /// /// This macro is only usable inside async functions and blocks. /// /// Futures that are ready first will be executed first. This makes /// `join!(a, b)` faster than the alternative `(a.await, b.await)`. /// /// ```rust /// #![forbid(unsafe_code)] /// /// async fn one() -> char { /// 'c' /// } /// /// async fn two() -> char { /// 'a' /// } /// /// async fn example() { /// // Joined await on the two futures. /// let a = one(); /// let b = two(); /// let ret = pasts::join!(a, b); /// assert_eq!(ret, ('c', 'a')); /// } /// /// <pasts::ThreadInterrupt as pasts::Interrupt>::block_on(example()); /// ``` #[macro_export] macro_rules! join { ($($future:ident),* $(,)?) => { { use $crate::{ select, _pasts_hide::{stn::mem::MaybeUninit, join} }; let mut count = 0; $( // Force move. let mut $future = $future; // Shadow to prevent future use. #[allow(unused_mut)] let mut $future = $crate::_pasts_hide::new_task(&mut $future); count += 1; )* for _ in 0..count { select! { $( ret = $future.0 => $future.1 = MaybeUninit::new(ret) ),* } } ($(join($future.1)),*) } }; }