1use std::iter;
2use std::mem::ManuallyDrop;
3use std::ops::{Deref, DerefMut};
4use std::option;
5use std::slice;
6
7#[repr(transparent)]
8pub(crate) struct NoDrop<T: ?Sized>(ManuallyDrop<T>);
9
10impl<T> NoDrop<T> {
11 pub(crate) fn new(value: T) -> Self
12 where
13 T: TrivialDrop,
14 {
15 NoDrop(ManuallyDrop::new(value))
16 }
17}
18
19impl<T: ?Sized> Deref for NoDrop<T> {
20 type Target = T;
21 fn deref(&self) -> &Self::Target {
22 &self.0
23 }
24}
25
26impl<T: ?Sized> DerefMut for NoDrop<T> {
27 fn deref_mut(&mut self) -> &mut Self::Target {
28 &mut self.0
29 }
30}
31
32pub(crate) trait TrivialDrop {}
33
34impl<T> TrivialDrop for iter::Empty<T> {}
35impl<'a, T> TrivialDrop for slice::Iter<'a, T> {}
36impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {}
37impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {}
38impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {}
39
40#[test]
41fn test_needs_drop() {
42 use std::mem::needs_drop;
43
44 struct NeedsDrop;
45
46 impl Drop for NeedsDrop {
47 fn drop(&mut self) {}
48 }
49
50 assert!(needs_drop::<NeedsDrop>());
51
52 // Test each of the types with a handwritten TrivialDrop impl above.
53 assert!(!needs_drop::<iter::Empty<NeedsDrop>>());
54 assert!(!needs_drop::<slice::Iter<NeedsDrop>>());
55 assert!(!needs_drop::<slice::IterMut<NeedsDrop>>());
56 assert!(!needs_drop::<option::IntoIter<&NeedsDrop>>());
57 assert!(!needs_drop::<option::IntoIter<&mut NeedsDrop>>());
58}
59