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 sectionThe 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.