aliasable/
mut_ref.rs

1//! Aliasable `&mut`.
2
3use core::fmt;
4use core::marker::PhantomData;
5use core::ops::{Deref, DerefMut};
6use core::pin::Pin;
7use core::ptr::NonNull;
8
9/// Basic aliasable alternative to `&mut`.
10///
11/// Note that this does not circumvent the core aliasing rules of Rust; if you use this to create
12/// multiple mutable references to a memory location at the same time, that is still UB. This type
13/// just adds a few abilities:
14///
15/// - You may hold any number of `AliasableMut`s and no references to a location.
16/// - You may hold any number of `AliasableMut`s and any number of shared references to a location
17/// at once.
18/// - You may hold any number of `AliasableMut`s and one mutable reference to a location at once.
19pub struct AliasableMut<'a, T: ?Sized> {
20    inner: NonNull<T>,
21    _lifetime: PhantomData<&'a ()>,
22}
23
24impl<'a, T: ?Sized> AliasableMut<'a, T> {
25    /// Construct an `AliasableMut` from an `&mut`.
26    #[inline]
27    pub fn from_unique(ptr: &'a mut T) -> Self {
28        Self {
29            inner: NonNull::from(ptr),
30            _lifetime: PhantomData,
31        }
32    }
33
34    /// Consumes `self` and converts it into a non-aliasable `&mut`.
35    #[inline]
36    pub fn into_unique(ptr: Self) -> &'a mut T {
37        unsafe { &mut *ptr.inner.as_ptr() }
38    }
39
40    /// Convert a pinned `AliasableMut` to a pinned `&mut`.
41    pub fn into_unique_pin(pin: Pin<Self>) -> Pin<&'a mut T> {
42        // SAFETY: The pointer is not changed, just the container.
43        unsafe {
44            let aliasable = Pin::into_inner_unchecked(pin);
45            Pin::new_unchecked(Self::into_unique(aliasable))
46        }
47    }
48
49    /// Convert a pinned `&mut` to a pinned `AliasableMut`.
50    pub fn from_unique_pin(pin: Pin<&'a mut T>) -> Pin<Self> {
51        // SAFETY: The pointer is not changed, just the container.
52        unsafe {
53            let unique = Pin::into_inner_unchecked(pin);
54            Pin::new_unchecked(Self::from_unique(unique))
55        }
56    }
57}
58
59impl<'a, T: ?Sized> From<&'a mut T> for AliasableMut<'a, T> {
60    fn from(ptr: &'a mut T) -> Self {
61        Self::from_unique(ptr)
62    }
63}
64
65impl<T: ?Sized> Deref for AliasableMut<'_, T> {
66    type Target = T;
67
68    #[inline]
69    fn deref(&self) -> &Self::Target {
70        // SAFETY: It is the callers responsibility to make sure that there are no `&mut`
71        // references at this point.
72        unsafe { self.inner.as_ref() }
73    }
74}
75
76impl<T: ?Sized> DerefMut for AliasableMut<'_, T> {
77    #[inline]
78    fn deref_mut(&mut self) -> &mut Self::Target {
79        // SAFETY: It is the callers responsibility to make sure that there are no `&mut`
80        // references at this point.
81        unsafe { self.inner.as_mut() }
82    }
83}
84
85impl<T: ?Sized> AsRef<T> for AliasableMut<'_, T> {
86    #[inline]
87    fn as_ref(&self) -> &T {
88        self
89    }
90}
91
92impl<T: ?Sized> AsMut<T> for AliasableMut<'_, T> {
93    #[inline]
94    fn as_mut(&mut self) -> &mut T {
95        self
96    }
97}
98
99impl<T: ?Sized> fmt::Debug for AliasableMut<'_, T>
100where
101    T: fmt::Debug,
102{
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        fmt::Debug::fmt(&**self, f)
105    }
106}
107
108unsafe impl<T: ?Sized> Send for AliasableMut<'_, T> where T: Send {}
109unsafe impl<T: ?Sized> Sync for AliasableMut<'_, T> where T: Sync {}
110
111#[cfg(feature = "traits")]
112unsafe impl<T: ?Sized> crate::StableDeref for AliasableMut<'_, T> {}
113
114#[cfg(feature = "traits")]
115unsafe impl<T: ?Sized> crate::AliasableDeref for AliasableMut<'_, T> {}
116
117#[cfg(test)]
118mod tests {
119    use super::AliasableMut;
120    use alloc::boxed::Box;
121    use alloc::format;
122    use core::pin::Pin;
123
124    #[test]
125    fn test_new() {
126        let mut data = Box::new(10);
127        let aliasable = AliasableMut::from_unique(&mut data);
128        assert_eq!(**aliasable, 10);
129        let unique = AliasableMut::into_unique(aliasable);
130        assert_eq!(**unique, 10);
131    }
132
133    #[test]
134    fn test_new_pin() {
135        let mut data = Box::new(10);
136        let data = unsafe { Pin::new_unchecked(&mut data) };
137        let aliasable = AliasableMut::from_unique_pin(data);
138        assert_eq!(**aliasable, 10);
139        let unique = AliasableMut::into_unique_pin(aliasable);
140        assert_eq!(**unique, 10);
141    }
142
143    #[test]
144    fn test_refs() {
145        let mut data = Box::new(10);
146        let mut aliasable = AliasableMut::from_unique(&mut data);
147        let ptr: *const Box<u8> = &mut *aliasable;
148        let as_mut_ptr: *const Box<u8> = aliasable.as_mut();
149        let as_ref_ptr: *const Box<u8> = aliasable.as_ref();
150        assert_eq!(ptr, as_mut_ptr);
151        assert_eq!(ptr, as_ref_ptr);
152    }
153
154    #[test]
155    fn test_debug() {
156        let mut data = 10;
157        let aliasable = AliasableMut::from_unique(&mut data);
158        assert_eq!(format!("{:?}", aliasable), "10");
159    }
160}