Skip to main content

DerefPlace

Trait DerefPlace 

Source
pub unsafe trait DerefPlace<PointeeTiming, PointerTiming>: PlaceHandle
where Self::Target: CreateHandle<PointeeTiming>, PointeeTiming: Timing, PointerTiming: Timing,
{ const POINTEE_ACCESS: AccessKind; const POINTER_ACCESS: AccessKind; const SAFE: bool; // Required method unsafe fn deref_place( self, ) -> <Self::Target as CreateHandle<PointeeTiming>>::Handle; }
Expand description

*place – Dereference the contents of a place.

Dereferencing from a borrow-checker perspective requires access to two places:

  • the place that comes out of the dereference operation (*place), and
  • the place that’s being dereferenced (place).

For this reason, the dereference operation has two associated constants of type AccessKind that specify the access permissions required for the two accesses and two Timing generics1 called PointeeTiming and PointerTiming.

Given a pointer ptr, the place that comes out of the dereference is *ptr and the place that is being dereferenced is ptr. The PointerTiming generic and Self::POINTER_ACCESS constant control how the borrow checker treats the access to ptr, while PointeeTiming and Self::POINTEE_ACCESS specify the kind of access to *ptr.

Utilizing this fact, one can encode that a pointer can be invalidated without invalidating pointers that were derived from dereferenced pointers. This is the case for mutable references:

fn overwrite_nested<'a>(ptr: &mut &'a mut Struct, make: impl FnOnce() -> &'a mut Struct) {
    let a: &'a mut Field = &mut (**ptr).field;
    *ptr = make();
    let b: &'a mut Field = &mut (**ptr).field;

    mem::swap(a, b); // can use both `a` and `b`!
}

In this case, dereferencing &mut has Instant as the PointerTiming, which results in never invalidating derived pointers when the original is used for something else.


  1. They can’t be associated types, because the timing Lifetime<'a> has a lifetime. If they were associated types, one could only use Lifetime<'a> if the handle also had that same lifetime. Because handles generally want to allow shortening lifetimes, the timing needs to introduce a fresh lifetime. 

Required Associated Constants§

Source

const POINTEE_ACCESS: AccessKind

The access permissions to the contents of the place handled by Self required by Self::deref_place.

Source

const POINTER_ACCESS: AccessKind

The access permissions to the place handled by Self required by Self::deref_place.

Source

const SAFE: bool

Whether Self::deref_place is safe when Self::POINTEE_ACCESS and Self::POINTER_ACCESS are honored for PointeeTiming and PointerTiming respectively.

This constant controls whether the compiler will require writing an unsafe block around dereferencing a place that uses the this handle.

Required Methods§

Source

unsafe fn deref_place( self, ) -> <Self::Target as CreateHandle<PointeeTiming>>::Handle

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl<P, ProxyTiming> DerefPlace<ProxyTiming, Instant> for *const P
where P: ?Sized + CreateHandle<ProxyTiming>, ProxyTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = P::ACCESS

Source§

const POINTER_ACCESS: AccessKind = AccessKind::Untracked

Source§

const SAFE: bool = false

Source§

unsafe fn deref_place( self, ) -> <Self::Target as CreateHandle<ProxyTiming>>::Handle

Source§

impl<P, ProxyTiming> DerefPlace<ProxyTiming, Instant> for *mut P
where P: ?Sized + CreateHandle<ProxyTiming>, ProxyTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = P::ACCESS

Source§

const POINTER_ACCESS: AccessKind = AccessKind::Untracked

Source§

const SAFE: bool = false

Source§

unsafe fn deref_place( self, ) -> <Self::Target as CreateHandle<ProxyTiming>>::Handle

Implementors§

Source§

impl<'a, ProxyTiming, P> DerefPlace<ProxyTiming, Instant> for MutHandle<'a, P>
where P: CreateHandle<ProxyTiming> + ?Sized, ProxyTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = P::ACCESS

Source§

const POINTER_ACCESS: AccessKind = AccessKind::Shared

Source§

const SAFE: bool = true

Source§

impl<'a, ProxyTiming, P> DerefPlace<ProxyTiming, Instant> for RefHandle<'a, P>
where P: CreateHandle<ProxyTiming> + ?Sized, ProxyTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = P::ACCESS

Source§

const POINTER_ACCESS: AccessKind = AccessKind::Shared

Source§

const SAFE: bool = true

Source§

impl<H, PointeeTiming, PointerTiming> DerefPlace<PointeeTiming, PointerTiming> for PinnedHandle<H>
where Self::Target: CreateHandle<PointeeTiming>, H: DerefPlace<PointeeTiming, PointerTiming>, PointeeTiming: Timing, PointerTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = H::POINTEE_ACCESS

Source§

const POINTER_ACCESS: AccessKind = H::POINTER_ACCESS

Source§

const SAFE: bool = H::SAFE

Source§

impl<P, ProxyTiming> DerefPlace<ProxyTiming, Instant> for LocalHandle<P>
where P: CreateHandle<ProxyTiming>, ProxyTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = P::ACCESS

Source§

const POINTER_ACCESS: AccessKind = P::ACCESS

Source§

const SAFE: bool = true

Source§

impl<T, ProxyTiming> DerefPlace<ProxyTiming, UntilDrop> for ArcRefHandle<T>
where T: ?Sized + CreateHandle<ProxyTiming>, ProxyTiming: Timing,

Source§

const POINTEE_ACCESS: AccessKind = T::ACCESS

Source§

const POINTER_ACCESS: AccessKind = AccessKind::Shared

Source§

const SAFE: bool = true