tokio's join macro is pretty amazing
To find out how this join! macro works exactly, you can do blow to expand the macro to see exact code generated.
rustup toolchain install nightly
cargo install cargo-expand
cargo expandYou will find the expanded code like below
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Macro expaned from | |
// let (first, second) = tokio::join!(do_stuff1(), do_stuff2()); | |
let (first, second) = { | |
use ::tokio::macros::support::{maybe_done, poll_fn, Future, Pin}; | |
use ::tokio::macros::support::Poll::{Ready, Pending}; | |
let mut futures = (maybe_done(do_stuff1()), maybe_done(do_stuff2())); | |
poll_fn(move |cx| { | |
let mut is_pending = false; | |
let (fut, ..) = &mut futures; | |
let mut fut = unsafe { Pin::new_unchecked(fut) }; | |
if fut.poll(cx).is_pending() { | |
is_pending = true; | |
} | |
let (_, fut, ..) = &mut futures; | |
let mut fut = unsafe { Pin::new_unchecked(fut) }; | |
if fut.poll(cx).is_pending() { | |
is_pending = true; | |
} | |
if is_pending { | |
Pending | |
} else { | |
Ready(( | |
{ | |
let (fut, ..) = &mut futures; | |
let mut fut = unsafe { Pin::new_unchecked(fut) }; | |
fut.take_output().expect("expected completed future") | |
}, | |
{ | |
let (_, fut, ..) = &mut futures; | |
let mut fut = unsafe { Pin::new_unchecked(fut) }; | |
fut.take_output().expect("expected completed future") | |
}, | |
)) | |
} | |
}) | |
.await | |
}; |