|  | 
|  | 1 | +#![deny(missing_docs, missing_debug_implementations)] | 
|  | 2 | +//! This library defines the `PinCell` type, a pinning variant of the standard | 
|  | 3 | +//! library's `RefCell`. | 
|  | 4 | +//! | 
|  | 5 | +//! It is not safe to "pin project" through a `RefCell` - getting a pinned | 
|  | 6 | +//! reference to something inside the `RefCell` when you have a pinned | 
|  | 7 | +//! refernece to the `RefCell` - because `RefCell` is too powerful. | 
|  | 8 | +//! | 
|  | 9 | +//! A `PinCell` is slightly less powerful than `RefCell`: unlike a `RefCell`, | 
|  | 10 | +//! one cannot get a mutable reference into a `PinCell`, only a pinned mutable | 
|  | 11 | +//! reference (`Pin<&mut T>`). This makes pin projection safe, allowing you | 
|  | 12 | +//! to use interior mutability with the knowledge that `T` will never actually | 
|  | 13 | +//! be moved out of the `RefCell` that wraps it. | 
|  | 14 | +
 | 
|  | 15 | +mod pin_ref; | 
|  | 16 | +mod pin_mut; | 
|  | 17 | + | 
|  | 18 | +use core::cell::{RefCell, RefMut, BorrowMutError}; | 
|  | 19 | +use core::pin::Pin; | 
|  | 20 | + | 
|  | 21 | +pub use pin_ref::PinRef; | 
|  | 22 | +pub use pin_mut::PinMut; | 
|  | 23 | + | 
|  | 24 | +/// A mutable memory location with dynamically checked borrow rules | 
|  | 25 | +/// | 
|  | 26 | +/// Unlike `RefCell`, this type only allows *pinned* mutable access to the | 
|  | 27 | +/// inner value, enabling a "pin-safe" version of interior mutability. | 
|  | 28 | +/// | 
|  | 29 | +/// See the standard library documentation for more information. | 
|  | 30 | +#[derive(Default, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] | 
|  | 31 | +pub struct PinCell<T: ?Sized> { | 
|  | 32 | +    inner: RefCell<T>, | 
|  | 33 | +} | 
|  | 34 | + | 
|  | 35 | +impl<T> PinCell<T> { | 
|  | 36 | +    /// Creates a new `PinCell` containing `value`. | 
|  | 37 | +    pub const fn new(value: T) -> PinCell<T> { | 
|  | 38 | +        PinCell { inner: RefCell::new(value) } | 
|  | 39 | +    } | 
|  | 40 | +} | 
|  | 41 | + | 
|  | 42 | +impl<T: ?Sized> PinCell<T> { | 
|  | 43 | +    /// Mutably borrows the wrapped value, preserving its pinnedness. | 
|  | 44 | +    /// | 
|  | 45 | +    /// The borrow lasts until the returned `PinMut` or all `PinMut`s derived | 
|  | 46 | +    /// from it exit scope. The value cannot be borrowed while this borrow is | 
|  | 47 | +    /// active. | 
|  | 48 | +    pub fn borrow_mut<'a>(self: Pin<&'a Self>) -> PinMut<'a, T> { | 
|  | 49 | +        self.try_borrow_mut().expect("already borrowed") | 
|  | 50 | +    } | 
|  | 51 | + | 
|  | 52 | +    /// Mutably borrows the wrapped value, preserving its pinnedness, | 
|  | 53 | +    /// returning an error if the value is currently borrowed. | 
|  | 54 | +    /// | 
|  | 55 | +    /// The borrow lasts until the returned `PinMut` or all `PinMut`s derived | 
|  | 56 | +    /// from it exit scope. The value cannot be borrowed while this borrow is | 
|  | 57 | +    /// active. | 
|  | 58 | +    /// | 
|  | 59 | +    /// This is the non-panicking variant of `borrow_mut`. | 
|  | 60 | +    pub fn try_borrow_mut<'a>(self: Pin<&'a Self>) -> Result<PinMut<'a, T>, BorrowMutError> { | 
|  | 61 | +        let ref_mut: RefMut<'a, T> = Pin::get_ref(self).inner.try_borrow_mut()?; | 
|  | 62 | + | 
|  | 63 | +        // this is a pin projection from Pin<&PinCell<T>> to Pin<RefMut<T>> | 
|  | 64 | +        // projecting is safe because: | 
|  | 65 | +        // | 
|  | 66 | +        // - for<T: ?Sized> (PinCell<T>: Unpin) imples (RefMut<T>: Unpin) | 
|  | 67 | +        //   holds true | 
|  | 68 | +        // - PinCell does not implement Drop | 
|  | 69 | +        // | 
|  | 70 | +        // see discussion on tracking issue #49150 about pin projection | 
|  | 71 | +        // invariants | 
|  | 72 | +        let pin_ref_mut: Pin<RefMut<'a, T>> = unsafe { | 
|  | 73 | +            Pin::new_unchecked(ref_mut) | 
|  | 74 | +        }; | 
|  | 75 | + | 
|  | 76 | +        Ok(PinMut { inner: pin_ref_mut }) | 
|  | 77 | +    } | 
|  | 78 | +} | 
|  | 79 | + | 
|  | 80 | +impl<T> From<T> for PinCell<T> { | 
|  | 81 | +    fn from(value: T) -> PinCell<T> { | 
|  | 82 | +        PinCell::new(value) | 
|  | 83 | +    } | 
|  | 84 | +} | 
|  | 85 | + | 
|  | 86 | +impl<T> From<RefCell<T>> for PinCell<T> { | 
|  | 87 | +    fn from(cell: RefCell<T>) -> PinCell<T> { | 
|  | 88 | +        PinCell { inner: cell } | 
|  | 89 | +    } | 
|  | 90 | +} | 
|  | 91 | + | 
|  | 92 | +impl<T> Into<RefCell<T>> for PinCell<T> { | 
|  | 93 | +    fn into(self) -> RefCell<T> { | 
|  | 94 | +        self.inner | 
|  | 95 | +    } | 
|  | 96 | +} | 
|  | 97 | + | 
|  | 98 | +// TODO CoerceUnsized | 
0 commit comments