pub unsafe trait PointerRecomposition {
type Components: Copy + Eq;
// Required methods
fn decompose(this: &Self) -> Self::Components;
unsafe fn recompose(ptr: Ptr<u8>, data: Self::Components) -> Ptr<Self>;
}
Expand description
The bridge that makes SelfRef
work with any type, sized or unsized.
Rust has two kinds of types: sized ones like i32
and String
that have a known
size at compile time, and unsized ones like [T]
, str
, and trait objects that
need extra metadata to work with. This trait abstracts away that complexity,
letting SelfRef
handle both seamlessly.
Most users never need to implement this trait directly - it’s already implemented
for all the types you’d want to use. The magic happens behind the scenes when you
create a SelfRef<[u8]>
or SelfRef<TraitObject<dyn Debug>>
.
use movable_ref::SelfRef;
// Works with sized types (metadata = ())
let mut value = 42i32;
let mut ptr: SelfRef<i32> = SelfRef::null();
ptr.set(&mut value).unwrap();
// Also works with slices (metadata = length)
let mut data = vec![1, 2, 3, 4, 5];
let mut slice_ptr: SelfRef<[i32]> = SelfRef::null();
slice_ptr.set(&mut data[1..4]).unwrap(); // Points to middle section
The trait handles the complex pointer arithmetic needed to reconstruct fat pointers
from offset-based storage, making SelfRef
truly universal across Rust’s type system.
§Safety
Implementations must correctly reconstruct valid pointers. The compose
method
is the critical piece - it takes a raw data pointer and metadata, then builds
a proper pointer to Self
. Get this wrong and you’ll have undefined behavior.
Required Associated Types§
Sourcetype Components: Copy + Eq
type Components: Copy + Eq
The metadata type - ()
for sized types, usize
for slices, vtables for trait objects.
This is what gets stored alongside the offset to fully reconstruct the pointer later.
For a String
, this is just ()
since the size is in the struct itself.
For a [u8]
, this is the length. For trait objects, it’s the vtable pointer.
Required Methods§
Sourcefn decompose(this: &Self) -> Self::Components
fn decompose(this: &Self) -> Self::Components
Extracts metadata from a live reference.
When SelfRef
stores a pointer, it calls this to capture whatever extra
information is needed to reconstruct the reference later. Think of it as
“what do I need to remember about this pointer besides its location?”
Sourceunsafe fn recompose(ptr: Ptr<u8>, data: Self::Components) -> Ptr<Self>
unsafe fn recompose(ptr: Ptr<u8>, data: Self::Components) -> Ptr<Self>
Reconstructs a proper pointer from raw components.
This is where the magic happens - takes a basic data pointer and the stored metadata, then builds back the original fat pointer. For slices, this means combining the data pointer with the length. For trait objects, it’s data + vtable.
§Safety
The ptr
must be a valid pointer to the start of the data, and data
must be
valid metadata that was previously extracted from a valid pointer of type Self
.
The resulting pointer will only be valid if both components are correct.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.