#![allow(undropped_manually_drops)] use core::mem::ManuallyDrop; #[test] fn smoke() { #[derive(Clone)] struct TypeWithDrop; impl Drop for TypeWithDrop { fn drop(&mut self) { unreachable!("Should not get dropped"); } } let x = ManuallyDrop::new(TypeWithDrop); drop(x); // also test unsizing let x: Box> = Box::new(ManuallyDrop::new([TypeWithDrop, TypeWithDrop])); drop(x); // test clone and clone_from implementations let mut x = ManuallyDrop::new(TypeWithDrop); let y = x.clone(); x.clone_from(&y); drop(x); drop(y); } #[test] fn const_drop_in_place() { const COUNTER: usize = { use core::cell::Cell; let counter = Cell::new(0); // only exists to make `Drop` indirect impl #[allow(dead_code)] struct Test<'a>(Dropped<'a>); struct Dropped<'a>(&'a Cell); impl const Drop for Dropped<'_> { fn drop(&mut self) { self.0.set(self.0.get() + 1); } } let mut one = ManuallyDrop::new(Test(Dropped(&counter))); let mut two = ManuallyDrop::new(Test(Dropped(&counter))); let mut three = ManuallyDrop::new(Test(Dropped(&counter))); assert!(counter.get() == 0); unsafe { ManuallyDrop::drop(&mut one); } assert!(counter.get() == 1); unsafe { ManuallyDrop::drop(&mut two); } assert!(counter.get() == 2); unsafe { ManuallyDrop::drop(&mut three); } counter.get() }; assert_eq!(COUNTER, 3); }