Rework the ByMoveBody shim to actually work correctly
This commit is contained in:
parent
1921968cc5
commit
3674032eb2
5 changed files with 336 additions and 36 deletions
|
|
@ -0,0 +1,29 @@
|
|||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
untouched
|
||||
|
||||
after call
|
||||
drop first
|
||||
after await
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
drop first
|
||||
after await
|
||||
uncaptured
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
fixed
|
||||
after await
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
untouched
|
||||
|
||||
after call
|
||||
drop first
|
||||
after await
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
drop first
|
||||
after await
|
||||
uncaptured
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
fixed
|
||||
after await
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
after await
|
||||
fixed
|
||||
untouched
|
||||
|
||||
after call
|
||||
drop first
|
||||
after await
|
||||
uncaptured
|
||||
|
||||
after call
|
||||
drop first
|
||||
after await
|
||||
uncaptured
|
||||
157
tests/ui/async-await/async-closures/precise-captures.rs
Normal file
157
tests/ui/async-await/async-closures/precise-captures.rs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
//@ aux-build:block-on.rs
|
||||
//@ edition:2021
|
||||
//@ run-pass
|
||||
//@ check-run-results
|
||||
//@ revisions: call call_once force_once
|
||||
|
||||
// call - Call the closure regularly.
|
||||
// call_once - Call the closure w/ `async FnOnce`, so exercising the by_move shim.
|
||||
// force_once - Force the closure mode to `FnOnce`, so exercising what was fixed
|
||||
// in <https://github.com/rust-lang/rust/pull/123350>.
|
||||
|
||||
#![feature(async_closure)]
|
||||
#![allow(unused_mut)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
#[cfg(any(call, force_once))]
|
||||
macro_rules! call {
|
||||
($c:expr) => { ($c)() }
|
||||
}
|
||||
|
||||
#[cfg(call_once)]
|
||||
async fn call_once(f: impl async FnOnce()) {
|
||||
f().await
|
||||
}
|
||||
|
||||
#[cfg(call_once)]
|
||||
macro_rules! call {
|
||||
($c:expr) => { call_once($c) }
|
||||
}
|
||||
|
||||
#[cfg(not(force_once))]
|
||||
macro_rules! guidance {
|
||||
($c:expr) => { $c }
|
||||
}
|
||||
|
||||
#[cfg(force_once)]
|
||||
fn infer_fnonce(c: impl async FnOnce()) -> impl async FnOnce() { c }
|
||||
|
||||
#[cfg(force_once)]
|
||||
macro_rules! guidance {
|
||||
($c:expr) => { infer_fnonce($c) }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Drop(&'static str);
|
||||
|
||||
impl std::ops::Drop for Drop {
|
||||
fn drop(&mut self) {
|
||||
println!("{}", self.0);
|
||||
}
|
||||
}
|
||||
|
||||
struct S {
|
||||
a: i32,
|
||||
b: Drop,
|
||||
c: Drop,
|
||||
}
|
||||
|
||||
async fn async_main() {
|
||||
// Precise capture struct
|
||||
{
|
||||
let mut s = S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
|
||||
let mut c = guidance!(async || {
|
||||
s.a = 2;
|
||||
let w = &mut s.b;
|
||||
w.0 = "fixed";
|
||||
});
|
||||
s.c.0 = "uncaptured";
|
||||
let fut = call!(c);
|
||||
println!("after call");
|
||||
fut.await;
|
||||
println!("after await");
|
||||
}
|
||||
println!();
|
||||
|
||||
// Precise capture &mut struct
|
||||
{
|
||||
let s = &mut S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
|
||||
let mut c = guidance!(async || {
|
||||
s.a = 2;
|
||||
let w = &mut s.b;
|
||||
w.0 = "fixed";
|
||||
});
|
||||
s.c.0 = "uncaptured";
|
||||
let fut = call!(c);
|
||||
println!("after call");
|
||||
fut.await;
|
||||
println!("after await");
|
||||
}
|
||||
println!();
|
||||
|
||||
// Precise capture struct by move
|
||||
{
|
||||
let mut s = S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
|
||||
let mut c = guidance!(async move || {
|
||||
s.a = 2;
|
||||
let w = &mut s.b;
|
||||
w.0 = "fixed";
|
||||
});
|
||||
s.c.0 = "uncaptured";
|
||||
let fut = call!(c);
|
||||
println!("after call");
|
||||
fut.await;
|
||||
println!("after await");
|
||||
}
|
||||
println!();
|
||||
|
||||
// Precise capture &mut struct by move
|
||||
{
|
||||
let s = &mut S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
|
||||
let mut c = guidance!(async move || {
|
||||
s.a = 2;
|
||||
let w = &mut s.b;
|
||||
w.0 = "fixed";
|
||||
});
|
||||
// `s` is still captured fully as `&mut S`.
|
||||
let fut = call!(c);
|
||||
println!("after call");
|
||||
fut.await;
|
||||
println!("after await");
|
||||
}
|
||||
println!();
|
||||
|
||||
// Precise capture struct, consume field
|
||||
{
|
||||
let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") };
|
||||
let c = guidance!(async move || {
|
||||
// s.a = 2; // FIXME(async_closures): Figure out why this fails
|
||||
drop(s.b);
|
||||
});
|
||||
s.c.0 = "uncaptured";
|
||||
let fut = call!(c);
|
||||
println!("after call");
|
||||
fut.await;
|
||||
println!("after await");
|
||||
}
|
||||
println!();
|
||||
|
||||
// Precise capture struct by move, consume field
|
||||
{
|
||||
let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") };
|
||||
let c = guidance!(async move || {
|
||||
// s.a = 2; // FIXME(async_closures): Figure out why this fails
|
||||
drop(s.b);
|
||||
});
|
||||
s.c.0 = "uncaptured";
|
||||
let fut = call!(c);
|
||||
println!("after call");
|
||||
fut.await;
|
||||
println!("after await");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
block_on::block_on(async_main());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue