]> git.lizzy.rs Git - rust.git/blob - tests/ui/async-await/async-fn-size-moved-locals.rs
Rollup merge of #107076 - megakorre:106419_add_test_case, r=compiler-errors
[rust.git] / tests / ui / async-await / async-fn-size-moved-locals.rs
1 // Test that we don't duplicate storage for futures moved around in .await, and
2 // for futures moved into other futures.
3 //
4 // The exact sizes can change by a few bytes (we'd like to know when they do).
5 // What we don't want to see is the wrong multiple of 1024 (the size of BigFut)
6 // being reflected in the size.
7 //
8 // See issue #59123 for a full explanation.
9
10 // needs-unwind Size of Futures change on panic=abort
11 // run-pass
12
13 // edition:2018
14
15 use std::future::Future;
16 use std::pin::Pin;
17 use std::task::{Context, Poll};
18
19 const BIG_FUT_SIZE: usize = 1024;
20 struct BigFut(#[allow(unused_tuple_struct_fields)] [u8; BIG_FUT_SIZE]);
21
22 impl BigFut {
23     fn new() -> Self {
24         BigFut([0; BIG_FUT_SIZE])
25     }
26 }
27
28 impl Drop for BigFut {
29     fn drop(&mut self) {}
30 }
31
32 impl Future for BigFut {
33     type Output = ();
34
35     fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll<Self::Output> {
36         Poll::Ready(())
37     }
38 }
39
40 #[allow(dead_code)]
41 struct Joiner {
42     a: Option<BigFut>,
43     b: Option<BigFut>,
44     c: Option<BigFut>,
45 }
46
47 impl Future for Joiner {
48     type Output = ();
49
50     fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll<Self::Output> {
51         Poll::Ready(())
52     }
53 }
54
55 fn noop() {}
56
57 async fn single() {
58     let x = BigFut::new();
59     x.await;
60 }
61
62 async fn single_with_noop() {
63     let x = BigFut::new();
64     noop();
65     x.await;
66 }
67
68 async fn joined() {
69     let a = BigFut::new();
70     let b = BigFut::new();
71     let c = BigFut::new();
72
73     let joiner = Joiner {
74         a: Some(a),
75         b: Some(b),
76         c: Some(c),
77     };
78     joiner.await
79 }
80
81 async fn joined_with_noop() {
82     let a = BigFut::new();
83     let b = BigFut::new();
84     let c = BigFut::new();
85
86     let joiner = Joiner {
87         a: Some(a),
88         b: Some(b),
89         c: Some(c),
90     };
91     noop();
92     joiner.await
93 }
94
95 async fn mixed_sizes() {
96     let a = BigFut::new();
97     let b = BigFut::new();
98     let c = BigFut::new();
99     let d = BigFut::new();
100     let e = BigFut::new();
101     let joiner = Joiner {
102         a: Some(a),
103         b: Some(b),
104         c: Some(c),
105     };
106
107     d.await;
108     e.await;
109     joiner.await;
110 }
111
112 fn main() {
113     assert_eq!(1025, std::mem::size_of_val(&single()));
114     assert_eq!(1026, std::mem::size_of_val(&single_with_noop()));
115     assert_eq!(3076, std::mem::size_of_val(&joined()));
116     assert_eq!(3076, std::mem::size_of_val(&joined_with_noop()));
117     assert_eq!(6157, std::mem::size_of_val(&mixed_sizes()));
118 }