ointers icon indicating copy to clipboard operation
ointers copied to clipboard

Relax Sized bound

Open jalil-salame opened this issue 1 year ago • 5 comments

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 avatar Sep 11 '24 21:09 jalil-salame

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 avatar Sep 11 '24 21:09 jalil-salame

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

jalil-salame avatar Sep 11 '24 21:09 jalil-salame

~~1.84.0 (current beta) stabilizes the strict provenance APIs so this is now possible!~~

T-T it requires https://github.com/rust-lang/rust/issues/69835 for the debug assertions as align_of::<T>() has a Sized requirement so we need align_of_val_raw(ptr).

Also, we use .cast() to cast between *mut u8 and *mut T, I'd need to look closer to know why this is going on, but .cast() has a Sized requirement so we can't use it.

jalil-salame avatar Dec 14 '24 12:12 jalil-salame

sorry, i've been ignoring github notifications for the most part.

in principle it should be fine to support wide pointers, but as you say there's always a catch somewhere. i decided to go with plain pointers while they worked some of the kinks out. the wide pointer support is a bit half-arsed IMO, but hopefully one day they'll fill the gaps.

jjl avatar Dec 29 '24 15:12 jjl

sorry, i've been ignoring github notifications for the most part.

in principle it should be fine to support wide pointers, but as you say there's always a catch somewhere. i decided to go with plain pointers while they worked some of the kinks out. the wide pointer support is a bit half-arsed IMO, but hopefully one day they'll fill the gaps.

No worries, I'm subscribed to basically every relevant thread on this matter so as soon as support is on beta/stable I'll update the issue c:

jalil-salame avatar Dec 29 '24 15:12 jalil-salame