summaryrefslogtreecommitdiffstats
path: root/src/test/ui/drop/repeat-drop.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/drop/repeat-drop.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/drop/repeat-drop.rs')
-rw-r--r--src/test/ui/drop/repeat-drop.rs121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/test/ui/drop/repeat-drop.rs b/src/test/ui/drop/repeat-drop.rs
new file mode 100644
index 000000000..a43612e5d
--- /dev/null
+++ b/src/test/ui/drop/repeat-drop.rs
@@ -0,0 +1,121 @@
+// run-pass
+// needs-unwind
+// ignore-wasm32-bare no unwinding panic
+// ignore-avr no unwinding panic
+// ignore-nvptx64 no unwinding panic
+
+static mut CHECK: usize = 0;
+
+struct DropChecker(usize);
+
+impl Drop for DropChecker {
+ fn drop(&mut self) {
+ unsafe {
+ if CHECK != self.0 - 1 {
+ panic!("Found {}, should have found {}", CHECK, self.0 - 1);
+ }
+ CHECK = self.0;
+ }
+ }
+}
+
+macro_rules! check_drops {
+ ($l:literal) => {
+ unsafe { assert_eq!(CHECK, $l) }
+ };
+}
+
+struct DropPanic;
+
+impl Drop for DropPanic {
+ fn drop(&mut self) {
+ panic!()
+ }
+}
+
+fn value_zero() {
+ unsafe { CHECK = 0 };
+ let foo = DropChecker(1);
+ let v: [DropChecker; 0] = [foo; 0];
+ check_drops!(1);
+ std::mem::drop(v);
+ check_drops!(1);
+}
+
+fn value_one() {
+ unsafe { CHECK = 0 };
+ let foo = DropChecker(1);
+ let v: [DropChecker; 1] = [foo; 1];
+ check_drops!(0);
+ std::mem::drop(v);
+ check_drops!(1);
+}
+
+const DROP_CHECKER: DropChecker = DropChecker(1);
+
+fn const_zero() {
+ unsafe { CHECK = 0 };
+ let v: [DropChecker; 0] = [DROP_CHECKER; 0];
+ check_drops!(0);
+ std::mem::drop(v);
+ check_drops!(0);
+}
+
+fn const_one() {
+ unsafe { CHECK = 0 };
+ let v: [DropChecker; 1] = [DROP_CHECKER; 1];
+ check_drops!(0);
+ std::mem::drop(v);
+ check_drops!(1);
+}
+
+fn const_generic_zero<const N: usize>() {
+ unsafe { CHECK = 0 };
+ let v: [DropChecker; N] = [DROP_CHECKER; N];
+ check_drops!(0);
+ std::mem::drop(v);
+ check_drops!(0);
+}
+
+fn const_generic_one<const N: usize>() {
+ unsafe { CHECK = 0 };
+ let v: [DropChecker; N] = [DROP_CHECKER; N];
+ check_drops!(0);
+ std::mem::drop(v);
+ check_drops!(1);
+}
+
+// Make sure that things are allowed to promote as expected
+
+fn allow_promote() {
+ unsafe { CHECK = 0 };
+ let foo = DropChecker(1);
+ let v: &'static [DropChecker; 0] = &[foo; 0];
+ check_drops!(1);
+ std::mem::drop(v);
+ check_drops!(1);
+}
+
+// Verify that unwinding in the drop causes the right things to drop in the right order
+fn on_unwind() {
+ unsafe { CHECK = 0 };
+ std::panic::catch_unwind(|| {
+ let panic = DropPanic;
+ let _local = DropChecker(2);
+ let _v = (DropChecker(1), [panic; 0]);
+ std::process::abort();
+ })
+ .unwrap_err();
+ check_drops!(2);
+}
+
+fn main() {
+ value_zero();
+ value_one();
+ const_zero();
+ const_one();
+ const_generic_zero::<0>();
+ const_generic_one::<1>();
+ allow_promote();
+ on_unwind();
+}