mirror of
https://github.com/Lokathor/bytemuck.git
synced 2024-10-29 21:30:48 +00:00
parent
1c09edf7b0
commit
da9b1874d8
@ -45,6 +45,9 @@ const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
|
||||
# Do not use if you can avoid it, because this is **unsound**!!!!
|
||||
unsound_ptr_pod_impl = []
|
||||
|
||||
# MSRV 1.46.0: adds the `#[track_caller]` attribute to functions which may panic
|
||||
track_caller = []
|
||||
|
||||
# Enables all features that are both sound and supported on the latest stable
|
||||
# version of Rust, with the exception of `extern_crate_alloc` and
|
||||
# `extern_crate_std`.
|
||||
@ -57,6 +60,7 @@ latest_stable_rust = [
|
||||
"derive",
|
||||
"min_const_generics",
|
||||
"must_cast",
|
||||
"track_caller",
|
||||
"wasm_simd",
|
||||
"zeroable_atomics",
|
||||
"zeroable_maybe_uninit",
|
||||
|
@ -891,6 +891,7 @@ pub fn box_bytes_of<T: sealed::BoxBytesOf + ?Sized>(input: Box<T>) -> BoxBytes {
|
||||
/// This is [`try_from_box_bytes`] but will panic on error and the input will be
|
||||
/// dropped.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn from_box_bytes<T: sealed::FromBoxBytes + ?Sized>(
|
||||
input: BoxBytes,
|
||||
) -> Box<T> {
|
||||
|
@ -413,6 +413,7 @@ pub fn try_cast_slice_mut<
|
||||
///
|
||||
/// This is [`try_from_bytes`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn from_bytes<T: CheckedBitPattern>(s: &[u8]) -> &T {
|
||||
match try_from_bytes(s) {
|
||||
Ok(t) => t,
|
||||
@ -426,6 +427,7 @@ pub fn from_bytes<T: CheckedBitPattern>(s: &[u8]) -> &T {
|
||||
///
|
||||
/// This is [`try_from_bytes_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn from_bytes_mut<T: NoUninit + CheckedBitPattern>(s: &mut [u8]) -> &mut T {
|
||||
match try_from_bytes_mut(s) {
|
||||
Ok(t) => t,
|
||||
@ -438,6 +440,7 @@ pub fn from_bytes_mut<T: NoUninit + CheckedBitPattern>(s: &mut [u8]) -> &mut T {
|
||||
/// ## Panics
|
||||
/// * This is like `try_pod_read_unaligned` but will panic on failure.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn pod_read_unaligned<T: CheckedBitPattern>(bytes: &[u8]) -> T {
|
||||
match try_pod_read_unaligned(bytes) {
|
||||
Ok(t) => t,
|
||||
@ -451,6 +454,7 @@ pub fn pod_read_unaligned<T: CheckedBitPattern>(bytes: &[u8]) -> T {
|
||||
///
|
||||
/// * This is like [`try_cast`], but will panic on a size mismatch.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast<A: NoUninit, B: CheckedBitPattern>(a: A) -> B {
|
||||
match try_cast(a) {
|
||||
Ok(t) => t,
|
||||
@ -464,6 +468,7 @@ pub fn cast<A: NoUninit, B: CheckedBitPattern>(a: A) -> B {
|
||||
///
|
||||
/// This is [`try_cast_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_mut<
|
||||
A: NoUninit + AnyBitPattern,
|
||||
B: NoUninit + CheckedBitPattern,
|
||||
@ -482,6 +487,7 @@ pub fn cast_mut<
|
||||
///
|
||||
/// This is [`try_cast_ref`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_ref<A: NoUninit, B: CheckedBitPattern>(a: &A) -> &B {
|
||||
match try_cast_ref(a) {
|
||||
Ok(t) => t,
|
||||
@ -495,6 +501,7 @@ pub fn cast_ref<A: NoUninit, B: CheckedBitPattern>(a: &A) -> &B {
|
||||
///
|
||||
/// This is [`try_cast_slice`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_slice<A: NoUninit, B: CheckedBitPattern>(a: &[A]) -> &[B] {
|
||||
match try_cast_slice(a) {
|
||||
Ok(t) => t,
|
||||
@ -508,6 +515,7 @@ pub fn cast_slice<A: NoUninit, B: CheckedBitPattern>(a: &[A]) -> &[B] {
|
||||
///
|
||||
/// This is [`try_cast_slice_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_slice_mut<
|
||||
A: NoUninit + AnyBitPattern,
|
||||
B: NoUninit + CheckedBitPattern,
|
||||
|
@ -118,6 +118,7 @@ pub unsafe trait Contiguous: Copy + 'static {
|
||||
/// This is undefined behavior regardless, so it could have been the nasal
|
||||
/// demons at that point anyway ;).
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
fn from_integer(value: Self::Int) -> Option<Self> {
|
||||
// Guard against an illegal implementation of Contiguous. Annoyingly we
|
||||
// can't rely on `transmute` to do this for us (see below), but
|
||||
@ -153,6 +154,7 @@ pub unsafe trait Contiguous: Copy + 'static {
|
||||
/// This is undefined behavior regardless, so it could have been the nasal
|
||||
/// demons at that point anyway ;).
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
fn into_integer(self) -> Self::Int {
|
||||
// Guard against an illegal implementation of Contiguous. Annoyingly we
|
||||
// can't rely on `transmute` to do the size check for us (see
|
||||
|
@ -23,6 +23,7 @@ possibility code branch.
|
||||
#[cfg(not(target_arch = "spirv"))]
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) fn something_went_wrong<D: core::fmt::Display>(
|
||||
_src: &str, _err: D,
|
||||
) -> ! {
|
||||
@ -75,6 +76,7 @@ pub(crate) unsafe fn bytes_of_mut<T: Copy>(t: &mut T) -> &mut [u8] {
|
||||
///
|
||||
/// This is [`try_from_bytes`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn from_bytes<T: Copy>(s: &[u8]) -> &T {
|
||||
match try_from_bytes(s) {
|
||||
Ok(t) => t,
|
||||
@ -88,6 +90,7 @@ pub(crate) unsafe fn from_bytes<T: Copy>(s: &[u8]) -> &T {
|
||||
///
|
||||
/// This is [`try_from_bytes_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn from_bytes_mut<T: Copy>(s: &mut [u8]) -> &mut T {
|
||||
match try_from_bytes_mut(s) {
|
||||
Ok(t) => t,
|
||||
@ -115,6 +118,7 @@ pub(crate) unsafe fn try_pod_read_unaligned<T: Copy>(
|
||||
/// ## Panics
|
||||
/// * This is like `try_pod_read_unaligned` but will panic on failure.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn pod_read_unaligned<T: Copy>(bytes: &[u8]) -> T {
|
||||
match try_pod_read_unaligned(bytes) {
|
||||
Ok(t) => t,
|
||||
@ -127,6 +131,7 @@ pub(crate) unsafe fn pod_read_unaligned<T: Copy>(bytes: &[u8]) -> T {
|
||||
/// ## Panics
|
||||
/// * If `align` is not a power of two. This includes when `align` is zero.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) fn is_aligned_to(ptr: *const (), align: usize) -> bool {
|
||||
#[cfg(feature = "align_offset")]
|
||||
{
|
||||
@ -186,6 +191,7 @@ pub(crate) unsafe fn try_from_bytes_mut<T: Copy>(
|
||||
///
|
||||
/// * This is like [`try_cast`](try_cast), but will panic on a size mismatch.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn cast<A: Copy, B: Copy>(a: A) -> B {
|
||||
if size_of::<A>() == size_of::<B>() {
|
||||
unsafe { transmute!(a) }
|
||||
@ -200,6 +206,7 @@ pub(crate) unsafe fn cast<A: Copy, B: Copy>(a: A) -> B {
|
||||
///
|
||||
/// This is [`try_cast_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn cast_mut<A: Copy, B: Copy>(a: &mut A) -> &mut B {
|
||||
if size_of::<A>() == size_of::<B>() && align_of::<A>() >= align_of::<B>() {
|
||||
// Plz mr compiler, just notice that we can't ever hit Err in this case.
|
||||
@ -221,6 +228,7 @@ pub(crate) unsafe fn cast_mut<A: Copy, B: Copy>(a: &mut A) -> &mut B {
|
||||
///
|
||||
/// This is [`try_cast_ref`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn cast_ref<A: Copy, B: Copy>(a: &A) -> &B {
|
||||
if size_of::<A>() == size_of::<B>() && align_of::<A>() >= align_of::<B>() {
|
||||
// Plz mr compiler, just notice that we can't ever hit Err in this case.
|
||||
@ -242,6 +250,7 @@ pub(crate) unsafe fn cast_ref<A: Copy, B: Copy>(a: &A) -> &B {
|
||||
///
|
||||
/// This is [`try_cast_slice`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn cast_slice<A: Copy, B: Copy>(a: &[A]) -> &[B] {
|
||||
match try_cast_slice(a) {
|
||||
Ok(b) => b,
|
||||
@ -255,6 +264,7 @@ pub(crate) unsafe fn cast_slice<A: Copy, B: Copy>(a: &[A]) -> &[B] {
|
||||
///
|
||||
/// This is [`try_cast_slice_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub(crate) unsafe fn cast_slice_mut<A: Copy, B: Copy>(a: &mut [A]) -> &mut [B] {
|
||||
match try_cast_slice_mut(a) {
|
||||
Ok(b) => b,
|
||||
|
42
src/lib.rs
42
src/lib.rs
@ -123,18 +123,20 @@ macro_rules! transmute {
|
||||
($val:expr) => {
|
||||
::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) => {
|
||||
{
|
||||
#[repr(C)]
|
||||
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)
|
||||
// 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) => {{
|
||||
#[repr(C)]
|
||||
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.
|
||||
@ -210,12 +212,12 @@ pub use bytemuck_derive::{
|
||||
/// The things that can go wrong when casting between [`Pod`] data forms.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum PodCastError {
|
||||
/// You tried to cast a reference into a reference to a type with a higher alignment
|
||||
/// requirement but the input reference wasn't aligned.
|
||||
/// You tried to cast a reference into a reference to a type with a higher
|
||||
/// alignment requirement but the input reference wasn't aligned.
|
||||
TargetAlignmentGreaterAndInputNotAligned,
|
||||
/// If the element size of a slice changes, then the output slice changes length
|
||||
/// accordingly. If the output slice wouldn't be a whole number of elements,
|
||||
/// then the conversion fails.
|
||||
/// If the element size of a slice changes, then the output slice changes
|
||||
/// length accordingly. If the output slice wouldn't be a whole number of
|
||||
/// elements, then the conversion fails.
|
||||
OutputSliceWouldHaveSlop,
|
||||
/// When casting an individual `T`, `&T`, or `&mut T` value the
|
||||
/// source size and destination size must be an exact match.
|
||||
@ -262,6 +264,7 @@ pub fn bytes_of_mut<T: NoUninit + AnyBitPattern>(t: &mut T) -> &mut [u8] {
|
||||
///
|
||||
/// This is like [`try_from_bytes`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn from_bytes<T: AnyBitPattern>(s: &[u8]) -> &T {
|
||||
unsafe { internal::from_bytes(s) }
|
||||
}
|
||||
@ -272,6 +275,7 @@ pub fn from_bytes<T: AnyBitPattern>(s: &[u8]) -> &T {
|
||||
///
|
||||
/// This is like [`try_from_bytes_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn from_bytes_mut<T: NoUninit + AnyBitPattern>(s: &mut [u8]) -> &mut T {
|
||||
unsafe { internal::from_bytes_mut(s) }
|
||||
}
|
||||
@ -298,6 +302,7 @@ pub fn try_pod_read_unaligned<T: AnyBitPattern>(
|
||||
/// ## Panics
|
||||
/// * This is like `try_pod_read_unaligned` but will panic on failure.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn pod_read_unaligned<T: AnyBitPattern>(bytes: &[u8]) -> T {
|
||||
unsafe { internal::pod_read_unaligned(bytes) }
|
||||
}
|
||||
@ -332,6 +337,7 @@ pub fn try_from_bytes_mut<T: NoUninit + AnyBitPattern>(
|
||||
///
|
||||
/// * This is like [`try_cast`], but will panic on a size mismatch.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
|
||||
unsafe { internal::cast(a) }
|
||||
}
|
||||
@ -342,6 +348,7 @@ pub fn cast<A: NoUninit, B: AnyBitPattern>(a: A) -> B {
|
||||
///
|
||||
/// This is [`try_cast_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_mut<A: NoUninit + AnyBitPattern, B: NoUninit + AnyBitPattern>(
|
||||
a: &mut A,
|
||||
) -> &mut B {
|
||||
@ -354,6 +361,7 @@ pub fn cast_mut<A: NoUninit + AnyBitPattern, B: NoUninit + AnyBitPattern>(
|
||||
///
|
||||
/// This is [`try_cast_ref`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B {
|
||||
unsafe { internal::cast_ref(a) }
|
||||
}
|
||||
@ -364,6 +372,7 @@ pub fn cast_ref<A: NoUninit, B: AnyBitPattern>(a: &A) -> &B {
|
||||
///
|
||||
/// This is [`try_cast_slice`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] {
|
||||
unsafe { internal::cast_slice(a) }
|
||||
}
|
||||
@ -374,6 +383,7 @@ pub fn cast_slice<A: NoUninit, B: AnyBitPattern>(a: &[A]) -> &[B] {
|
||||
///
|
||||
/// This is [`try_cast_slice_mut`] but will panic on error.
|
||||
#[inline]
|
||||
#[cfg_attr(feature = "track_caller", track_caller)]
|
||||
pub fn cast_slice_mut<
|
||||
A: NoUninit + AnyBitPattern,
|
||||
B: NoUninit + AnyBitPattern,
|
||||
|
Loading…
Reference in New Issue
Block a user