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
use ;
use crate::;
/// Derefencing move operations for [`MoveRef`].
///
/// This trait serves a similar purpose for [`MoveRef`] as [`Deref`](core::ops::Deref) does for
/// normal references.
///
/// In order to implement this trait, the `Self` pointer type must be the *unique owner* of its
/// referent, such that dropping `Self` would cause its referent's destructor to run.
///
/// This is a subtle condition that depends upon the semantics of the `Self` pointer type and must
/// be verified by the implementer, hence the unsafety.
///
/// Examples:
///
/// - [`MoveRef<T>`] implements [`DerefMove`] by definition.
/// - [`Box<T>`](crate::Box<T>) implements [`DerefMove`] because when it drops it destructs `T`.
/// - `&mut T` does *not* implement [`DerefMove`] because it is non-owning.
/// - [`Arc<T>`](crate::Arc<T>) does *not* implement [`DerefMove`] because it is not *uniquely*
/// owning.
/// - [`Rc<T>`](crate::Rc<T>) does *not* implement [`DerefMove`] because it is not *uniquely*
/// owning.
/// - [`Pin<P>`](core::pin::Pin<T>) given `P: DerefMove`, implements [`DerefMove`] only when
/// `P::Target: Unpin`, because `DerefMove: DerefMut` and `Pin<P>: DerefMut` requires `P::Target:
/// Unpin`.
///
/// # Safety
///
/// Correctness for [`DerefMove`] impls require that the unique ownership invariant of [`MoveRef`]
/// is upheld. In particular, the following function *must not* violate memory safety:
/// ```
/// # use moveref::{DerefMove, MoveRef, bind};
/// fn move_out_of<P>(ptr: P) -> P::Target
/// where
/// P: DerefMove,
/// P::Target: Sized,
/// {
/// unsafe {
/// // Move out of `ptr` into a fresh `MoveRef` (backed by a fresh storage `Slot`).
/// bind!(mvp = &move *ptr);
///
/// // From this point on, the `P::Target` destructor must run when, and only when,
/// // the function's return value goes out of scope per the usual Rust rules.
/// //
/// // In particular, the original `ptr` or any pointer it came from must not
/// // run the destructor when they go out of scope, under any circumstance.
/// MoveRef::into_inner(mvp)
/// }
/// }
/// ```
pub unsafe