drops.rs 1.4 KB

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