Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax Sized bound #2

Open
jalil-salame opened this issue Sep 11, 2024 · 5 comments
Open

Relax Sized bound #2

jalil-salame opened this issue Sep 11, 2024 · 5 comments

Comments

@jalil-salame
Copy link

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
Copy link
Author

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 😢

@jalil-salame
Copy link
Author

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

@jalil-salame
Copy link
Author

jalil-salame commented Dec 14, 2024

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

T-T it requires rust-lang/rust#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.

@jjl
Copy link
Contributor

jjl commented Dec 29, 2024

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.

@jalil-salame
Copy link
Author

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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants