1 // aux-build:arc_wake.rs
5 #![allow(unused_variables)]
7 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
8 // parameters (used or unused) are not dropped until the async fn completes execution.
11 extern crate arc_wake;
13 use arc_wake::ArcWake;
14 use std::cell::RefCell;
15 use std::future::Future;
16 use std::marker::PhantomData;
19 use std::task::Context;
23 impl ArcWake for EmptyWaker {
24 fn wake(self: Arc<Self>) {}
27 #[derive(Debug, Eq, PartialEq)]
33 type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
35 struct D(&'static str, DropOrderListPtr);
39 self.1.borrow_mut().push(DropOrder::Val(self.0));
43 /// Check that unused bindings are dropped after the function is polled.
44 async fn foo_async(ref mut x: D, ref mut _y: D) {
45 x.1.borrow_mut().push(DropOrder::Function);
48 fn foo_sync(ref mut x: D, ref mut _y: D) {
49 x.1.borrow_mut().push(DropOrder::Function);
52 /// Check that underscore patterns are dropped after the function is polled.
53 async fn bar_async(ref mut x: D, _: D) {
54 x.1.borrow_mut().push(DropOrder::Function);
57 fn bar_sync(ref mut x: D, _: D) {
58 x.1.borrow_mut().push(DropOrder::Function);
61 /// Check that underscore patterns within more complex patterns are dropped after the function
63 async fn baz_async((ref mut x, _): (D, D)) {
64 x.1.borrow_mut().push(DropOrder::Function);
67 fn baz_sync((ref mut x, _): (D, D)) {
68 x.1.borrow_mut().push(DropOrder::Function);
71 /// Check that underscore and unused bindings within and outwith more complex patterns are dropped
72 /// after the function is polled.
73 async fn foobar_async(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
74 x.1.borrow_mut().push(DropOrder::Function);
77 fn foobar_sync(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) {
78 x.1.borrow_mut().push(DropOrder::Function);
84 /// Check that unused bindings are dropped after the method is polled.
85 async fn foo_async(ref mut x: D, ref mut _y: D) {
86 x.1.borrow_mut().push(DropOrder::Function);
89 fn foo_sync(ref mut x: D, ref mut _y: D) {
90 x.1.borrow_mut().push(DropOrder::Function);
93 /// Check that underscore patterns are dropped after the method is polled.
94 async fn bar_async(ref mut x: D, _: D) {
95 x.1.borrow_mut().push(DropOrder::Function);
98 fn bar_sync(ref mut x: D, _: D) {
99 x.1.borrow_mut().push(DropOrder::Function);
102 /// Check that underscore patterns within more complex patterns are dropped after the method
104 async fn baz_async((ref mut x, _): (D, D)) {
105 x.1.borrow_mut().push(DropOrder::Function);
108 fn baz_sync((ref mut x, _): (D, D)) {
109 x.1.borrow_mut().push(DropOrder::Function);
112 /// Check that underscore and unused bindings within and outwith more complex patterns are
113 /// dropped after the method is polled.
114 async fn foobar_async(
115 ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
117 x.1.borrow_mut().push(DropOrder::Function);
121 ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
123 x.1.borrow_mut().push(DropOrder::Function);
127 struct Bar<'a>(PhantomData<&'a ()>);
130 /// Check that unused bindings are dropped after the method with self is polled.
131 async fn foo_async(&'a self, ref mut x: D, ref mut _y: D) {
132 x.1.borrow_mut().push(DropOrder::Function);
135 fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) {
136 x.1.borrow_mut().push(DropOrder::Function);
139 /// Check that underscore patterns are dropped after the method with self is polled.
140 async fn bar_async(&'a self, ref mut x: D, _: D) {
141 x.1.borrow_mut().push(DropOrder::Function);
144 fn bar_sync(&'a self, ref mut x: D, _: D) {
145 x.1.borrow_mut().push(DropOrder::Function);
148 /// Check that underscore patterns within more complex patterns are dropped after the method
149 /// with self is polled.
150 async fn baz_async(&'a self, (ref mut x, _): (D, D)) {
151 x.1.borrow_mut().push(DropOrder::Function);
154 fn baz_sync(&'a self, (ref mut x, _): (D, D)) {
155 x.1.borrow_mut().push(DropOrder::Function);
158 /// Check that underscore and unused bindings within and outwith more complex patterns are
159 /// dropped after the method with self is polled.
160 async fn foobar_async(
161 &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
163 x.1.borrow_mut().push(DropOrder::Function);
167 &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
169 x.1.borrow_mut().push(DropOrder::Function);
173 fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
174 f: impl FnOnce(DropOrderListPtr) -> Fut,
175 g: impl FnOnce(DropOrderListPtr),
177 let empty = Arc::new(EmptyWaker);
178 let waker = ArcWake::into_waker(empty);
179 let mut cx = Context::from_waker(&waker);
181 let actual_order = Rc::new(RefCell::new(Vec::new()));
182 let mut fut = Box::pin(f(actual_order.clone()));
183 let _ = fut.as_mut().poll(&mut cx);
185 let expected_order = Rc::new(RefCell::new(Vec::new()));
186 g(expected_order.clone());
188 assert_eq!(*actual_order.borrow(), *expected_order.borrow());
192 // Free functions (see doc comment on function for what it tests).
193 assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
194 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
195 assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())),
196 |l| bar_sync(D("x", l.clone()), D("_", l.clone())));
197 assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))),
198 |l| baz_sync((D("x", l.clone()), D("_", l.clone()))));
199 assert_drop_order_after_poll(
203 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
211 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
218 // Methods w/out self (see doc comment on function for what it tests).
219 assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())),
220 |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())));
221 assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())),
222 |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())));
223 assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))),
224 |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))));
225 assert_drop_order_after_poll(
229 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
237 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
244 // Methods (see doc comment on function for what it tests).
245 let b = Bar(Default::default());
246 assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())),
247 |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())));
248 assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())),
249 |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())));
250 assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))),
251 |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))));
252 assert_drop_order_after_poll(
256 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
264 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),