117 lines
2.4 KiB
Rust
117 lines
2.4 KiB
Rust
//@ 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<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;
|
|
}
|
|
}
|