UnsafePinned in core::pin - Rust (original) (raw)
Struct UnsafePinned
pub struct UnsafePinned<T: ?Sized> { /* private fields */ }
🔬This is a nightly-only experimental API. (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 asmem::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.
🔬This is a nightly-only experimental API. (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>
orPin<&mut UnsafePinned<T>>
requires unsafe
code.
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
Unwraps the value, consuming this UnsafePinned
.
🔬This is a nightly-only experimental API. (unsafe_pinned
#125735)
Get read-write access to the contents of a pinned UnsafePinned
.
🔬This is a nightly-only experimental API. (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.
🔬This is a nightly-only experimental API. (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! UseUnsafeCell if you also need interior mutability.
#![feature(unsafe_pinned)]
use std::pin::UnsafePinned;
unsafe {
let mut x = UnsafePinned::new(0);
let ptr = x.get(); // read-only pointer, assumes immutability
x.get_mut_unchecked().write(1);
ptr.read(); // UB!
}
🔬This is a nightly-only experimental API. (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.
🔬This is a nightly-only experimental API. (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.
Creates an UnsafePinned
, with the Default
value for T.
Creates a new UnsafePinned<T>
containing the given value.
The type is Copy
when T
is to avoid people assuming that Copy
implies there is noUnsafePinned
anywhere. (This is an issue with UnsafeCell
: people use Copy
bounds to meanFreeze
.) 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).
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.