at master 1.5 kB view raw
1// SPDX-License-Identifier: Apache-2.0 OR MIT 2 3use std::iter; 4use std::mem::ManuallyDrop; 5use std::ops::{Deref, DerefMut}; 6use std::option; 7use std::slice; 8 9#[repr(transparent)] 10pub(crate) struct NoDrop<T: ?Sized>(ManuallyDrop<T>); 11 12impl<T> NoDrop<T> { 13 pub(crate) fn new(value: T) -> Self 14 where 15 T: TrivialDrop, 16 { 17 NoDrop(ManuallyDrop::new(value)) 18 } 19} 20 21impl<T: ?Sized> Deref for NoDrop<T> { 22 type Target = T; 23 fn deref(&self) -> &Self::Target { 24 &self.0 25 } 26} 27 28impl<T: ?Sized> DerefMut for NoDrop<T> { 29 fn deref_mut(&mut self) -> &mut Self::Target { 30 &mut self.0 31 } 32} 33 34pub(crate) trait TrivialDrop {} 35 36impl<T> TrivialDrop for iter::Empty<T> {} 37impl<T> TrivialDrop for slice::Iter<'_, T> {} 38impl<T> TrivialDrop for slice::IterMut<'_, T> {} 39impl<T> TrivialDrop for option::IntoIter<&T> {} 40impl<T> TrivialDrop for option::IntoIter<&mut T> {} 41 42#[test] 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}