mirror of
https://github.com/Lokathor/bytemuck.git
synced 2024-11-21 14:22:26 +00:00
Make must_cast by-value and by-shared-ref functions const (#261)
* Make must_cast by-value and by-shared-ref functions const (but not by-mut-ref) * Add comment for transmute! macro new arm, and update Cargo.toml comment for must_cast MSRV.
This commit is contained in:
parent
243302d3ef
commit
5eecd33318
@ -32,7 +32,7 @@ min_const_generics = [] # MSRV 1.51: support arrays via min_const_generics
|
|||||||
wasm_simd = [] # MSRV 1.54.0: support wasm simd types
|
wasm_simd = [] # MSRV 1.54.0: support wasm simd types
|
||||||
aarch64_simd = [] # MSRV 1.59.0: support aarch64 simd types
|
aarch64_simd = [] # MSRV 1.59.0: support aarch64 simd types
|
||||||
|
|
||||||
must_cast = [] # MSRV 1.57.0: support the `must` module.
|
must_cast = [] # MSRV 1.64.0: support the `must` module.
|
||||||
|
|
||||||
const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
|
const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
|
||||||
|
|
||||||
|
11
src/lib.rs
11
src/lib.rs
@ -123,6 +123,17 @@ macro_rules! transmute {
|
|||||||
($val:expr) => {
|
($val:expr) => {
|
||||||
::core::mem::transmute_copy(&::core::mem::ManuallyDrop::new($val))
|
::core::mem::transmute_copy(&::core::mem::ManuallyDrop::new($val))
|
||||||
};
|
};
|
||||||
|
// This arm is for use in const contexts, where the borrow required to use transmute_copy poses an issue
|
||||||
|
// since the compiler hedges that the type being borrowed could have interior mutability.
|
||||||
|
($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.
|
/// A macro to implement marker traits for various simd types.
|
||||||
|
@ -38,9 +38,9 @@ impl<A, B> Cast<A, B> {
|
|||||||
/// let bytes : [u8; 3] = bytemuck::must_cast(12_u16);
|
/// let bytes : [u8; 3] = bytemuck::must_cast(12_u16);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[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;
|
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.
|
/// Convert `&A` into `&B` if infalliable, or fail to compile.
|
||||||
@ -64,7 +64,7 @@ pub fn must_cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
|
|||||||
/// let bytes : &u16 = bytemuck::must_cast_ref(&[1u8, 2u8]);
|
/// let bytes : &u16 = bytemuck::must_cast_ref(&[1u8, 2u8]);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[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_SIZE_EQUAL;
|
||||||
let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
|
let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
|
||||||
unsafe { &*(a as *const A as *const B) }
|
unsafe { &*(a as *const A as *const B) }
|
||||||
@ -143,7 +143,7 @@ pub fn must_cast_mut<
|
|||||||
/// let zsts: &[()] = bytemuck::must_cast_slice(bytes);
|
/// let zsts: &[()] = bytemuck::must_cast_slice(bytes);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[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_SIZE_MULTIPLE_OF_OR_INPUT_ZST;
|
||||||
let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
|
let _ = Cast::<A, B>::ASSERT_ALIGN_GREATER_THAN_EQUAL;
|
||||||
let new_len = if size_of::<A>() == size_of::<B>() {
|
let new_len = if size_of::<A>() == size_of::<B>() {
|
||||||
|
Loading…
Reference in New Issue
Block a user