Open bravely-beep opened 1 year ago
I would not necessarily be opposed to these, but a few notes:
cast_ref
/cast_mut
/cast_slice
/cast_slice_mut
? Otherwise I don't really see the point; if they are meant to always succeed you can just as
-cast them.)bytemuck
already has a lot of functions (https://github.com/Lokathor/bytemuck/pull/132#issuecomment-1234896922)try_
functions to also exist.ptr
between slice
and mut
(my preference: cast_ptr_mut
/cast_slice_ptr_mut
) or ptr
after mut
(cast_mut_ptr
/cast_slice_mut_ptr
). For the second case, IMO it would read better if cast_ptr
/cast_slice_ptr
had const
where the *mut
versions have mut
.cast_slice_ptr
and cast_slice_ptr_mut
could not (currently) be (fully) implemented on stable AFAIK, since there is no (fully "blessed") way to get the length of a general slice pointer on stable (<*const [T]>::len
is unstable. There are some partial workarounds/polyfills listed on the tracking issue but none are completely general and safe.).std::ptr::slice_from_raw_parts
was only stabilized in Rust 1.42.0 which is above bytemuck
's MSRV of 1.34.0, so the slice pointer functions would probably have to be behind a feature flag anyway.usize::MAX
bytes, which would introduce an additional failure case to cast_slice_ptr(_mut)
that doesn't exist for other casts: "Casting this slice pointer from the source to destination type would overflow the element-length of the slice", though this could reasonably be folded into PodCastError::SizeMismatch
I suppose (PodCastError
is not #[non_exhaustive]
, so a new variant could not be added semver-compatibly), or a new error type could be added similar to CheckedCastError
. Example:let too_long: *const [u32] = std::ptr::slice_from_raw_parts(std::ptr::null(), usize::MAX);
let what_error_should_this_return: Result<*const [u8], PodCastError> = try_cast_slice_ptr(too_long);
Yeah, there's a lot more small design work than it might seem at first.
Personally, for volatile access i have the voladdress
crate, which has always served my needs well enough to not bother with raw pointers in bytemuck
If I may, I would suggest to leave slice pointer casts out for now, but add support for NonNull
pointers.
I'm doing this in some of my projects, and I'm basically copy-pasting cast_ref
and friends. These would be trivial additions.
there is no (fully "blessed") way to get the length of a general slice pointer on stable.
Since Rust 1.75.0, with the stabilization of wrapping_byte_add
it is possible to write a correct polyfill of <*mut [T]>::len
on stable.
https://github.com/rust-lang/rust/issues/71146#issuecomment-1871542032
Would it make sense to include cast functions that handle raw pointers?
fn cast_ptr(a: *const A) -> *const B
fn cast_mut_ptr(a: *mut A) -> *mut B
fn cast_slice_ptr(a: *const [A]) -> *const [B]
fn cast_mut_slice_ptr(a: *mut [A]) -> *mut [B]
This would be useful when working with data that is unsafe to take references to (e.g. volatile IO memory).