]> git.proxmox.com Git - rustc.git/blame - src/test/ui/async-await/async-await.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / src / test / ui / async-await / async-await.rs
CommitLineData
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
12extern crate arc_wake;
13
0bf4aa26 14use std::pin::Pin;
8faf50e0
XL
15use std::future::Future;
16use std::sync::{
17 Arc,
18 atomic::{self, AtomicUsize},
19};
532ac7d7 20use std::task::{Context, Poll};
9fa01778 21use arc_wake::ArcWake;
8faf50e0
XL
22
23struct Counter {
24 wakes: AtomicUsize,
25}
26
9fa01778 27impl 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
36struct WakeOnceThenComplete(bool);
37
38fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
39
40impl 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
53fn 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
60fn 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
67fn 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
79async fn async_fn(x: u8) -> u8 {
48663c56 80 wake_and_yield_once().await;
8faf50e0
XL
81 x
82}
83
532ac7d7 84async fn generic_async_fn<T>(x: T) -> T {
48663c56 85 wake_and_yield_once().await;
532ac7d7
XL
86 x
87}
88
8faf50e0 89async fn async_fn_with_borrow(x: &u8) -> u8 {
48663c56 90 wake_and_yield_once().await;
8faf50e0
XL
91 *x
92}
93
b7449926 94async 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
99fn 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 106async 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
111async 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
116fn 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 122async unsafe fn unsafe_async_fn(x: u8) -> u8 {
48663c56 123 wake_and_yield_once().await;
8faf50e0
XL
124 x
125}
126
416331ca
XL
127unsafe fn unsafe_fn(x: u8) -> u8 {
128 x
129}
130
131fn 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
139struct Foo;
140
141trait Bar {
142 fn foo() {}
143}
144
145impl 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
157fn test_future_yields_once_then_returns<F, Fut>(f: F)
158where
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
172fn 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}