]> git.lizzy.rs Git - rust.git/blob - src/test/ui/async-await/async-fn-send-uses-nonsend.rs
Add more tests for async/await
[rust.git] / src / test / ui / async-await / async-fn-send-uses-nonsend.rs
1 // compile-pass
2 // edition:2018
3 // compile-flags: --crate-type lib
4
5 #![feature(async_await)]
6
7 use std::{
8     cell::RefCell,
9     fmt::Debug,
10     rc::Rc,
11 };
12
13 fn non_sync() -> impl Debug { RefCell::new(()) }
14
15 fn non_send() -> impl Debug { Rc::new(()) }
16
17 fn take_ref<T>(_: &T) {}
18
19 async fn fut() {}
20
21 async fn fut_arg<T>(_: T) {}
22
23 async fn still_send() {
24     fut().await;
25     println!("{:?} {:?}", non_send(), non_sync());
26     fut().await;
27     drop(non_send());
28     drop(non_sync());
29     fut().await;
30     fut_arg(non_sync()).await;
31
32     // Note: all temporaries in `if let` and `match` scrutinee
33     // are dropped at the *end* of the blocks, so using `non_send()`
34     // in either of those positions with an await in the middle will
35     // cause a `!Send` future. It might be nice in the future to allow
36     // this for `Copy` types, since they can be "dropped" early without
37     // affecting the end user.
38     if let Some(_) = Some(non_sync()) {
39         fut().await;
40     }
41     match Some(non_sync()) {
42         Some(_) => fut().await,
43         None => fut().await,
44     }
45
46     let _ = non_send();
47     fut().await;
48
49     {
50         let _x = non_send();
51     }
52     fut().await;
53 }
54
55 fn assert_send(_: impl Send) {}
56
57 pub fn pass_assert() {
58     assert_send(still_send());
59 }