//@ aux-build:block-on.rs //@ edition:2021 //@ run-pass //@ check-run-results // Same as miri's `tests/pass/async-closure-captures.rs`, keep in sync #![feature(async_closure)] extern crate block_on; fn main() { block_on::block_on(async_main()); } async fn call(f: &impl async Fn() -> T) -> T { f().await } async fn call_once(f: impl async FnOnce() -> T) -> T { f().await } #[derive(Debug)] #[allow(unused)] struct Hello(i32); async fn async_main() { // Capture something by-ref { let x = Hello(0); let c = async || { println!("{x:?}"); }; call(&c).await; call_once(c).await; let x = &Hello(1); let c = async || { println!("{x:?}"); }; call(&c).await; call_once(c).await; } // Capture something and consume it (force to `AsyncFnOnce`) { let x = Hello(2); let c = async || { println!("{x:?}"); drop(x); }; call_once(c).await; } // Capture something with `move`, don't consume it { let x = Hello(3); let c = async move || { println!("{x:?}"); }; call(&c).await; call_once(c).await; let x = &Hello(4); let c = async move || { println!("{x:?}"); }; call(&c).await; call_once(c).await; } // Capture something with `move`, also consume it (so `AsyncFnOnce`) { let x = Hello(5); let c = async move || { println!("{x:?}"); drop(x); }; call_once(c).await; } fn force_fnonce(f: impl async FnOnce() -> T) -> impl async FnOnce() -> T { f } // Capture something with `move`, but infer to `AsyncFnOnce` { let x = Hello(6); let c = force_fnonce(async move || { println!("{x:?}"); }); call_once(c).await; let x = &Hello(7); let c = force_fnonce(async move || { println!("{x:?}"); }); call_once(c).await; } // Capture something by-ref, but infer to `AsyncFnOnce` { let x = Hello(8); let c = force_fnonce(async || { println!("{x:?}"); }); call_once(c).await; let x = &Hello(9); let c = force_fnonce(async || { println!("{x:?}"); }); call_once(c).await; } }