Skip to content

Commit 8b57be1

Browse files
committed
Add test for drop order in async functions.
This tests that async functions drop parameters in the same order as regular functions.
1 parent 9224be5 commit 8b57be1

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/test/run-pass/issue-54716.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// aux-build:arc_wake.rs
2+
// edition:2018
3+
// run-pass
4+
5+
#![allow(unused_variables)]
6+
#![feature(async_await, await_macro, futures_api)]
7+
8+
extern crate arc_wake;
9+
10+
use arc_wake::ArcWake;
11+
use std::cell::RefCell;
12+
use std::future::Future;
13+
use std::sync::Arc;
14+
use std::task::Context;
15+
16+
struct EmptyWaker;
17+
18+
impl ArcWake for EmptyWaker {
19+
fn wake(self: Arc<Self>) {}
20+
}
21+
22+
#[derive(Debug, Eq, PartialEq)]
23+
enum DropOrder {
24+
Function,
25+
Val(&'static str),
26+
}
27+
28+
struct D(&'static str, Arc<RefCell<Vec<DropOrder>>>);
29+
30+
impl Drop for D {
31+
fn drop(&mut self) {
32+
self.1.borrow_mut().push(DropOrder::Val(self.0));
33+
}
34+
}
35+
36+
async fn foo(x: D, _y: D) {
37+
x.1.borrow_mut().push(DropOrder::Function);
38+
}
39+
40+
async fn bar(x: D, _: D) {
41+
x.1.borrow_mut().push(DropOrder::Function);
42+
}
43+
44+
async fn baz((x, _): (D, D)) {
45+
x.1.borrow_mut().push(DropOrder::Function);
46+
}
47+
48+
async fn foobar(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
49+
x.1.borrow_mut().push(DropOrder::Function);
50+
}
51+
52+
fn main() {
53+
let empty = Arc::new(EmptyWaker);
54+
let waker = ArcWake::into_waker(empty);
55+
let mut cx = Context::from_waker(&waker);
56+
57+
use DropOrder::*;
58+
59+
// Currently, the `bar` and `foobar` tests do not output the same order as the equivalent
60+
// non-async functions. This is because the drop order of captured variables doesn't match the
61+
// drop order of arguments in a function.
62+
63+
let af = Arc::new(RefCell::new(Vec::new()));
64+
let mut fut = Box::pin(foo(D("x", af.clone()), D("_y", af.clone())));
65+
let _ = fut.as_mut().poll(&mut cx);
66+
assert_eq!(*af.borrow(), &[Function, Val("_y"), Val("x")]);
67+
68+
let af = Arc::new(RefCell::new(Vec::new()));
69+
let mut fut = Box::pin(bar(D("x", af.clone()), D("_", af.clone())));
70+
let _ = fut.as_mut().poll(&mut cx);
71+
assert_eq!(*af.borrow(), &[Function, Val("x"), Val("_")]);
72+
73+
let af = Arc::new(RefCell::new(Vec::new()));
74+
let mut fut = Box::pin(baz((D("x", af.clone()), D("_", af.clone()))));
75+
let _ = fut.as_mut().poll(&mut cx);
76+
assert_eq!(*af.borrow(), &[Function, Val("x"), Val("_")]);
77+
78+
let af = Arc::new(RefCell::new(Vec::new()));
79+
let mut fut = Box::pin(foobar(
80+
D("x", af.clone()),
81+
(D("a", af.clone()), D("_", af.clone()), D("_c", af.clone())),
82+
D("_", af.clone()),
83+
D("_y", af.clone()),
84+
));
85+
let _ = fut.as_mut().poll(&mut cx);
86+
assert_eq!(*af.borrow(), &[
87+
Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_"),
88+
]);
89+
}

0 commit comments

Comments
 (0)