]> git.lizzy.rs Git - rust.git/blob - src/test/ui/issues/issue-40883.rs
Rollup merge of #91804 - woppopo:const_clone, r=oli-obk
[rust.git] / src / test / ui / issues / issue-40883.rs
1 // run-pass
2 #![allow(dead_code)]
3 // check that we don't have linear stack usage with multiple calls to `push`
4
5 #![feature(test)]
6
7 extern crate test;
8 use std::mem;
9
10 fn meal() -> Big {
11     if test::black_box(false) {
12         panic!()
13     }
14     Big { drop_me: [
15         None, None, None, None, None, None, None, None,
16         None, None, None, None, None, None, None, None,
17         None, None, None, None, None, None, None, None,
18         None, None, None, None, None, None, None, None,
19         None, None, None, None, None, None, None, None,
20         None, None, None, None, None, None, None, None,
21     ]}
22 }
23
24 pub struct Big {
25     drop_me: [Option<Box<u8>>; 48],
26 }
27
28 #[inline]
29 fn push(out: &mut Vec<Big>) {
30     out.push(meal());
31 }
32
33 #[inline(never)]
34 pub fn supersize_me(out: &mut Vec<Big>) {
35     push(out);
36     push(out);
37     push(out);
38     push(out);
39     push(out);
40     push(out);
41     push(out);
42     push(out);
43     push(out);
44     push(out);
45     push(out);
46     push(out);
47     push(out);
48     push(out);
49     push(out);
50     push(out); // 16 calls to `push`
51
52     verify_stack_usage(out);
53
54     push(out);
55     push(out);
56     push(out);
57     push(out);
58     push(out);
59     push(out);
60     push(out);
61     push(out);
62     push(out);
63     push(out);
64     push(out);
65     push(out);
66     push(out);
67     push(out);
68     push(out);
69     push(out); // 16 calls to `push`
70 }
71
72 #[inline(never)]
73 fn verify_stack_usage(before_ptr: *mut Vec<Big>) {
74     // To check stack usage, create locals before and after
75     // and check the difference in addresses between them.
76     let mut stack_var: Vec<Big> = vec![];
77     test::black_box(&mut stack_var);
78     let stack_usage = isize::abs(
79         (&mut stack_var as *mut _ as isize) -
80             (before_ptr as isize)) as usize;
81     // Give space for 2 copies of `Big` + 272 "misc" bytes
82     // (value observed on x86_64-pc-windows-gnu).
83     if stack_usage > mem::size_of::<Big>() * 2 + 272 {
84         panic!("used {} bytes of stack, but `struct Big` is only {} bytes",
85                stack_usage, mem::size_of::<Big>());
86     }
87
88 }
89
90 pub fn main() {
91     let mut v = vec![];
92     test::black_box(&mut v);
93     supersize_me(&mut v);
94 }