diff options
Diffstat (limited to 'tests/ui/drop/repeat-drop.rs')
-rw-r--r-- | tests/ui/drop/repeat-drop.rs | 118 |
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(); +} |