Skip to content

Commit 5ce3540

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 0576ac1 commit 5ce3540

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

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

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

0 commit comments

Comments
 (0)