1//! Aliasable `&mut`.
23use core::fmt;
4use core::marker::PhantomData;
5use core::ops::{Deref, DerefMut};
6use core::pin::Pin;
7use core::ptr::NonNull;
89/// 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}
2324impl<'a, T: ?Sized> AliasableMut<'a, T> {
25/// Construct an `AliasableMut` from an `&mut`.
26#[inline]
27pub fn from_unique(ptr: &'a mut T) -> Self {
28Self {
29 inner: NonNull::from(ptr),
30 _lifetime: PhantomData,
31 }
32 }
3334/// Consumes `self` and converts it into a non-aliasable `&mut`.
35#[inline]
36pub fn into_unique(ptr: Self) -> &'a mut T {
37unsafe { &mut *ptr.inner.as_ptr() }
38 }
3940/// Convert a pinned `AliasableMut` to a pinned `&mut`.
41pub fn into_unique_pin(pin: Pin<Self>) -> Pin<&'a mut T> {
42// SAFETY: The pointer is not changed, just the container.
43unsafe {
44let aliasable = Pin::into_inner_unchecked(pin);
45 Pin::new_unchecked(Self::into_unique(aliasable))
46 }
47 }
4849/// Convert a pinned `&mut` to a pinned `AliasableMut`.
50pub fn from_unique_pin(pin: Pin<&'a mut T>) -> Pin<Self> {
51// SAFETY: The pointer is not changed, just the container.
52unsafe {
53let unique = Pin::into_inner_unchecked(pin);
54 Pin::new_unchecked(Self::from_unique(unique))
55 }
56 }
57}
5859impl<'a, T: ?Sized> From<&'a mut T> for AliasableMut<'a, T> {
60fn from(ptr: &'a mut T) -> Self {
61Self::from_unique(ptr)
62 }
63}
6465impl<T: ?Sized> Deref for AliasableMut<'_, T> {
66type Target = T;
6768#[inline]
69fn deref(&self) -> &Self::Target {
70// SAFETY: It is the callers responsibility to make sure that there are no `&mut`
71 // references at this point.
72unsafe { self.inner.as_ref() }
73 }
74}
7576impl<T: ?Sized> DerefMut for AliasableMut<'_, T> {
77#[inline]
78fn 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.
81unsafe { self.inner.as_mut() }
82 }
83}
8485impl<T: ?Sized> AsRef<T> for AliasableMut<'_, T> {
86#[inline]
87fn as_ref(&self) -> &T {
88self
89}
90}
9192impl<T: ?Sized> AsMut<T> for AliasableMut<'_, T> {
93#[inline]
94fn as_mut(&mut self) -> &mut T {
95self
96}
97}
9899impl<T: ?Sized> fmt::Debug for AliasableMut<'_, T>
100where
101T: fmt::Debug,
102{
103fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 fmt::Debug::fmt(&**self, f)
105 }
106}
107108unsafe impl<T: ?Sized> Send for AliasableMut<'_, T> where T: Send {}
109unsafe impl<T: ?Sized> Sync for AliasableMut<'_, T> where T: Sync {}
110111#[cfg(feature = "traits")]
112unsafe impl<T: ?Sized> crate::StableDeref for AliasableMut<'_, T> {}
113114#[cfg(feature = "traits")]
115unsafe impl<T: ?Sized> crate::AliasableDeref for AliasableMut<'_, T> {}
116117#[cfg(test)]
118mod tests {
119use super::AliasableMut;
120use alloc::boxed::Box;
121use alloc::format;
122use core::pin::Pin;
123124#[test]
125fn test_new() {
126let mut data = Box::new(10);
127let aliasable = AliasableMut::from_unique(&mut data);
128assert_eq!(**aliasable, 10);
129let unique = AliasableMut::into_unique(aliasable);
130assert_eq!(**unique, 10);
131 }
132133#[test]
134fn test_new_pin() {
135let mut data = Box::new(10);
136let data = unsafe { Pin::new_unchecked(&mut data) };
137let aliasable = AliasableMut::from_unique_pin(data);
138assert_eq!(**aliasable, 10);
139let unique = AliasableMut::into_unique_pin(aliasable);
140assert_eq!(**unique, 10);
141 }
142143#[test]
144fn test_refs() {
145let mut data = Box::new(10);
146let mut aliasable = AliasableMut::from_unique(&mut data);
147let ptr: *const Box<u8> = &mut *aliasable;
148let as_mut_ptr: *const Box<u8> = aliasable.as_mut();
149let as_ref_ptr: *const Box<u8> = aliasable.as_ref();
150assert_eq!(ptr, as_mut_ptr);
151assert_eq!(ptr, as_ref_ptr);
152 }
153154#[test]
155fn test_debug() {
156let mut data = 10;
157let aliasable = AliasableMut::from_unique(&mut data);
158assert_eq!(format!("{:?}", aliasable), "10");
159 }
160}