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