    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58

    use std::iter;
    use std::mem::ManuallyDrop;
    use std::ops::{Deref, DerefMut};
    use std::option;
    use std::slice;

    #[repr(transparent)]
    pub(crate) struct NoDrop<T: ?Sized>(ManuallyDrop<T>);

    impl<T> NoDrop<T> {
        pub(crate) fn new(value: T) -> Self
        where
            T: TrivialDrop,
        {
            NoDrop(ManuallyDrop::new(value))
        }
    }

    impl<T: ?Sized> Deref for NoDrop<T> {
        type Target = T;
        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    impl<T: ?Sized> DerefMut for NoDrop<T> {
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.0
        }
    }

    pub(crate) trait TrivialDrop {}

    impl<T> TrivialDrop for iter::Empty<T> {}
    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::<NeedsDrop>());

        // Test each of the types with a handwritten TrivialDrop impl above.
        assert!(!needs_drop::<iter::Empty<NeedsDrop>>());
        assert!(!needs_drop::<slice::Iter<NeedsDrop>>());
        assert!(!needs_drop::<slice::IterMut<NeedsDrop>>());
        assert!(!needs_drop::<option::IntoIter<&NeedsDrop>>());
        assert!(!needs_drop::<option::IntoIter<&mut NeedsDrop>>());
    }