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