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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use ::core::mem::ManuallyDrop;

#[cfg(doc)] use crate::Out;

/// Extension trait providing a cast to the [`ManuallyDrop`] type.
///
/// This is useful if you want to use an [`Out`] reference to something that
/// is not `Copy` (potentially because it has drop glue, in which case you
/// either don't mind leaking / skipping that drop glue, or you know you will
/// be manually handling it).
///
/// ⚠️ **Misusage of this function can thus lead to memory leaks** ⚠️
///
/// # Example
///
/// The following fails to compile because of the missing `Copy` bound:
///
/// ```rust,compile_fail
/// use ::uninit::prelude::*;
/// use ::core::cell::Cell;
///
/// let mut cell = Cell::new(0);
/// cell.as_out().write(Cell::new(42)); // Error, not `Copy`
/// assert_eq!(cell.get(), 42);
/// ```
///
/// We see here that the `Copy` bound can be too restrictive. By calling
/// `.manually_drop_mut()`, we no longer need to satisfy this `Copy` bound; but
/// then we need to be careful with memory leaks.
///
/// Since `::core::mem::needs_drop::<Cell<_>>() == false`, there is nothing to
/// worry about:
///
/// ```rust
/// use ::uninit::prelude::*;
/// use ::core::cell::Cell;
///
/// let mut cell = Cell::new(0);
/// cell.manually_drop_mut().as_out().write(Cell::new(42)); // OK
/// assert_eq!(cell.get(), 42);
/// ```
///
/// # Counterexample
///
/// ```rust
/// use ::uninit::prelude::*;
/// use ::std::rc::Rc;
///
/// let rc = Rc::new(());
/// assert_eq!(Rc::strong_count(&rc), 1);
/// let mut rc2 = Some(Rc::clone(&rc));
/// assert_eq!(Rc::strong_count(&rc), 2);
/// // This overwrites `rc2` without running any destructor whatsoever, hence
/// // leaking the `rc` clone.
/// rc2.manually_drop_mut().as_out().write(None);
/// assert_eq!(Rc::strong_count(&rc), 2);
/// assert!(Rc::try_unwrap(rc).is_err());
/// ```
#[allow(missing_docs)]
pub
trait ManuallyDropMut {
    type Ret : ?Sized;

    fn manually_drop_mut (self: &'_ mut Self)
      -> &'_ mut Self::Ret
    ;
}

impl<T> ManuallyDropMut for [T] {
    type Ret = [ManuallyDrop<T>];

    #[inline]
    fn manually_drop_mut<'__> (self: &'__ mut [T])
      -> &'__ mut [ManuallyDrop<T>]
    {
        let len = self.len();
        unsafe {
            // Safety: `ManuallyDrop<T>` is `#[repr(transparent)]`
            ::core::slice::from_raw_parts_mut(
                self.as_mut_ptr().cast(), len,
            )
        }
    }
}

impl<T> ManuallyDropMut for T {
    type Ret = ManuallyDrop<T>;

    #[inline]
    fn manually_drop_mut<'__> (self: &'__ mut T)
      -> &'__ mut ManuallyDrop<T>
    {
        unsafe {
            // Safety: `ManuallyDrop<T>` is `#[repr(transparent)]`
            ::core::mem::transmute(self)
        }
    }
}