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