| 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<T> TrivialDrop for slice::Iter<'_, T> {} |
| 36 | impl<T> TrivialDrop for slice::IterMut<'_, T> {} |
| 37 | impl<T> TrivialDrop for option::IntoIter<&T> {} |
| 38 | impl<T> TrivialDrop for option::IntoIter<&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 | |