]> git.proxmox.com Git - rustc.git/blame - src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
Update unsuspicious file list
[rustc.git] / src / test / ui / async-await / drop-order / drop-order-for-async-fn-parameters-by-ref-binding.rs
CommitLineData
48663c56
XL
1// aux-build:arc_wake.rs
2// edition:2018
3// run-pass
4
5#![allow(unused_variables)]
48663c56
XL
6
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.
9// See also #54716.
10
11extern crate arc_wake;
12
13use arc_wake::ArcWake;
14use std::cell::RefCell;
15use std::future::Future;
16use std::marker::PhantomData;
17use std::sync::Arc;
18use std::rc::Rc;
19use std::task::Context;
20
21struct EmptyWaker;
22
23impl ArcWake for EmptyWaker {
24 fn wake(self: Arc<Self>) {}
25}
26
27#[derive(Debug, Eq, PartialEq)]
28enum DropOrder {
29 Function,
30 Val(&'static str),
31}
32
33type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
34
35struct D(&'static str, DropOrderListPtr);
36
37impl Drop for D {
38 fn drop(&mut self) {
39 self.1.borrow_mut().push(DropOrder::Val(self.0));
40 }
41}
42
43/// Check that unused bindings are dropped after the function is polled.
44async fn foo_async(ref mut x: D, ref mut _y: D) {
45 x.1.borrow_mut().push(DropOrder::Function);
46}
47
48fn foo_sync(ref mut x: D, ref mut _y: D) {
49 x.1.borrow_mut().push(DropOrder::Function);
50}
51
52/// Check that underscore patterns are dropped after the function is polled.
53async fn bar_async(ref mut x: D, _: D) {
54 x.1.borrow_mut().push(DropOrder::Function);
55}
56
57fn bar_sync(ref mut x: D, _: D) {
58 x.1.borrow_mut().push(DropOrder::Function);
59}
60
61/// Check that underscore patterns within more complex patterns are dropped after the function
62/// is polled.
63async fn baz_async((ref mut x, _): (D, D)) {
64 x.1.borrow_mut().push(DropOrder::Function);
65}
66
67fn baz_sync((ref mut x, _): (D, D)) {
68 x.1.borrow_mut().push(DropOrder::Function);
69}
70
71/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
72/// after the function is polled.
73async 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);
75}
76
77fn 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);
79}
80
81struct Foo;
82
83impl Foo {
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);
87 }
88
89 fn foo_sync(ref mut x: D, ref mut _y: D) {
90 x.1.borrow_mut().push(DropOrder::Function);
91 }
92
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);
96 }
97
98 fn bar_sync(ref mut x: D, _: D) {
99 x.1.borrow_mut().push(DropOrder::Function);
100 }
101
102 /// Check that underscore patterns within more complex patterns are dropped after the method
103 /// is polled.
104 async fn baz_async((ref mut x, _): (D, D)) {
105 x.1.borrow_mut().push(DropOrder::Function);
106 }
107
108 fn baz_sync((ref mut x, _): (D, D)) {
109 x.1.borrow_mut().push(DropOrder::Function);
110 }
111
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,
116 ) {
117 x.1.borrow_mut().push(DropOrder::Function);
118 }
119
120 fn foobar_sync(
121 ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
122 ) {
123 x.1.borrow_mut().push(DropOrder::Function);
124 }
125}
126
127struct Bar<'a>(PhantomData<&'a ()>);
128
129impl<'a> Bar<'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);
133 }
134
135 fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) {
136 x.1.borrow_mut().push(DropOrder::Function);
137 }
138
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);
142 }
143
144 fn bar_sync(&'a self, ref mut x: D, _: D) {
145 x.1.borrow_mut().push(DropOrder::Function);
146 }
147
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);
152 }
153
154 fn baz_sync(&'a self, (ref mut x, _): (D, D)) {
155 x.1.borrow_mut().push(DropOrder::Function);
156 }
157
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,
162 ) {
163 x.1.borrow_mut().push(DropOrder::Function);
164 }
165
166 fn foobar_sync(
167 &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D,
168 ) {
169 x.1.borrow_mut().push(DropOrder::Function);
170 }
171}
172
173fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
174 f: impl FnOnce(DropOrderListPtr) -> Fut,
175 g: impl FnOnce(DropOrderListPtr),
176) {
177 let empty = Arc::new(EmptyWaker);
178 let waker = ArcWake::into_waker(empty);
179 let mut cx = Context::from_waker(&waker);
180
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);
184
185 let expected_order = Rc::new(RefCell::new(Vec::new()));
186 g(expected_order.clone());
187
188 assert_eq!(*actual_order.borrow(), *expected_order.borrow());
189}
190
191fn main() {
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(
200 |l| {
201 foobar_async(
202 D("x", l.clone()),
203 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
204 D("_", l.clone()),
205 D("_y", l.clone()),
206 )
207 },
208 |l| {
209 foobar_sync(
210 D("x", l.clone()),
211 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
212 D("_", l.clone()),
213 D("_y", l.clone()),
214 )
215 },
216 );
217
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(
226 |l| {
227 Foo::foobar_async(
228 D("x", l.clone()),
229 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
230 D("_", l.clone()),
231 D("_y", l.clone()),
232 )
233 },
234 |l| {
235 Foo::foobar_sync(
236 D("x", l.clone()),
237 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
238 D("_", l.clone()),
239 D("_y", l.clone()),
240 )
241 },
242 );
243
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(
253 |l| {
254 b.foobar_async(
255 D("x", l.clone()),
256 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
257 D("_", l.clone()),
258 D("_y", l.clone()),
259 )
260 },
261 |l| {
262 b.foobar_sync(
263 D("x", l.clone()),
264 (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
265 D("_", l.clone()),
266 D("_y", l.clone()),
267 )
268 },
269 );
270}