blob: 1638c82b161b4fa0c3c784668258df6e77c90729 [file] [log] [blame] [edit]
#![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<ManuallyDrop<[TypeWithDrop]>> =
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<usize>);
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);
}