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