]> git.lizzy.rs Git - rust.git/blob - src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
Auto merge of #103217 - mejrs:track, r=eholk
[rust.git] / src / test / ui / async-await / drop-order / drop-order-for-locals-when-cancelled.rs
1 // aux-build:arc_wake.rs
2 // edition:2018
3 // run-pass
4
5 #![deny(dead_code)]
6 #![allow(unused_variables)]
7 #![allow(unused_must_use)]
8 #![allow(path_statements)]
9
10 // Test that the drop order for locals in a fn and async fn matches up.
11 extern crate arc_wake;
12
13 use arc_wake::ArcWake;
14 use std::cell::RefCell;
15 use std::future::Future;
16 use std::pin::Pin;
17 use std::rc::Rc;
18 use std::sync::Arc;
19 use std::task::{Context, Poll};
20
21 struct EmptyWaker;
22
23 impl ArcWake for EmptyWaker {
24     fn wake(self: Arc<Self>) {}
25 }
26
27 #[derive(Debug, Eq, PartialEq)]
28 enum DropOrder {
29     Function,
30     Val(&'static str),
31 }
32
33 type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
34
35 struct D(&'static str, DropOrderListPtr);
36
37 impl Drop for D {
38     fn drop(&mut self) {
39         self.1.borrow_mut().push(DropOrder::Val(self.0));
40     }
41 }
42
43 struct NeverReady;
44
45 impl Future for NeverReady {
46     type Output = ();
47     fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
48         Poll::Pending
49     }
50 }
51
52 async fn simple_variable_declaration_async(l: DropOrderListPtr) {
53     l.borrow_mut().push(DropOrder::Function);
54     let x = D("x", l.clone());
55     let y = D("y", l.clone());
56     NeverReady.await;
57 }
58
59 fn simple_variable_declaration_sync(l: DropOrderListPtr) {
60     l.borrow_mut().push(DropOrder::Function);
61     let x = D("x", l.clone());
62     let y = D("y", l.clone());
63 }
64
65 async fn varable_completely_contained_within_block_async(l: DropOrderListPtr) {
66     l.borrow_mut().push(DropOrder::Function);
67     async {
68         let x = D("x", l.clone());
69     }
70         .await;
71     let y = D("y", l.clone());
72     NeverReady.await;
73 }
74
75 fn varable_completely_contained_within_block_sync(l: DropOrderListPtr) {
76     l.borrow_mut().push(DropOrder::Function);
77     {
78         let x = D("x", l.clone());
79     }
80     let y = D("y", l.clone());
81 }
82
83 async fn variables_moved_into_separate_blocks_async(l: DropOrderListPtr) {
84     l.borrow_mut().push(DropOrder::Function);
85     let x = D("x", l.clone());
86     let y = D("y", l.clone());
87     async move { x }.await;
88     async move { y }.await;
89     NeverReady.await;
90 }
91
92 fn variables_moved_into_separate_blocks_sync(l: DropOrderListPtr) {
93     l.borrow_mut().push(DropOrder::Function);
94     let x = D("x", l.clone());
95     let y = D("y", l.clone());
96     {
97         x
98     };
99     {
100         y
101     };
102 }
103
104 async fn variables_moved_into_same_block_async(l: DropOrderListPtr) {
105     l.borrow_mut().push(DropOrder::Function);
106     let x = D("x", l.clone());
107     let y = D("y", l.clone());
108     async move {
109         x;
110         y;
111     };
112     NeverReady.await;
113 }
114
115 fn variables_moved_into_same_block_sync(l: DropOrderListPtr) {
116     l.borrow_mut().push(DropOrder::Function);
117     let x = D("x", l.clone());
118     let y = D("y", l.clone());
119     {
120         x;
121         y;
122     };
123     return;
124 }
125
126 async fn move_after_current_await_doesnt_affect_order(l: DropOrderListPtr) {
127     l.borrow_mut().push(DropOrder::Function);
128     let x = D("x", l.clone());
129     let y = D("y", l.clone());
130     NeverReady.await;
131     async move {
132         x;
133         y;
134     };
135 }
136
137 fn assert_drop_order_after_cancel<Fut: Future<Output = ()>>(
138     f: impl FnOnce(DropOrderListPtr) -> Fut,
139     g: impl FnOnce(DropOrderListPtr),
140 ) {
141     let empty = Arc::new(EmptyWaker);
142     let waker = ArcWake::into_waker(empty);
143     let mut cx = Context::from_waker(&waker);
144
145     let actual_order = Rc::new(RefCell::new(Vec::new()));
146     let mut fut = Box::pin(f(actual_order.clone()));
147     let _ = fut.as_mut().poll(&mut cx);
148     drop(fut);
149
150     let expected_order = Rc::new(RefCell::new(Vec::new()));
151     g(expected_order.clone());
152     assert_eq!(*actual_order.borrow(), *expected_order.borrow());
153 }
154
155 fn main() {
156     assert_drop_order_after_cancel(
157         simple_variable_declaration_async,
158         simple_variable_declaration_sync,
159     );
160     assert_drop_order_after_cancel(
161         varable_completely_contained_within_block_async,
162         varable_completely_contained_within_block_sync,
163     );
164     assert_drop_order_after_cancel(
165         variables_moved_into_separate_blocks_async,
166         variables_moved_into_separate_blocks_sync,
167     );
168     assert_drop_order_after_cancel(
169         variables_moved_into_same_block_async,
170         variables_moved_into_same_block_sync,
171     );
172     assert_drop_order_after_cancel(
173         move_after_current_await_doesnt_affect_order,
174         simple_variable_declaration_sync,
175     );
176 }