about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/run-pass/issue-54716.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/test/run-pass/issue-54716.rs b/src/test/run-pass/issue-54716.rs
new file mode 100644
index 00000000000..7f64c6e120e
--- /dev/null
+++ b/src/test/run-pass/issue-54716.rs
@@ -0,0 +1,89 @@
+// aux-build:arc_wake.rs
+// edition:2018
+// run-pass
+
+#![allow(unused_variables)]
+#![feature(async_await, await_macro, futures_api)]
+
+extern crate arc_wake;
+
+use arc_wake::ArcWake;
+use std::cell::RefCell;
+use std::future::Future;
+use std::sync::Arc;
+use std::task::Context;
+
+struct EmptyWaker;
+
+impl ArcWake for EmptyWaker {
+    fn wake(self: Arc<Self>) {}
+}
+
+#[derive(Debug, Eq, PartialEq)]
+enum DropOrder {
+    Function,
+    Val(&'static str),
+}
+
+struct D(&'static str, Arc<RefCell<Vec<DropOrder>>>);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        self.1.borrow_mut().push(DropOrder::Val(self.0));
+    }
+}
+
+async fn foo(x: D, _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+async fn bar(x: D, _: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+async fn baz((x, _): (D, D)) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+async fn foobar(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
+    x.1.borrow_mut().push(DropOrder::Function);
+}
+
+fn main() {
+    let empty = Arc::new(EmptyWaker);
+    let waker = ArcWake::into_waker(empty);
+    let mut cx = Context::from_waker(&waker);
+
+    use DropOrder::*;
+
+    // Currently, the `bar` and `foobar` tests do not output the same order as the equivalent
+    // non-async functions. This is because the drop order of captured variables doesn't match the
+    // drop order of arguments in a function.
+
+    let af = Arc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(foo(D("x", af.clone()), D("_y", af.clone())));
+    let _ = fut.as_mut().poll(&mut cx);
+    assert_eq!(*af.borrow(), &[Function, Val("_y"), Val("x")]);
+
+    let af = Arc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(bar(D("x", af.clone()), D("_", af.clone())));
+    let _ = fut.as_mut().poll(&mut cx);
+    assert_eq!(*af.borrow(), &[Function, Val("x"), Val("_")]);
+
+    let af = Arc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(baz((D("x", af.clone()), D("_", af.clone()))));
+    let _ = fut.as_mut().poll(&mut cx);
+    assert_eq!(*af.borrow(), &[Function, Val("x"), Val("_")]);
+
+    let af = Arc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(foobar(
+        D("x", af.clone()),
+        (D("a", af.clone()), D("_", af.clone()), D("_c", af.clone())),
+        D("_", af.clone()),
+        D("_y", af.clone()),
+    ));
+    let _ = fut.as_mut().poll(&mut cx);
+    assert_eq!(*af.borrow(), &[
+       Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_"),
+    ]);
+}