]>
Commit | Line | Data |
---|---|---|
923072b8 FG |
1 | // run-pass |
2 | // needs-unwind | |
923072b8 FG |
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 | } |