1 // aux-build:arc_wake.rs
5 #![allow(unused_variables)]
6 #![feature(async_await, await_macro)]
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(ref mut x: D, ref mut _y: D) {
46 x.1.borrow_mut().push(DropOrder::Function);
49 fn foo_sync(ref mut x: D, ref mut _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(ref mut x: D, _: D) {
55 x.1.borrow_mut().push(DropOrder::Function);
58 fn bar_sync(ref mut 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((ref mut x, _): (D, D)) {
65 x.1.borrow_mut().push(DropOrder::Function);
68 fn baz_sync((ref mut 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(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
75 x.1.borrow_mut().push(DropOrder::Function);
78 fn foobar_sync(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _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(ref mut x: D, ref mut _y: D) {
87 x.1.borrow_mut().push(DropOrder::Function);
90 fn foo_sync(ref mut x: D, ref mut _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(ref mut x: D, _: D) {
96 x.1.borrow_mut().push(DropOrder::Function);
99 fn bar_sync(ref mut 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((ref mut x, _): (D, D)) {
106 x.1.borrow_mut().push(DropOrder::Function);
109 fn baz_sync((ref mut 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(
116 ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
118 x.1.borrow_mut().push(DropOrder::Function);
122 ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
124 x.1.borrow_mut().push(DropOrder::Function);
128 struct Bar<'a>(PhantomData<&'a ()>);
131 /// Check that unused bindings are dropped after the method with self is polled.
132 async fn foo_async(&'a self, ref mut x: D, ref mut _y: D) {
133 x.1.borrow_mut().push(DropOrder::Function);
136 fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) {
137 x.1.borrow_mut().push(DropOrder::Function);
140 /// Check that underscore patterns are dropped after the method with self is polled.
141 async fn bar_async(&'a self, ref mut x: D, _: D) {
142 x.1.borrow_mut().push(DropOrder::Function);
145 fn bar_sync(&'a self, ref mut x: D, _: D) {
146 x.1.borrow_mut().push(DropOrder::Function);
149 /// Check that underscore patterns within more complex patterns are dropped after the method
150 /// with self is polled.
151 async fn baz_async(&'a self, (ref mut x, _): (D, D)) {
152 x.1.borrow_mut().push(DropOrder::Function);
155 fn baz_sync(&'a self, (ref mut x, _): (D, D)) {
156 x.1.borrow_mut().push(DropOrder::Function);
159 /// Check that underscore and unused bindings within and outwith more complex patterns are
160 /// dropped after the method with self is polled.
161 async fn foobar_async(
162 &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
164 x.1.borrow_mut().push(DropOrder::Function);
168 &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
170 x.1.borrow_mut().push(DropOrder::Function);
174 fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
175 f: impl FnOnce(DropOrderListPtr) -> Fut,
176 g: impl FnOnce(DropOrderListPtr),
178 let empty = Arc::new(EmptyWaker);
179 let waker = ArcWake::into_waker(empty);
180 let mut cx = Context::from_waker(&waker);
182 let actual_order = Rc::new(RefCell::new(Vec::new()));
183 let mut fut = Box::pin(f(actual_order.clone()));
184 let _ = fut.as_mut().poll(&mut cx);
186 let expected_order = Rc::new(RefCell::new(Vec::new()));
187 g(expected_order.clone());
189 assert_eq!(*actual_order.borrow(), *expected_order.borrow());
193 // Free functions (see doc comment on function for what it tests).
194 assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
195 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
196 assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
197 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
198 assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
199 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
200 assert_drop_order_after_poll(
204 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
212 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
219 // Methods w/out self (see doc comment on function for what it tests).
220 assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
221 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
222 assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
223 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
224 assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
225 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
226 assert_drop_order_after_poll(
230 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
238 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
245 // Methods (see doc comment on function for what it tests).
246 let b = Bar(Default::default());
247 assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
248 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
249 assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
250 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
251 assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
252 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
253 assert_drop_order_after_poll(
257 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
265 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),