Last active
March 4, 2020 13:22
-
-
Save rklaehn/7cec8b3faf6902e69b7fbcac4ca2a5c6 to your computer and use it in GitHub Desktop.
How the select! macro expands
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
use futures::{future::FutureExt, select}; | |
async fn a() {} | |
async fn b() {} | |
async fn test() { | |
select! { | |
a = a().fuse() => println!("a"), | |
b = b().fuse() => println!("b"), | |
} | |
} | |
#[async_std::main] | |
async fn main() -> std::io::Result<()> { | |
Ok(test().await) | |
} |
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
#![feature(prelude_import)] | |
#[prelude_import] | |
use std::prelude::v1::*; | |
#[macro_use] | |
extern crate std; | |
use futures::{future::FutureExt, select}; | |
async fn a() {} | |
async fn b() {} | |
async fn test() { | |
{ | |
enum ProcMacroHack { | |
Nested = ( "futures_crate_path (:: futures) a = a () . fuse () => println ! (\"a\"), b = b\n() . fuse () => println ! (\"b\")," , 0 ) . 1 , } | |
{ | |
enum __PrivResult<_0, _1> { | |
_0(_0), | |
_1(_1), | |
} | |
let __select_result = { | |
let mut _0 = a().fuse(); | |
let mut _1 = b().fuse(); | |
let mut __poll_fn = |__cx: &mut ::futures::task::Context<'_>| { | |
let mut __any_polled = false; | |
let mut _0 = |__cx: &mut ::futures::task::Context<'_>| { | |
let mut _0 = unsafe { ::core::pin::Pin::new_unchecked(&mut _0) }; | |
if ::futures::future::FusedFuture::is_terminated(&_0) { | |
None | |
} else { | |
Some( | |
::futures::future::FutureExt::poll_unpin(&mut _0, __cx) | |
.map(__PrivResult::_0), | |
) | |
} | |
}; | |
let _0: &mut dyn FnMut( | |
&mut ::futures::task::Context<'_>, | |
) | |
-> Option<::futures::task::Poll<_>> = &mut _0; | |
let mut _1 = |__cx: &mut ::futures::task::Context<'_>| { | |
let mut _1 = unsafe { ::core::pin::Pin::new_unchecked(&mut _1) }; | |
if ::futures::future::FusedFuture::is_terminated(&_1) { | |
None | |
} else { | |
Some( | |
::futures::future::FutureExt::poll_unpin(&mut _1, __cx) | |
.map(__PrivResult::_1), | |
) | |
} | |
}; | |
let _1: &mut dyn FnMut( | |
&mut ::futures::task::Context<'_>, | |
) | |
-> Option<::futures::task::Poll<_>> = &mut _1; | |
let mut __select_arr = [_0, _1]; | |
::futures::async_await::shuffle(&mut __select_arr); | |
for poller in &mut __select_arr { | |
let poller: &mut &mut dyn FnMut( | |
&mut ::futures::task::Context<'_>, | |
) | |
-> Option<::futures::task::Poll<_>> = poller; | |
match poller(__cx) { | |
Some(x @ ::futures::task::Poll::Ready(_)) => return x, | |
Some(::futures::task::Poll::Pending) => { | |
__any_polled = true; | |
} | |
None => {} | |
} | |
} | |
if !__any_polled { | |
{ | |
::std::rt::begin_panic( | |
"all futures in select! were completed,\ | |
but no `complete =>` handler was provided", | |
&("src/main.rs", 8u32, 5u32), | |
) | |
} | |
} else { | |
::futures::task::Poll::Pending | |
} | |
}; | |
::futures::future::poll_fn(__poll_fn).await | |
}; | |
match __select_result { | |
__PrivResult::_0(a) => { | |
::std::io::_print(::core::fmt::Arguments::new_v1( | |
&["a\n"], | |
&match () { | |
() => [], | |
}, | |
)); | |
} | |
__PrivResult::_1(b) => { | |
::std::io::_print(::core::fmt::Arguments::new_v1( | |
&["b\n"], | |
&match () { | |
() => [], | |
}, | |
)); | |
} | |
} | |
} | |
} | |
} | |
fn main() -> std::io::Result<()> { | |
async fn main() -> std::io::Result<()> { | |
{ | |
Ok(test().await) | |
} | |
} | |
async_std::task::block_on(async { main().await }) | |
} |
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
#![feature(prelude_import)] | |
#[prelude_import] | |
use std::prelude::v1::*; | |
#[macro_use] | |
extern crate std; | |
use futures::{future::FutureExt, select_biased}; | |
async fn a() {} | |
async fn b() {} | |
async fn test() { | |
{ | |
enum ProcMacroHack { | |
Nested = ( "futures_crate_path (:: futures) a = a () . fuse () => println ! (\"a\"), b = b\n() . fuse () => println ! (\"b\")," , 0 ) . 1 , } | |
{ | |
enum __PrivResult<_0, _1> { | |
_0(_0), | |
_1(_1), | |
} | |
let __select_result = { | |
let mut _0 = a().fuse(); | |
let mut _1 = b().fuse(); | |
let mut __poll_fn = |__cx: &mut ::futures::task::Context<'_>| { | |
let mut __any_polled = false; | |
let mut _0 = |__cx: &mut ::futures::task::Context<'_>| { | |
let mut _0 = unsafe { ::core::pin::Pin::new_unchecked(&mut _0) }; | |
if ::futures::future::FusedFuture::is_terminated(&_0) { | |
None | |
} else { | |
Some( | |
::futures::future::FutureExt::poll_unpin(&mut _0, __cx) | |
.map(__PrivResult::_0), | |
) | |
} | |
}; | |
let _0: &mut dyn FnMut( | |
&mut ::futures::task::Context<'_>, | |
) | |
-> Option<::futures::task::Poll<_>> = &mut _0; | |
let mut _1 = |__cx: &mut ::futures::task::Context<'_>| { | |
let mut _1 = unsafe { ::core::pin::Pin::new_unchecked(&mut _1) }; | |
if ::futures::future::FusedFuture::is_terminated(&_1) { | |
None | |
} else { | |
Some( | |
::futures::future::FutureExt::poll_unpin(&mut _1, __cx) | |
.map(__PrivResult::_1), | |
) | |
} | |
}; | |
let _1: &mut dyn FnMut( | |
&mut ::futures::task::Context<'_>, | |
) | |
-> Option<::futures::task::Poll<_>> = &mut _1; | |
let mut __select_arr = [_0, _1]; | |
for poller in &mut __select_arr { | |
let poller: &mut &mut dyn FnMut( | |
&mut ::futures::task::Context<'_>, | |
) | |
-> Option<::futures::task::Poll<_>> = poller; | |
match poller(__cx) { | |
Some(x @ ::futures::task::Poll::Ready(_)) => return x, | |
Some(::futures::task::Poll::Pending) => { | |
__any_polled = true; | |
} | |
None => {} | |
} | |
} | |
if !__any_polled { | |
{ | |
::std::rt::begin_panic( | |
"all futures in select! were completed,\ | |
but no `complete =>` handler was provided", | |
&("src/main.rs", 8u32, 5u32), | |
) | |
} | |
} else { | |
::futures::task::Poll::Pending | |
} | |
}; | |
::futures::future::poll_fn(__poll_fn).await | |
}; | |
match __select_result { | |
__PrivResult::_0(a) => { | |
::std::io::_print(::core::fmt::Arguments::new_v1( | |
&["a\n"], | |
&match () { | |
() => [], | |
}, | |
)); | |
} | |
__PrivResult::_1(b) => { | |
::std::io::_print(::core::fmt::Arguments::new_v1( | |
&["b\n"], | |
&match () { | |
() => [], | |
}, | |
)); | |
} | |
} | |
} | |
} | |
} | |
fn main() -> std::io::Result<()> { | |
async fn main() -> std::io::Result<()> { | |
{ | |
Ok(test().await) | |
} | |
} | |
async_std::task::block_on(async { main().await }) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment