|  | // Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync | 
|  |  | 
|  | #![feature(async_trait_bounds)] | 
|  |  | 
|  | use std::future::Future; | 
|  | use std::pin::pin; | 
|  | use std::task::*; | 
|  |  | 
|  | pub fn block_on<T>(fut: impl Future<Output = T>) -> T { | 
|  | let mut fut = pin!(fut); | 
|  | let ctx = &mut Context::from_waker(Waker::noop()); | 
|  |  | 
|  | loop { | 
|  | match fut.as_mut().poll(ctx) { | 
|  | Poll::Pending => {} | 
|  | Poll::Ready(t) => break t, | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | block_on(async_main()); | 
|  | } | 
|  |  | 
|  | async fn call<T>(f: &impl async Fn() -> T) -> T { | 
|  | f().await | 
|  | } | 
|  |  | 
|  | async fn call_once<T>(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<T>(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; | 
|  | } | 
|  | } |