add track_caller feature (#276)

closes #68
This commit is contained in:
Christofer Nolander 2024-10-13 06:06:43 +02:00 committed by GitHub
parent 1c09edf7b0
commit da9b1874d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 51 additions and 16 deletions

View File

@ -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",

View File

@ -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> {

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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,