Lokathor/bytemuck

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

RReverser opened this issue · 8 comments

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.

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

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

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.

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

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

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

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

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.

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.