]> git.lizzy.rs Git - rust.git/blob - src/test/ui/drop/repeat-drop.rs
Rollup merge of #106043 - c410-f3r:moar-errors, r=petrochenkov
[rust.git] / src / test / ui / drop / repeat-drop.rs
1 // run-pass
2 // needs-unwind
3
4 static mut CHECK: usize = 0;
5
6 struct DropChecker(usize);
7
8 impl Drop for DropChecker {
9     fn drop(&mut self) {
10         unsafe {
11             if CHECK != self.0 - 1 {
12                 panic!("Found {}, should have found {}", CHECK, self.0 - 1);
13             }
14             CHECK = self.0;
15         }
16     }
17 }
18
19 macro_rules! check_drops {
20     ($l:literal) => {
21         unsafe { assert_eq!(CHECK, $l) }
22     };
23 }
24
25 struct DropPanic;
26
27 impl Drop for DropPanic {
28     fn drop(&mut self) {
29         panic!()
30     }
31 }
32
33 fn value_zero() {
34     unsafe { CHECK = 0 };
35     let foo = DropChecker(1);
36     let v: [DropChecker; 0] = [foo; 0];
37     check_drops!(1);
38     std::mem::drop(v);
39     check_drops!(1);
40 }
41
42 fn value_one() {
43     unsafe { CHECK = 0 };
44     let foo = DropChecker(1);
45     let v: [DropChecker; 1] = [foo; 1];
46     check_drops!(0);
47     std::mem::drop(v);
48     check_drops!(1);
49 }
50
51 const DROP_CHECKER: DropChecker = DropChecker(1);
52
53 fn const_zero() {
54     unsafe { CHECK = 0 };
55     let v: [DropChecker; 0] = [DROP_CHECKER; 0];
56     check_drops!(0);
57     std::mem::drop(v);
58     check_drops!(0);
59 }
60
61 fn const_one() {
62     unsafe { CHECK = 0 };
63     let v: [DropChecker; 1] = [DROP_CHECKER; 1];
64     check_drops!(0);
65     std::mem::drop(v);
66     check_drops!(1);
67 }
68
69 fn const_generic_zero<const N: usize>() {
70     unsafe { CHECK = 0 };
71     let v: [DropChecker; N] = [DROP_CHECKER; N];
72     check_drops!(0);
73     std::mem::drop(v);
74     check_drops!(0);
75 }
76
77 fn const_generic_one<const N: usize>() {
78     unsafe { CHECK = 0 };
79     let v: [DropChecker; N] = [DROP_CHECKER; N];
80     check_drops!(0);
81     std::mem::drop(v);
82     check_drops!(1);
83 }
84
85 // Make sure that things are allowed to promote as expected
86
87 fn allow_promote() {
88     unsafe { CHECK = 0 };
89     let foo = DropChecker(1);
90     let v: &'static [DropChecker; 0] = &[foo; 0];
91     check_drops!(1);
92     std::mem::drop(v);
93     check_drops!(1);
94 }
95
96 // Verify that unwinding in the drop causes the right things to drop in the right order
97 fn on_unwind() {
98     unsafe { CHECK = 0 };
99     std::panic::catch_unwind(|| {
100         let panic = DropPanic;
101         let _local = DropChecker(2);
102         let _v = (DropChecker(1), [panic; 0]);
103         std::process::abort();
104     })
105     .unwrap_err();
106     check_drops!(2);
107 }
108
109 fn main() {
110     value_zero();
111     value_one();
112     const_zero();
113     const_one();
114     const_generic_zero::<0>();
115     const_generic_one::<1>();
116     allow_promote();
117     on_unwind();
118 }