pub struct Ptr<'a, T, I>where
I: Invariants,
T: ?Sized,{ /* private fields */ }Expand description
A raw pointer with more restrictions.
Ptr<T> is similar to NonNull<T>, but it is more restrictive in the
following ways (note that these requirements only hold of non-zero-sized
referents):
- It must derive from a valid allocation.
- It must reference a byte range which is contained inside the
allocation from which it derives.
- As a consequence, the byte range it references must have a size
which does not overflow
isize.
- As a consequence, the byte range it references must have a size
which does not overflow
Depending on how Ptr is parameterized, it may have additional
invariants:
ptrconforms to the aliasing invariant ofI::Aliasing.ptrconforms to the alignment invariant ofI::Alignment.ptrconforms to the validity invariant ofI::Validity.
Ptr<'a, T> is covariant in 'a and invariant in T.
Implementations§
Source§impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants,
impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants,
Sourcepub fn as_inner(&self) -> PtrInner<'a, T>
pub fn as_inner(&self) -> PtrInner<'a, T>
Converts this Ptr<T> to a PtrInner<T>.
Note that this method does not consume self. The caller should
watch out for unsafe code which uses the returned value in a way
that violates the safety invariants of self.
Source§impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)>where
T: 'a + ?Sized,
&'a mut T → Ptr<'a, T>
impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)>where
T: 'a + ?Sized,
&'a mut T → Ptr<'a, T>
Source§impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants<Alignment = Aligned, Validity = Valid>,
<I as Invariants>::Aliasing: Reference,
Ptr<'a, T> → &'a T
impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants<Alignment = Aligned, Validity = Valid>,
<I as Invariants>::Aliasing: Reference,
Ptr<'a, T> → &'a T
Source§impl<'a, T, I> Ptr<'a, T, I>
impl<'a, T, I> Ptr<'a, T, I>
Sourcepub fn reborrow<'b>(&'b mut self) -> Ptr<'b, T, I>where
'a: 'b,
pub fn reborrow<'b>(&'b mut self) -> Ptr<'b, T, I>where
'a: 'b,
Reborrows self, producing another Ptr.
Since self is borrowed mutably, this prevents any methods from
being called on self as long as the returned Ptr exists.
Reborrows self as shared, producing another Ptr with Shared
aliasing.
Since self is borrowed mutably, this prevents any methods from
being called on self as long as the returned Ptr exists.
Source§impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)>where
T: 'a + ?Sized,
Ptr<'a, T> → &'a mut T
impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)>where
T: 'a + ?Sized,
Ptr<'a, T> → &'a mut T
Source§impl<'a, T, I> Ptr<'a, T, I>where
I: Invariants,
T: ?Sized,
Ptr<'a, T> → Ptr<'a, U>
impl<'a, T, I> Ptr<'a, T, I>where
I: Invariants,
T: ?Sized,
Ptr<'a, T> → Ptr<'a, U>
pub fn transmute<U, V, R>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, V)>where
V: Validity,
U: TransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, V, <U as SizeEq<T>>::CastFrom, R> + SizeEq<T> + ?Sized,
pub fn transmute_with<U, V, C, R>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, V)>where
V: Validity,
U: TransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, V, C, R> + ?Sized,
C: CastExact<T, U>,
pub fn recall_validity<V, R>(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, V)>where
V: Validity,
T: TransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, V, IdCast, R>,
Sourcepub unsafe fn project_transmute_unchecked<U, V, P>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, V)>
pub unsafe fn project_transmute_unchecked<U, V, P>( self, ) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, V)>
Projects and/or transmutes to a different (unsized) referent type without checking interior mutability.
Callers should prefer cast or project where possible.
§Safety
The caller promises that:
- If
I::AliasingisShared, it must not be possible for safe code, operating on a&Tand&U, with the referents ofselfandself.project_transmute_unchecked(), respectively, to cause undefined behavior. - It is sound to project and/or transmute a pointer of type
Twith aliasingI::Aliasingand validityI::Validityto a pointer of typeUwith aliasingI::Aliasingand validityV. This is a subtle soundness requirement that is a function ofT,U,I::Aliasing,I::Validity, andV, and may depend upon the presence, absence, or specific location ofUnsafeCells inTand/orU, and on whether interior mutation is ever permitted via thoseUnsafeCells. SeeValidityfor more details.
Source§impl<'a, T, I> Ptr<'a, T, I>where
I: Invariants,
Ptr<'a, T, (_, _, _)> → Ptr<'a, Unalign<T>, (_, Aligned, _)>
impl<'a, T, I> Ptr<'a, T, I>where
I: Invariants,
Ptr<'a, T, (_, _, _)> → Ptr<'a, Unalign<T>, (_, Aligned, _)>
Sourcepub fn into_unalign(
self,
) -> Ptr<'a, Unalign<T>, (<I as Invariants>::Aliasing, Aligned, <I as Invariants>::Validity)>
pub fn into_unalign( self, ) -> Ptr<'a, Unalign<T>, (<I as Invariants>::Aliasing, Aligned, <I as Invariants>::Validity)>
Converts a Ptr an unaligned T into a Ptr to an aligned
Unalign<T>.
Source§impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants,
impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants,
Sourcepub fn unify_invariants<H>(self) -> Ptr<'a, T, H>where
H: Invariants<Aliasing = <I as Invariants>::Aliasing, Alignment = <I as Invariants>::Alignment, Validity = <I as Invariants>::Validity>,
pub fn unify_invariants<H>(self) -> Ptr<'a, T, H>where
H: Invariants<Aliasing = <I as Invariants>::Aliasing, Alignment = <I as Invariants>::Alignment, Validity = <I as Invariants>::Validity>,
Helps the type system unify two distinct invariant types which are actually the same.
Sourcepub fn try_into_aligned(
self,
) -> Result<Ptr<'a, T, (<I as Invariants>::Aliasing, Aligned, <I as Invariants>::Validity)>, AlignmentError<Ptr<'a, T, I>, T>>where
T: Sized,
pub fn try_into_aligned(
self,
) -> Result<Ptr<'a, T, (<I as Invariants>::Aliasing, Aligned, <I as Invariants>::Validity)>, AlignmentError<Ptr<'a, T, I>, T>>where
T: Sized,
Checks the self’s alignment at runtime, returning an aligned Ptr
on success.
Sourcepub fn bikeshed_recall_aligned(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, Aligned, <I as Invariants>::Validity)>where
T: Unaligned,
pub fn bikeshed_recall_aligned(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, Aligned, <I as Invariants>::Validity)>where
T: Unaligned,
Recalls that self’s referent is validly-aligned for T.
Sourcepub unsafe fn assume_validity<V>(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, V)>where
V: Validity,
pub unsafe fn assume_validity<V>(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, V)>where
V: Validity,
Assumes that self’s referent conforms to the validity requirement
of V.
§Safety
The caller promises that self’s referent conforms to the validity
requirement of V.
Sourcepub unsafe fn assume_initialized(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, Initialized)>
pub unsafe fn assume_initialized( self, ) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, Initialized)>
A shorthand for self.assume_validity<invariant::Initialized>().
§Safety
The caller promises to uphold the safety preconditions of
self.assume_validity<invariant::Initialized>().
Sourcepub unsafe fn assume_valid(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, Valid)>
pub unsafe fn assume_valid( self, ) -> Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, Valid)>
A shorthand for self.assume_validity<Valid>().
§Safety
The caller promises to uphold the safety preconditions of
self.assume_validity<Valid>().
Sourcepub fn try_into_valid<R, S>(
self,
) -> Result<Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, Valid)>, ValidityError<Ptr<'a, T, I>, T>>where
T: TryFromBytes + Read<<I as Invariants>::Aliasing, R> + TryTransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, Valid, IdCast, S>,
ReadOnly<T>: Read<<I as Invariants>::Aliasing, R>,
<I as Invariants>::Aliasing: Reference,
I: Invariants<Validity = Initialized>,
pub fn try_into_valid<R, S>(
self,
) -> Result<Ptr<'a, T, (<I as Invariants>::Aliasing, <I as Invariants>::Alignment, Valid)>, ValidityError<Ptr<'a, T, I>, T>>where
T: TryFromBytes + Read<<I as Invariants>::Aliasing, R> + TryTransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, Valid, IdCast, S>,
ReadOnly<T>: Read<<I as Invariants>::Aliasing, R>,
<I as Invariants>::Aliasing: Reference,
I: Invariants<Validity = Initialized>,
Checks that self’s referent is validly initialized for T,
returning a Ptr with Valid on success.
§Panics
This method will panic if
T::is_bit_valid panics.
§Safety
On error, unsafe code may rely on this method’s returned
ValidityError containing self.
Sourcepub fn forget_aligned(
self,
) -> Ptr<'a, T, (<I as Invariants>::Aliasing, Unaligned, <I as Invariants>::Validity)>
pub fn forget_aligned( self, ) -> Ptr<'a, T, (<I as Invariants>::Aliasing, Unaligned, <I as Invariants>::Validity)>
Forgets that self’s referent is validly-aligned for T.
Source§impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants,
impl<'a, T, I> Ptr<'a, T, I>where
T: 'a + ?Sized,
I: Invariants,
Sourcepub unsafe fn cast_unchecked<U, C>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, <I as Invariants>::Validity)>where
C: Cast<T, U>,
U: 'a + CastableFrom<T, <I as Invariants>::Validity, <I as Invariants>::Validity> + ?Sized,
pub unsafe fn cast_unchecked<U, C>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, <I as Invariants>::Validity)>where
C: Cast<T, U>,
U: 'a + CastableFrom<T, <I as Invariants>::Validity, <I as Invariants>::Validity> + ?Sized,
Sourcepub fn cast<U, C, R>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, <I as Invariants>::Validity)>where
T: MutationCompatible<U, <I as Invariants>::Aliasing, <I as Invariants>::Validity, <I as Invariants>::Validity, R>,
U: 'a + CastableFrom<T, <I as Invariants>::Validity, <I as Invariants>::Validity> + ?Sized,
C: Cast<T, U>,
pub fn cast<U, C, R>(
self,
) -> Ptr<'a, U, (<I as Invariants>::Aliasing, Unaligned, <I as Invariants>::Validity)>where
T: MutationCompatible<U, <I as Invariants>::Aliasing, <I as Invariants>::Validity, <I as Invariants>::Validity, R>,
U: 'a + CastableFrom<T, <I as Invariants>::Validity, <I as Invariants>::Validity> + ?Sized,
C: Cast<T, U>,
Casts to a different referent type.
pub fn project<F, const VARIANT_ID: i128, const FIELD_ID: i128>( self, ) -> Result<Ptr<'a, <T as HasField<F, VARIANT_ID, FIELD_ID>>::Type, <T as ProjectField<F, I, VARIANT_ID, FIELD_ID>>::Invariants>, <T as ProjectField<F, I, VARIANT_ID, FIELD_ID>>::Error>
Sourcepub fn try_with<U, J, E, F>(
self,
f: F,
) -> Result<Ptr<'a, U, J>, <E as TryWithError<Ptr<'a, T, I>>>::Mapped>where
U: 'a + ?Sized,
J: Invariants<Aliasing = <I as Invariants>::Aliasing>,
E: TryWithError<Ptr<'a, T, I>>,
F: FnOnce(Ptr<'a, T, I>) -> Result<Ptr<'a, U, J>, E>,
I: Invariants<Aliasing = Shared>,
pub fn try_with<U, J, E, F>(
self,
f: F,
) -> Result<Ptr<'a, U, J>, <E as TryWithError<Ptr<'a, T, I>>>::Mapped>where
U: 'a + ?Sized,
J: Invariants<Aliasing = <I as Invariants>::Aliasing>,
E: TryWithError<Ptr<'a, T, I>>,
F: FnOnce(Ptr<'a, T, I>) -> Result<Ptr<'a, U, J>, E>,
I: Invariants<Aliasing = Shared>,
Attempts to transform the pointer, restoring the original on failure.
Source§impl<'a, T, I> Ptr<'a, T, I>
impl<'a, T, I> Ptr<'a, T, I>
Sourcepub fn as_bytes<R>(
self,
) -> Ptr<'a, [u8], (<I as Invariants>::Aliasing, Aligned, Valid)>where
[u8]: TransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, Valid, AsBytesCast, R>,
pub fn as_bytes<R>(
self,
) -> Ptr<'a, [u8], (<I as Invariants>::Aliasing, Aligned, Valid)>where
[u8]: TransmuteFromPtr<T, <I as Invariants>::Aliasing, <I as Invariants>::Validity, Valid, AsBytesCast, R>,
Casts this pointer-to-initialized into a pointer-to-bytes.
Source§impl<'a, I> Ptr<'a, [u8], I>where
I: Invariants<Validity = Valid>,
For caller convenience, these methods are generic over alignment
invariant. In practice, the referent is always well-aligned, because the
alignment of [u8] is 1.
impl<'a, I> Ptr<'a, [u8], I>where
I: Invariants<Validity = Valid>,
For caller convenience, these methods are generic over alignment
invariant. In practice, the referent is always well-aligned, because the
alignment of [u8] is 1.
Sourcepub fn try_cast_into<U, R>(
self,
cast_type: CastType,
meta: Option<<U as KnownLayout>::PointerMetadata>,
) -> Result<(Ptr<'a, U, (<I as Invariants>::Aliasing, Aligned, Initialized)>, Ptr<'a, [u8], I>), ConvertError<AlignmentError<Ptr<'a, [u8], I>, U>, SizeError<Ptr<'a, [u8], I>, U>, Infallible>>where
<I as Invariants>::Aliasing: Reference,
U: 'a + KnownLayout + Read<<I as Invariants>::Aliasing, R> + ?Sized,
pub fn try_cast_into<U, R>(
self,
cast_type: CastType,
meta: Option<<U as KnownLayout>::PointerMetadata>,
) -> Result<(Ptr<'a, U, (<I as Invariants>::Aliasing, Aligned, Initialized)>, Ptr<'a, [u8], I>), ConvertError<AlignmentError<Ptr<'a, [u8], I>, U>, SizeError<Ptr<'a, [u8], I>, U>, Infallible>>where
<I as Invariants>::Aliasing: Reference,
U: 'a + KnownLayout + Read<<I as Invariants>::Aliasing, R> + ?Sized,
Attempts to cast self to a U using the given cast type.
If U is a slice DST and pointer metadata (meta) is provided,
then the cast will only succeed if it would produce an object with
the given metadata.
Returns None if the resulting U would be invalidly-aligned, if
no U can fit in self, or if the provided pointer metadata
describes an invalid instance of U. On success, returns a pointer
to the largest-possible U which fits in self.
§Safety
The caller may assume that this implementation is correct, and may
rely on that assumption for the soundness of their code. In
particular, the caller may assume that, if try_cast_into returns
Some((ptr, remainder)), then ptr and remainder refer to
non-overlapping byte ranges within self, and that ptr and
remainder entirely cover self. Finally:
- If this is a prefix cast,
ptrhas the same address asself. - If this is a suffix cast,
remainderhas the same address asself.
Sourcepub fn try_cast_into_no_leftover<U, R>(
self,
meta: Option<<U as KnownLayout>::PointerMetadata>,
) -> Result<Ptr<'a, U, (<I as Invariants>::Aliasing, Aligned, Initialized)>, ConvertError<AlignmentError<Ptr<'a, [u8], I>, U>, SizeError<Ptr<'a, [u8], I>, U>, Infallible>>where
<I as Invariants>::Aliasing: Reference,
U: 'a + KnownLayout + Read<<I as Invariants>::Aliasing, R> + ?Sized,
[u8]: Read<<I as Invariants>::Aliasing, R>,
pub fn try_cast_into_no_leftover<U, R>(
self,
meta: Option<<U as KnownLayout>::PointerMetadata>,
) -> Result<Ptr<'a, U, (<I as Invariants>::Aliasing, Aligned, Initialized)>, ConvertError<AlignmentError<Ptr<'a, [u8], I>, U>, SizeError<Ptr<'a, [u8], I>, U>, Infallible>>where
<I as Invariants>::Aliasing: Reference,
U: 'a + KnownLayout + Read<<I as Invariants>::Aliasing, R> + ?Sized,
[u8]: Read<<I as Invariants>::Aliasing, R>,
Attempts to cast self into a U, failing if all of the bytes of
self cannot be treated as a U.
In particular, this method fails if self is not validly-aligned
for U or if self’s size is not a valid size for U.
§Safety
On success, the caller may assume that the returned pointer
references the same byte range as self.
Source§impl<'a, T, I> Ptr<'a, UnsafeCell<T>, I>
impl<'a, T, I> Ptr<'a, UnsafeCell<T>, I>
Sourcepub fn get_mut(self) -> Ptr<'a, T, I>
pub fn get_mut(self) -> Ptr<'a, T, I>
Converts this Ptr into a pointer to the underlying data.
This call borrows the UnsafeCell mutably (at compile-time) which
guarantees that we possess the only reference.
This is like UnsafeCell::get_mut, but for Ptr.
Trait Implementations§
impl<'a, T, I> Copy for Ptr<'a, T, I>
SAFETY: Shared pointers are safely Copy. Ptr’s other invariants
(besides aliasing) are unaffected by the number of references that exist
to Ptr’s referent. The notable cases are:
-
Alignment is a property of the referent type (
T) and the address, both of which are unchanged -
Let
S(T, V)be the set of bit values permitted to appear in the referent of aPtr<T, I: Invariants<Validity = V>>. Since this copy does not changeI::ValidityorT,S(T, I::Validity)is also unchanged.We are required to guarantee that the referents of the original
Ptrand of the copy (which, of course, are actually the same since they live in the same byte address range) both remain in the setS(T, I::Validity). Since this invariant holds on the originalPtr, it cannot be violated by the originalPtr, and thus the originalPtrcannot be used to violate this invariant on the copy. The inverse holds as well.