Trait erasable::Erasable

source ·
pub unsafe trait Erasable {
    const ACK_1_1_0: bool = false;

    unsafe fn unerase(this: ErasedPtr) -> NonNull<Self>;

    fn erase(this: NonNull<Self>) -> ErasedPtr { ... }
}
Expand description

A pointee type that supports type-erased pointers (thin pointers).

This trait is automatically implemented for all sized types, and can be manually implemented for unsized types that know their own metadata.

Safety

Must be implemented as described and may be relied upon by generic code.

Provided Associated Constants§

Whether this implementor has acknowledged the 1.1.0 update to unerase’s documented implementation requirements.

Prior to 1.1.0, creating a temporary shared reference (&_) in unerase was explicitly listed as allowed, but for the 1.1.0 release it was determined that this in fact can cause problems for some use cases that Erasable is designed to support.

Implementing this as false is not allowed and is not permission to create references within unerase. It only exists as a way to make the soundness fix in 1.1.0 disallowing references not breaking. You must override this with a value of true and follow the current documented requirements for unerase, and not create references.

If your use of unerase would be problematic if it creates a temporary shared reference, you should assert that this value is true. Not doing so will expose you to potentially unsound implementations written against 1.0.0 before the reference clarification was made.

The environment variable ERASABLE_ENFORCE_1_1_0_SEMANTICS can be set to enforce that all implementors have provided an override for this.

Required Methods§

Unerase this erased pointer.

Note that this must be sound to roundtrip pointers with any provenance, shared, unique, raw, frozen, mutable, and any valid combination thereof. (In other words, &mut _ and &_ can be safely erased and unerased, and any raw pointer should roundtrip without losing the provenance it had.)

Concretely, this means that the resulting pointer must be derived from the input pointer without any intervening references manifested. Additionally, no references to the pointee at all should be created, as their mere temporary existence may impact the validity and usable provenance of other pointers to the same location.

Creating a shared reference sounds on the surface like it should be ok. After all, you have a known-valid pointer to your type, and you can borrow from whatever pointer was erased. However, in the face of raw pointers with a shared mutable provenance, this is problematic. If a write to the pointee location even potentially races with any invocation of unerase, and it creates a reference to the location, we have immediate undefined behavior for writing behind a shared ref.

The root issue is that there may be external synchronization that this implementation has no way of knowing about. An implementation of this trait must only read the mimimum amount of data required to re-type the pointer, and must do so with a raw pointer read, or, if and only if there is a known UnsafeCell point (such as an atomic), a reference to that UnsafeCell point and the safe API of that UnsafeCell point.

Safety

The erased pointer must have been created by eraseing a valid pointer.

Provided Methods§

Turn this erasable pointer into an erased pointer.

To retrieve the original pointer, use unerase.

Implementors§