use std::iter; use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut}; use std::option; use std::slice; #[repr(transparent)] pub(crate) struct NoDrop(ManuallyDrop); impl NoDrop { pub(crate) fn new(value: T) -> Self where T: TrivialDrop, { NoDrop(ManuallyDrop::new(value)) } } impl Deref for NoDrop { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for NoDrop { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } pub(crate) trait TrivialDrop {} impl TrivialDrop for iter::Empty {} impl<'a, T> TrivialDrop for slice::Iter<'a, T> {} impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {} impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {} impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {} #[test] fn test_needs_drop() { use std::mem::needs_drop; struct NeedsDrop; impl Drop for NeedsDrop { fn drop(&mut self) {} } assert!(needs_drop::()); // Test each of the types with a handwritten TrivialDrop impl above. assert!(!needs_drop::>()); assert!(!needs_drop::>()); assert!(!needs_drop::>()); assert!(!needs_drop::>()); assert!(!needs_drop::>()); }