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

Getting allocated bytes (Box/Rc/Arc) out of Box<T> #167

Closed
RReverser opened this issue Jan 23, 2023 · 8 comments · Fixed by #211 · May be fixed by #184
Closed

Getting allocated bytes (Box/Rc/Arc) out of Box<T> #167

RReverser opened this issue Jan 23, 2023 · 8 comments · Fixed by #211 · May be fixed by #184

Comments

@RReverser
Copy link

When working with allocated types, I often wish for a function like bytemuck::bytes_of but for heap types.

For example, if I have a compatible Box<Metadata>, I should be able to receive a zero-cost Box<[u8]> and so on.

For now, the only casts available are either between sized Boxes or between Vecs of different types but I couldn't find a way to go from Box<T> to Vec<u8> or anything similar.

@notgull
Copy link
Contributor

notgull commented Jan 23, 2023

Wouldn't this be unsound? When it comes to deallocation, Metadata and [u8] (probably) have different layouts.

@RReverser
Copy link
Author

Hmm, good point, I suppose some custom allocator might potentially care about alignment. Ugh...

@RReverser
Copy link
Author

I suppose it could be allowed at least for structs where alignment == 1, similarly to what bytemuck already requires for Box<T> -> Box<U> conversions.

@notgull
Copy link
Contributor

notgull commented Jan 23, 2023

At that point, wouldn't cast_box fulfill that requirement?

@zachs18
Copy link
Contributor

zachs18 commented Jan 23, 2023

You can do this with a helper function (unsafely on stable, safely on nightly with #[feature(box_into_boxed_slice)]) using either Box::from_raw/into_raw or Box::into_boxed_slice to go from Box<T> to Box<[T]>, then bytemuck::allocation::(try_)cast_slice_box to go from a Box<[T]> to a Box<[u8]>.
playground link

At that point, wouldn't cast_box fulfill that requirement?

If you know the size of the type statically, then yeah you can (try_)cast_box from Box<T> to Box<[u8; SIZE]>, then coerce to Box<[u8]> ((try_)cast_box only works for sized types).

@RReverser
Copy link
Author

At that point, wouldn't cast_box fulfill that requirement?

Yes, if it supported unsized types like [u8]. It doesn't today.

@RReverser
Copy link
Author

RReverser commented Jan 23, 2023

You can do this with a helper function (unsafely on stable, safely on nightly with #[feature(box_into_boxed_slice)]) using either Box::from_raw/into_raw or Box::into_boxed_slice to go from Box<T> to Box<[T]>, then bytemuck::allocation::(try_)cast_slice_box to go from a Box<[T]> to a Box<[u8]>.

Oh yeah, sure, I know how to achieve it with unsafe code, when I said "I couldn't find a way" I meant specifically using bytemuck's safe APIs.

@Lokathor
Copy link
Owner

Having a general sized-or-unsized to sized-or-unsized seems tricky to get right,

But specifically a sized box into a byte slice box seems doable.

Mostly, the crate is kinda light on box stuff because i don't use boxes much so i never thought about it too deeply.

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