Skip to content

Commit

Permalink
Make must_cast by-value and by-shared-ref functions const (but not by…
Browse files Browse the repository at this point in the history
…-mut-ref)
  • Loading branch information
zachs18 committed Aug 8, 2024
1 parent 243302d commit f2846f9
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ macro_rules! transmute {
($val:expr) => {
::core::mem::transmute_copy(&::core::mem::ManuallyDrop::new($val))
};
($srcty:ty; $dstty:ty; $val:expr) => {
{
union Transmute<A, B> {
src: ::core::mem::ManuallyDrop<A>,
dst: ::core::mem::ManuallyDrop<B>,
}
::core::mem::ManuallyDrop::into_inner(Transmute::<$srcty, $dstty> { src: ::core::mem::ManuallyDrop::new($val) }.dst)
}
}
}

/// A macro to implement marker traits for various simd types.
Expand Down
8 changes: 4 additions & 4 deletions src/must.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ impl<A, B> Cast<A, B> {
/// let bytes : [u8; 3] = bytemuck::must_cast(12_u16);
/// ```
#[inline]
pub fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
pub const fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL;
unsafe { transmute!(a) }
unsafe { transmute!(A; B; a) }
}

/// Convert `&A` into `&B` if infalliable, or fail to compile.
Expand All @@ -64,7 +64,7 @@ pub fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
/// let bytes : &u16 = bytemuck::must_cast_ref(&[1u8, 2u8]);
/// ```
#[inline]
pub fn must_cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B {
pub const fn must_cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B {
let _ = Cast::<A, B>::ASSERT_SIZE_EQUAL;
let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
unsafe { &*(a as *const A as *const B) }
Expand Down Expand Up @@ -143,7 +143,7 @@ pub fn must_cast_mut<
/// let zsts: &[()] = bytemuck::must_cast_slice(bytes);
/// ```
#[inline]
pub fn must_cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] {
pub const fn must_cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] {
let _ = Cast::<A, B>::ASSERT_SIZE_MULTIPLE_OF_OR_INPUT_ZST;
let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
let new_len = if size_of::<A>() == size_of::<B>() {
Expand Down

0 comments on commit f2846f9

Please sign in to comment.