2023-07-12 21:38:55 -04:00
|
|
|
#![allow(undropped_manually_drops)]
|
2023-05-13 12:13:37 +02:00
|
|
|
|
2018-07-27 12:12:55 +02:00
|
|
|
use core::mem::ManuallyDrop;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn smoke() {
|
2021-07-05 11:55:45 +00:00
|
|
|
#[derive(Clone)]
|
2018-07-27 12:12:55 +02:00
|
|
|
struct TypeWithDrop;
|
|
|
|
|
impl Drop for TypeWithDrop {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
unreachable!("Should not get dropped");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let x = ManuallyDrop::new(TypeWithDrop);
|
|
|
|
|
drop(x);
|
2018-08-03 18:02:34 +02:00
|
|
|
|
|
|
|
|
// also test unsizing
|
2019-12-06 20:18:12 -08:00
|
|
|
let x: Box<ManuallyDrop<[TypeWithDrop]>> =
|
2018-08-06 15:52:36 +02:00
|
|
|
Box::new(ManuallyDrop::new([TypeWithDrop, TypeWithDrop]));
|
2018-08-03 18:02:34 +02:00
|
|
|
drop(x);
|
2021-07-05 11:55:45 +00:00
|
|
|
|
|
|
|
|
// test clone and clone_from implementations
|
|
|
|
|
let mut x = ManuallyDrop::new(TypeWithDrop);
|
|
|
|
|
let y = x.clone();
|
|
|
|
|
x.clone_from(&y);
|
|
|
|
|
drop(x);
|
|
|
|
|
drop(y);
|
2018-07-27 12:12:55 +02:00
|
|
|
}
|
2025-10-19 02:44:41 -04:00
|
|
|
|
|
|
|
|
#[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);
|
|
|
|
|
}
|