1 // aux-build:arc_wake.rs
5 #![allow(unused_variables)]
6 #![feature(async_await)]
8 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
9 // parameters (used or unused) are not dropped until the async fn completes execution.
12 extern crate arc_wake;
14 use arc_wake::ArcWake;
15 use std::cell::RefCell;
16 use std::future::Future;
17 use std::marker::PhantomData;
20 use std::task::Context;
24 impl ArcWake for EmptyWaker {
25 fn wake(self: Arc<Self>) {}
28 #[derive(Debug, Eq, PartialEq)]
34 type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
36 struct D(&'static str, DropOrderListPtr);
40 self.1.borrow_mut().push(DropOrder::Val(self.0));
44 /// Check that unused bindings are dropped after the function is polled.
45 async fn foo_async(x: D, _y: D) {
46 x.1.borrow_mut().push(DropOrder::Function);
49 fn foo_sync(x: D, _y: D) {
50 x.1.borrow_mut().push(DropOrder::Function);
53 /// Check that underscore patterns are dropped after the function is polled.
54 async fn bar_async(x: D, _: D) {
55 x.1.borrow_mut().push(DropOrder::Function);
58 fn bar_sync(x: D, _: D) {
59 x.1.borrow_mut().push(DropOrder::Function);
62 /// Check that underscore patterns within more complex patterns are dropped after the function
64 async fn baz_async((x, _): (D, D)) {
65 x.1.borrow_mut().push(DropOrder::Function);
68 fn baz_sync((x, _): (D, D)) {
69 x.1.borrow_mut().push(DropOrder::Function);
72 /// Check that underscore and unused bindings within and outwith more complex patterns are dropped
73 /// after the function is polled.
74 async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
75 x.1.borrow_mut().push(DropOrder::Function);
78 fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
79 x.1.borrow_mut().push(DropOrder::Function);
85 /// Check that unused bindings are dropped after the method is polled.
86 async fn foo_async(x: D, _y: D) {
87 x.1.borrow_mut().push(DropOrder::Function);
90 fn foo_sync(x: D, _y: D) {
91 x.1.borrow_mut().push(DropOrder::Function);
94 /// Check that underscore patterns are dropped after the method is polled.
95 async fn bar_async(x: D, _: D) {
96 x.1.borrow_mut().push(DropOrder::Function);
99 fn bar_sync(x: D, _: D) {
100 x.1.borrow_mut().push(DropOrder::Function);
103 /// Check that underscore patterns within more complex patterns are dropped after the method
105 async fn baz_async((x, _): (D, D)) {
106 x.1.borrow_mut().push(DropOrder::Function);
109 fn baz_sync((x, _): (D, D)) {
110 x.1.borrow_mut().push(DropOrder::Function);
113 /// Check that underscore and unused bindings within and outwith more complex patterns are
114 /// dropped after the method is polled.
115 async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
116 x.1.borrow_mut().push(DropOrder::Function);
119 fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
120 x.1.borrow_mut().push(DropOrder::Function);
124 struct Bar<'a>(PhantomData<&'a ()>);
127 /// Check that unused bindings are dropped after the method with self is polled.
128 async fn foo_async(&'a self, x: D, _y: D) {
129 x.1.borrow_mut().push(DropOrder::Function);
132 fn foo_sync(&'a self, x: D, _y: D) {
133 x.1.borrow_mut().push(DropOrder::Function);
136 /// Check that underscore patterns are dropped after the method with self is polled.
137 async fn bar_async(&'a self, x: D, _: D) {
138 x.1.borrow_mut().push(DropOrder::Function);
141 fn bar_sync(&'a self, x: D, _: D) {
142 x.1.borrow_mut().push(DropOrder::Function);
145 /// Check that underscore patterns within more complex patterns are dropped after the method
146 /// with self is polled.
147 async fn baz_async(&'a self, (x, _): (D, D)) {
148 x.1.borrow_mut().push(DropOrder::Function);
151 fn baz_sync(&'a self, (x, _): (D, D)) {
152 x.1.borrow_mut().push(DropOrder::Function);
155 /// Check that underscore and unused bindings within and outwith more complex patterns are
156 /// dropped after the method with self is polled.
157 async fn foobar_async(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
158 x.1.borrow_mut().push(DropOrder::Function);
161 fn foobar_sync(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
162 x.1.borrow_mut().push(DropOrder::Function);
166 fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
167 f: impl FnOnce(DropOrderListPtr) -> Fut,
168 g: impl FnOnce(DropOrderListPtr),
170 let empty = Arc::new(EmptyWaker);
171 let waker = ArcWake::into_waker(empty);
172 let mut cx = Context::from_waker(&waker);
174 let actual_order = Rc::new(RefCell::new(Vec::new()));
175 let mut fut = Box::pin(f(actual_order.clone()));
176 let _ = fut.as_mut().poll(&mut cx);
178 let expected_order = Rc::new(RefCell::new(Vec::new()));
179 g(expected_order.clone());
181 assert_eq!(*actual_order.borrow(), *expected_order.borrow());
185 // Free functions (see doc comment on function for what it tests).
186 assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
187 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
188 assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
189 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
190 assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
191 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
192 assert_drop_order_after_poll(
196 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
204 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
211 // Methods w/out self (see doc comment on function for what it tests).
212 assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
213 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
214 assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
215 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
216 assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
217 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
218 assert_drop_order_after_poll(
222 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
230 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
237 // Methods (see doc comment on function for what it tests).
238 let b = Bar(Default::default());
239 assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
240 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
241 assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
242 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
243 assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
244 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
245 assert_drop_order_after_poll(
249 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
257 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),