summaryrefslogtreecommitdiffstats
path: root/tests/ui/drop/repeat-drop.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/drop/repeat-drop.rs
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/drop/repeat-drop.rs')
-rw-r--r--tests/ui/drop/repeat-drop.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs
new file mode 100644
index 000000000..8fd46ecaf
--- /dev/null
+++ b/tests/ui/drop/repeat-drop.rs
@@ -0,0 +1,118 @@
+// run-pass
+// needs-unwind
+
+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();
+}