pub struct UnsafePinned<T>where
T: ?Sized,{ /* private fields */ }
unsafe_pinned
#125735)Expand description
This type provides a way to opt-out of typical aliasing rules;
specifically, &mut UnsafePinned<T>
is not guaranteed to be a unique pointer.
However, even if you define your type like pub struct Wrapper(UnsafePinned<...>)
, it is still
very risky to have an &mut Wrapper
that aliases anything else. Many functions that work
generically on &mut T
assume that the memory that stores T
is uniquely owned (such as
mem::swap
). In other words, while having aliasing with &mut Wrapper
is not immediate
Undefined Behavior, it is still unsound to expose such a mutable reference to code you do not
control! Techniques such as pinning via Pin
are needed to ensure soundness.
Similar to UnsafeCell
, UnsafePinned
will not usually show up in
the public API of a library. It is an internal implementation detail of libraries that need to
support aliasing mutable references.
Further note that this does not lift the requirement that shared references must be read-only!
Use UnsafeCell
for that.
This type blocks niches the same way UnsafeCell
does.
Implementations§
Source§impl<T> UnsafePinned<T>
impl<T> UnsafePinned<T>
Sourcepub const fn new(value: T) -> UnsafePinned<T>
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn new(value: T) -> UnsafePinned<T>
unsafe_pinned
#125735)Constructs a new instance of UnsafePinned
which will wrap the specified value.
All access to the inner value through &UnsafePinned<T>
or &mut UnsafePinned<T>
or
Pin<&mut UnsafePinned<T>>
requires unsafe
code.
Sourcepub const fn into_inner(self) -> T
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn into_inner(self) -> T
unsafe_pinned
#125735)Unwraps the value, consuming this UnsafePinned
.
Source§impl<T> UnsafePinned<T>where
T: ?Sized,
impl<T> UnsafePinned<T>where
T: ?Sized,
Sourcepub const fn get_mut_pinned(self: Pin<&mut UnsafePinned<T>>) -> *mut T
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn get_mut_pinned(self: Pin<&mut UnsafePinned<T>>) -> *mut T
unsafe_pinned
#125735)Get read-write access to the contents of a pinned UnsafePinned
.
Sourcepub const fn get_mut_unchecked(&mut self) -> *mut T
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn get_mut_unchecked(&mut self) -> *mut T
unsafe_pinned
#125735)Get read-write access to the contents of an UnsafePinned
.
You should usually be using get_mut_pinned
instead to explicitly track the fact that this
memory is “pinned” due to there being aliases.
Sourcepub const fn get(&self) -> *const T
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn get(&self) -> *const T
unsafe_pinned
#125735)Get read-only access to the contents of a shared UnsafePinned
.
Note that &UnsafePinned<T>
is read-only if &T
is read-only. This means that if there is
mutation of the T
, future reads from the *const T
returned here are UB! Use
UnsafeCell
if you also need interior mutability.
Sourcepub const fn raw_get(this: *const UnsafePinned<T>) -> *const T
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn raw_get(this: *const UnsafePinned<T>) -> *const T
unsafe_pinned
#125735)Gets an immutable pointer to the wrapped value.
The difference from get
is that this function accepts a raw pointer, which is useful to
avoid the creation of temporary references.
Sourcepub const fn raw_get_mut(this: *mut UnsafePinned<T>) -> *mut T
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
pub const fn raw_get_mut(this: *mut UnsafePinned<T>) -> *mut T
unsafe_pinned
#125735)Gets a mutable pointer to the wrapped value.
The difference from get_mut_pinned
and get_mut_unchecked
is that this function
accepts a raw pointer, which is useful to avoid the creation of temporary references.
Trait Implementations§
Source§impl<T> Clone for UnsafePinned<T>where
T: Copy,
impl<T> Clone for UnsafePinned<T>where
T: Copy,
Source§fn clone(&self) -> UnsafePinned<T>
fn clone(&self) -> UnsafePinned<T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<T> Debug for UnsafePinned<T>where
T: ?Sized,
impl<T> Debug for UnsafePinned<T>where
T: ?Sized,
Source§impl<T> Default for UnsafePinned<T>where
T: Default,
impl<T> Default for UnsafePinned<T>where
T: Default,
Source§fn default() -> UnsafePinned<T>
fn default() -> UnsafePinned<T>
Creates an UnsafePinned
, with the Default
value for T.
Source§impl<T> From<T> for UnsafePinned<T>
impl<T> From<T> for UnsafePinned<T>
Source§fn from(value: T) -> UnsafePinned<T>
fn from(value: T) -> UnsafePinned<T>
Creates a new UnsafePinned<T>
containing the given value.
impl<T, U> CoerceUnsized<UnsafePinned<U>> for UnsafePinned<T>where
T: CoerceUnsized<U>,
impl<T> Copy for UnsafePinned<T>where
T: Copy,
The type is Copy
when T
is to avoid people assuming that Copy
implies there is no
UnsafePinned
anywhere. (This is an issue with UnsafeCell
: people use Copy
bounds to mean
Freeze
.) Given that there is no unsafe impl Copy for ...
, this is also the option that
leaves the user more choices (as they can always wrap this in a !Copy
type).
impl<T, U> DispatchFromDyn<UnsafePinned<U>> for UnsafePinned<T>where
T: DispatchFromDyn<U>,
impl<T> PointerLike for UnsafePinned<T>where
T: PointerLike,
impl<T> !Unpin for UnsafePinned<T>where
T: ?Sized,
When this type is used, that almost certainly means safe APIs need to use pinning to avoid the
aliases from becoming invalidated. Therefore let’s mark this as !Unpin
. You can always opt
back in to Unpin
with an impl
block, provided your API is still sound while unpinned.