3 // revisions: default nomiropt thirunsafeck
4 //[nomiropt]compile-flags: -Z mir-opt-level=0
5 //[thirunsafeck]compile-flags: -Zthir-unsafeck
10 // aux-build:arc_wake.rs
12 extern crate arc_wake
;
15 use std
::future
::Future
;
18 atomic
::{self, AtomicUsize}
,
20 use std
::task
::{Context, Poll}
;
21 use arc_wake
::ArcWake
;
27 impl ArcWake
for Counter
{
28 fn wake(self: Arc
<Self>) {
29 Self::wake_by_ref(&self)
31 fn wake_by_ref(arc_self
: &Arc
<Self>) {
32 arc_self
.wakes
.fetch_add(1, atomic
::Ordering
::SeqCst
);
36 struct WakeOnceThenComplete(bool
);
38 fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
40 impl Future
for WakeOnceThenComplete
{
42 fn poll(mut self: Pin
<&mut Self>, cx
: &mut Context
<'_
>) -> Poll
<()> {
46 cx
.waker().wake_by_ref();
53 fn async_block(x
: u8) -> impl Future
<Output
= u8> {
55 wake_and_yield_once().await
;
60 fn async_block_with_borrow_named_lifetime
<'a
>(x
: &'a
u8) -> impl Future
<Output
= u8> + 'a
{
62 wake_and_yield_once().await
;
67 fn async_nonmove_block(x
: u8) -> impl Future
<Output
= u8> {
70 wake_and_yield_once().await
;
77 // see async-closure.rs for async_closure + async_closure_in_unsafe_block
79 async
fn async_fn(x
: u8) -> u8 {
80 wake_and_yield_once().await
;
84 async
fn generic_async_fn
<T
>(x
: T
) -> T
{
85 wake_and_yield_once().await
;
89 async
fn async_fn_with_borrow(x
: &u8) -> u8 {
90 wake_and_yield_once().await
;
94 async
fn async_fn_with_borrow_named_lifetime
<'a
>(x
: &'a
u8) -> u8 {
95 wake_and_yield_once().await
;
99 fn async_fn_with_impl_future_named_lifetime
<'a
>(x
: &'a
u8) -> impl Future
<Output
= u8> + 'a
{
101 wake_and_yield_once().await
;
106 async
fn async_fn_multiple_args(x
: &u8, _y
: &u8) -> u8 {
107 wake_and_yield_once().await
;
111 async
fn async_fn_multiple_args_named_lifetime
<'a
>(x
: &'a
u8, _y
: &'a
u8) -> u8 {
112 wake_and_yield_once().await
;
116 fn async_fn_with_internal_borrow(y
: u8) -> impl Future
<Output
= u8> {
118 async_fn_with_borrow_named_lifetime(&y
).await
122 async
unsafe fn unsafe_async_fn(x
: u8) -> u8 {
123 wake_and_yield_once().await
;
127 unsafe fn unsafe_fn(x
: u8) -> u8 {
131 fn async_block_in_unsafe_block(x
: u8) -> impl Future
<Output
= u8> {
134 unsafe_fn(unsafe_async_fn(x
).await
)
146 async
fn async_assoc_item(x
: u8) -> u8 {
148 unsafe_async_fn(x
).await
152 async
unsafe fn async_unsafe_assoc_item(x
: u8) -> u8 {
153 unsafe_async_fn(x
).await
157 fn test_future_yields_once_then_returns
<F
, Fut
>(f
: F
)
159 F
: FnOnce(u8) -> Fut
,
160 Fut
: Future
<Output
= u8>,
162 let mut fut
= Box
::pin(f(9));
163 let counter
= Arc
::new(Counter { wakes: AtomicUsize::new(0) }
);
164 let waker
= ArcWake
::into_waker(counter
.clone());
165 let mut cx
= Context
::from_waker(&waker
);
166 assert_eq
!(0, counter
.wakes
.load(atomic
::Ordering
::SeqCst
));
167 assert_eq
!(Poll
::Pending
, fut
.as_mut().poll(&mut cx
));
168 assert_eq
!(1, counter
.wakes
.load(atomic
::Ordering
::SeqCst
));
169 assert_eq
!(Poll
::Ready(9), fut
.as_mut().poll(&mut cx
));
174 ($
($fn_name
:expr
,)*) => { $
(
175 test_future_yields_once_then_returns($fn_name
);
179 macro_rules
! test_with_borrow
{
180 ($
($fn_name
:expr
,)*) => { $
(
181 test_future_yields_once_then_returns(|x
| {
194 async_fn_with_internal_borrow
,
195 async_block_in_unsafe_block
,
196 Foo
::async_assoc_item
,
199 unsafe { unsafe_async_fn(x).await }
204 unsafe { Foo::async_unsafe_assoc_item(x).await }
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
,
215 async_fn_multiple_args_named_lifetime(x
, x
).await