rune_alloc/btree/
borrow.rs

1use core::marker::PhantomData;
2
3use crate::ptr::NonNull;
4
5/// Models a reborrow of some unique reference, when you know that the reborrow
6/// and all its descendants (i.e., all pointers and references derived from it)
7/// will not be used any more at some point, after which you want to use the
8/// original unique reference again.
9///
10/// The borrow checker usually handles this stacking of borrows for you, but
11/// some control flows that accomplish this stacking are too complicated for
12/// the compiler to follow. A `DormantMutRef` allows you to check borrowing
13/// yourself, while still expressing its stacked nature, and encapsulating
14/// the raw pointer code needed to do this without undefined behavior.
15pub(crate) struct DormantMutRef<'a, T> {
16    ptr: NonNull<T>,
17    _marker: PhantomData<&'a mut T>,
18}
19
20unsafe impl<'a, T> Sync for DormantMutRef<'a, T> where &'a mut T: Sync {}
21unsafe impl<'a, T> Send for DormantMutRef<'a, T> where &'a mut T: Send {}
22
23impl<'a, T> DormantMutRef<'a, T> {
24    /// Capture a unique borrow, and immediately reborrow it. For the compiler,
25    /// the lifetime of the new reference is the same as the lifetime of the
26    /// original reference, but you promise to use it for a shorter period.
27    pub(crate) fn new(t: &'a mut T) -> (&'a mut T, Self) {
28        let ptr = NonNull::from(t);
29        // SAFETY: we hold the borrow throughout 'a via `_marker`, and we expose
30        // only this reference, so it is unique.
31        let new_ref = unsafe { &mut *ptr.as_ptr() };
32        (
33            new_ref,
34            Self {
35                ptr,
36                _marker: PhantomData,
37            },
38        )
39    }
40
41    /// Revert to the unique borrow initially captured.
42    ///
43    /// # Safety
44    ///
45    /// The reborrow must have ended, i.e., the reference returned by `new` and
46    /// all pointers and references derived from it, must not be used anymore.
47    pub(crate) unsafe fn awaken(self) -> &'a mut T {
48        // SAFETY: our own safety conditions imply this reference is again unique.
49        unsafe { &mut *self.ptr.as_ptr() }
50    }
51
52    /// Borrows a new mutable reference from the unique borrow initially captured.
53    ///
54    /// # Safety
55    ///
56    /// The reborrow must have ended, i.e., the reference returned by `new` and
57    /// all pointers and references derived from it, must not be used anymore.
58    pub(crate) unsafe fn reborrow(&mut self) -> &'a mut T {
59        // SAFETY: our own safety conditions imply this reference is again unique.
60        unsafe { &mut *self.ptr.as_ptr() }
61    }
62}