Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add track_caller feature #276

Merged
merged 1 commit into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -57,6 +60,7 @@ latest_stable_rust = [
"derive",
"min_const_generics",
"must_cast",
"track_caller",
"wasm_simd",
"zeroable_atomics",
"zeroable_maybe_uninit",
Expand Down
1 change: 1 addition & 0 deletions src/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
8 changes: 8 additions & 0 deletions src/checked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/contiguous.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
) -> ! {
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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")]
{
Expand Down Expand Up @@ -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) }
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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,
Expand All @@ -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,
Expand Down
42 changes: 26 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) }
}
Expand All @@ -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) }
}
Expand All @@ -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) }
}
Expand Down Expand Up @@ -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) }
}
Expand All @@ -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 {
Expand All @@ -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) }
}
Expand All @@ -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) }
}
Expand All @@ -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,
Expand Down
Loading