irrustible / ointers

What do you call a pointer we stole the high bits off? An ointer.
Apache License 2.0
85 stars 3 forks source link

Relax Sized bound #2

Open jalil-salame opened 2 weeks ago

jalil-salame commented 2 weeks ago

Currently there is a sized bound on T for all structs, I don't think it is necessary and it prevents me from defining a MaybeBoxed type based on this crate:

enum MaybeBoxed<'a, T> { // is actually a struct that provides this kind of interface
    Boxed { Ox<T> },
    Ref { &'a T },
}

This is great for zero copy deserialization where Cow<'a, T> is unnecessary because the structure itself does not provide &mut T or similar access (thus Cow<'a, T> is 24-bytes instead of 16-bytes on 64-buit systems).

I specifically want to be able to use ointers::NonNull<[T]> and ointers::NonNull<str> c:

jalil-salame commented 2 weeks ago

Looking at the implementation of this, we either need ptr_metadata or strict_provenance to make this work:

//! simplified for brevity

/// Doesn't compile T-T
fn pack_stable(ptr: *mut [T], data: usize) -> Ointer<[T]> {
    //  ------------------------------------------ we drop the metadata (length information)
    //  vvvvvvvvvv                  vvvvvvvvvvv--- we don't have the required metadata
   (ptr as *mut () as usize | data) as *mut [T]
}

#![feature(ptr_metadata)]
fn pack_ptr_metadata(ptr: *mut [T], data: usize) -> *mut [T] {
   // extract metadata
   let (ptr, metadata) = ptr.to_raw_parts();
   // we can now restore the metadata ------------vvvvvvvv
   core::ptr::from_raw_parts(ptr as usize | data, metadata) as *mut [T]
}

#![feature(strict_provenance)]
fn pack_ptr_metadata(ptr: *mut [T], data: usize) -> *mut [T] {
    // manipulate the addr directly 😍
    ptr.map_addr(|addr| (addr | data))
}

As always, nightly is where all the cool stuff lies :cry:

jalil-salame commented 2 weeks ago

sptr puts a Sized bound too so we can't really use it...