1 | use std::iter; |
2 | use std::mem::ManuallyDrop; |
3 | use std::ops::{Deref, DerefMut}; |
4 | use std::option; |
5 | use std::slice; |
6 | |
7 | #[repr (transparent)] |
8 | pub(crate) struct NoDrop<T: ?Sized>(ManuallyDrop<T>); |
9 | |
10 | impl<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 | |
19 | impl<T: ?Sized> Deref for NoDrop<T> { |
20 | type Target = T; |
21 | fn deref(&self) -> &Self::Target { |
22 | &self.0 |
23 | } |
24 | } |
25 | |
26 | impl<T: ?Sized> DerefMut for NoDrop<T> { |
27 | fn deref_mut(&mut self) -> &mut Self::Target { |
28 | &mut self.0 |
29 | } |
30 | } |
31 | |
32 | pub(crate) trait TrivialDrop {} |
33 | |
34 | impl<T> TrivialDrop for iter::Empty<T> {} |
35 | impl<'a, T> TrivialDrop for slice::Iter<'a, T> {} |
36 | impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {} |
37 | impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {} |
38 | impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {} |
39 | |
40 | #[test] |
41 | fn 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 | |