]>
Commit | Line | Data |
---|---|---|
dc9dc135 XL |
1 | // run-pass |
2 | ||
17df50a5 | 3 | // revisions: default nomiropt thirunsafeck |
f9f354fc | 4 | //[nomiropt]compile-flags: -Z mir-opt-level=0 |
17df50a5 | 5 | //[thirunsafeck]compile-flags: -Zthir-unsafeck |
f9f354fc | 6 | |
e1599b0c XL |
7 | #![allow(unused)] |
8 | ||
064997fb | 9 | // edition: 2018 |
9fa01778 | 10 | // aux-build:arc_wake.rs |
8faf50e0 | 11 | |
9fa01778 XL |
12 | extern crate arc_wake; |
13 | ||
0bf4aa26 | 14 | use std::pin::Pin; |
8faf50e0 XL |
15 | use std::future::Future; |
16 | use std::sync::{ | |
17 | Arc, | |
18 | atomic::{self, AtomicUsize}, | |
19 | }; | |
532ac7d7 | 20 | use std::task::{Context, Poll}; |
9fa01778 | 21 | use arc_wake::ArcWake; |
8faf50e0 XL |
22 | |
23 | struct Counter { | |
24 | wakes: AtomicUsize, | |
25 | } | |
26 | ||
9fa01778 | 27 | impl ArcWake for Counter { |
48663c56 XL |
28 | fn wake(self: Arc<Self>) { |
29 | Self::wake_by_ref(&self) | |
30 | } | |
31 | fn wake_by_ref(arc_self: &Arc<Self>) { | |
9fa01778 | 32 | arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); |
8faf50e0 XL |
33 | } |
34 | } | |
35 | ||
8faf50e0 XL |
36 | struct WakeOnceThenComplete(bool); |
37 | ||
38 | fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } | |
39 | ||
40 | impl Future for WakeOnceThenComplete { | |
41 | type Output = (); | |
532ac7d7 | 42 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { |
8faf50e0 XL |
43 | if self.0 { |
44 | Poll::Ready(()) | |
45 | } else { | |
48663c56 | 46 | cx.waker().wake_by_ref(); |
8faf50e0 XL |
47 | self.0 = true; |
48 | Poll::Pending | |
49 | } | |
50 | } | |
51 | } | |
52 | ||
53 | fn async_block(x: u8) -> impl Future<Output = u8> { | |
54 | async move { | |
48663c56 | 55 | wake_and_yield_once().await; |
8faf50e0 XL |
56 | x |
57 | } | |
58 | } | |
59 | ||
b7449926 XL |
60 | fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a { |
61 | async move { | |
48663c56 | 62 | wake_and_yield_once().await; |
b7449926 XL |
63 | *x |
64 | } | |
65 | } | |
66 | ||
8faf50e0 XL |
67 | fn async_nonmove_block(x: u8) -> impl Future<Output = u8> { |
68 | async move { | |
69 | let future = async { | |
48663c56 | 70 | wake_and_yield_once().await; |
8faf50e0 XL |
71 | x |
72 | }; | |
48663c56 | 73 | future.await |
8faf50e0 XL |
74 | } |
75 | } | |
76 | ||
416331ca | 77 | // see async-closure.rs for async_closure + async_closure_in_unsafe_block |
8faf50e0 XL |
78 | |
79 | async fn async_fn(x: u8) -> u8 { | |
48663c56 | 80 | wake_and_yield_once().await; |
8faf50e0 XL |
81 | x |
82 | } | |
83 | ||
532ac7d7 | 84 | async fn generic_async_fn<T>(x: T) -> T { |
48663c56 | 85 | wake_and_yield_once().await; |
532ac7d7 XL |
86 | x |
87 | } | |
88 | ||
8faf50e0 | 89 | async fn async_fn_with_borrow(x: &u8) -> u8 { |
48663c56 | 90 | wake_and_yield_once().await; |
8faf50e0 XL |
91 | *x |
92 | } | |
93 | ||
b7449926 | 94 | async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 { |
48663c56 | 95 | wake_and_yield_once().await; |
b7449926 XL |
96 | *x |
97 | } | |
98 | ||
99 | fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future<Output = u8> + 'a { | |
100 | async move { | |
48663c56 | 101 | wake_and_yield_once().await; |
b7449926 XL |
102 | *x |
103 | } | |
104 | } | |
105 | ||
532ac7d7 | 106 | async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 { |
416331ca | 107 | wake_and_yield_once().await; |
532ac7d7 XL |
108 | *x |
109 | } | |
532ac7d7 XL |
110 | |
111 | async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 { | |
48663c56 | 112 | wake_and_yield_once().await; |
b7449926 XL |
113 | *x |
114 | } | |
115 | ||
8faf50e0 XL |
116 | fn async_fn_with_internal_borrow(y: u8) -> impl Future<Output = u8> { |
117 | async move { | |
48663c56 | 118 | async_fn_with_borrow_named_lifetime(&y).await |
8faf50e0 XL |
119 | } |
120 | } | |
121 | ||
dc9dc135 | 122 | async unsafe fn unsafe_async_fn(x: u8) -> u8 { |
48663c56 | 123 | wake_and_yield_once().await; |
8faf50e0 XL |
124 | x |
125 | } | |
126 | ||
416331ca XL |
127 | unsafe fn unsafe_fn(x: u8) -> u8 { |
128 | x | |
129 | } | |
130 | ||
131 | fn async_block_in_unsafe_block(x: u8) -> impl Future<Output = u8> { | |
132 | unsafe { | |
133 | async move { | |
134 | unsafe_fn(unsafe_async_fn(x).await) | |
135 | } | |
136 | } | |
137 | } | |
138 | ||
8faf50e0 XL |
139 | struct Foo; |
140 | ||
141 | trait Bar { | |
142 | fn foo() {} | |
143 | } | |
144 | ||
145 | impl Foo { | |
dc9dc135 | 146 | async fn async_assoc_item(x: u8) -> u8 { |
8faf50e0 | 147 | unsafe { |
48663c56 | 148 | unsafe_async_fn(x).await |
8faf50e0 XL |
149 | } |
150 | } | |
dc9dc135 XL |
151 | |
152 | async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 { | |
153 | unsafe_async_fn(x).await | |
154 | } | |
8faf50e0 XL |
155 | } |
156 | ||
157 | fn test_future_yields_once_then_returns<F, Fut>(f: F) | |
158 | where | |
159 | F: FnOnce(u8) -> Fut, | |
160 | Fut: Future<Output = u8>, | |
161 | { | |
0731742a | 162 | let mut fut = Box::pin(f(9)); |
8faf50e0 | 163 | let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); |
9fa01778 | 164 | let waker = ArcWake::into_waker(counter.clone()); |
532ac7d7 | 165 | let mut cx = Context::from_waker(&waker); |
8faf50e0 | 166 | assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); |
532ac7d7 | 167 | assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); |
8faf50e0 | 168 | assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); |
532ac7d7 | 169 | assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); |
8faf50e0 XL |
170 | } |
171 | ||
172 | fn main() { | |
173 | macro_rules! test { | |
b7449926 | 174 | ($($fn_name:expr,)*) => { $( |
8faf50e0 XL |
175 | test_future_yields_once_then_returns($fn_name); |
176 | )* } | |
177 | } | |
178 | ||
b7449926 XL |
179 | macro_rules! test_with_borrow { |
180 | ($($fn_name:expr,)*) => { $( | |
181 | test_future_yields_once_then_returns(|x| { | |
182 | async move { | |
48663c56 | 183 | $fn_name(&x).await |
b7449926 XL |
184 | } |
185 | }); | |
186 | )* } | |
187 | } | |
188 | ||
8faf50e0 XL |
189 | test! { |
190 | async_block, | |
191 | async_nonmove_block, | |
8faf50e0 | 192 | async_fn, |
532ac7d7 | 193 | generic_async_fn, |
8faf50e0 | 194 | async_fn_with_internal_borrow, |
416331ca | 195 | async_block_in_unsafe_block, |
dc9dc135 | 196 | Foo::async_assoc_item, |
b7449926 XL |
197 | |x| { |
198 | async move { | |
48663c56 | 199 | unsafe { unsafe_async_fn(x).await } |
b7449926 XL |
200 | } |
201 | }, | |
dc9dc135 XL |
202 | |x| { |
203 | async move { | |
204 | unsafe { Foo::async_unsafe_assoc_item(x).await } | |
205 | } | |
206 | }, | |
b7449926 | 207 | } |
b7449926 XL |
208 | test_with_borrow! { |
209 | async_block_with_borrow_named_lifetime, | |
210 | async_fn_with_borrow, | |
211 | async_fn_with_borrow_named_lifetime, | |
212 | async_fn_with_impl_future_named_lifetime, | |
213 | |x| { | |
214 | async move { | |
48663c56 | 215 | async_fn_multiple_args_named_lifetime(x, x).await |
b7449926 XL |
216 | } |
217 | }, | |
8faf50e0 XL |
218 | } |
219 | } |