From b3a56be1880bdffc734f5878ae7417df4cef8615 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Mon, 30 Dec 2024 16:18:34 -0500 Subject: [PATCH] Include arguments to the precondition check in failure messages --- library/core/src/alloc/layout.rs | 2 +- library/core/src/ascii/ascii_char.rs | 2 +- library/core/src/char/convert.rs | 2 +- library/core/src/num/int_macros.rs | 6 +++++ library/core/src/num/nonzero.rs | 2 ++ library/core/src/num/uint_macros.rs | 5 ++++ library/core/src/ops/index_range.rs | 3 ++- library/core/src/ptr/alignment.rs | 3 ++- library/core/src/ptr/const_ptr.rs | 12 ++++++--- library/core/src/ptr/mod.rs | 27 ++++++++++++------- library/core/src/ptr/mut_ptr.rs | 9 ++++--- library/core/src/ptr/non_null.rs | 2 +- library/core/src/slice/index.rs | 22 +++++++++------ library/core/src/slice/mod.rs | 15 +++++++---- library/core/src/slice/raw.rs | 6 +++-- library/core/src/str/traits.rs | 12 ++++++--- library/core/src/ub_checks.rs | 16 ++++++----- tests/ui/precondition-checks/alignment.rs | 2 +- .../ascii-char-digit_unchecked.rs | 2 +- .../precondition-checks/assert_unchecked.rs | 2 +- .../char-from_u32_unchecked.rs | 2 +- .../copy-nonoverlapping.rs | 2 +- tests/ui/precondition-checks/copy.rs | 2 +- tests/ui/precondition-checks/layout.rs | 2 +- tests/ui/precondition-checks/nonnull.rs | 2 +- .../nonzero-from_mut_unchecked.rs | 2 +- .../nonzero-new_unchecked.rs | 2 +- tests/ui/precondition-checks/read.rs | 2 +- tests/ui/precondition-checks/read_volatile.rs | 2 +- tests/ui/precondition-checks/replace.rs | 2 +- .../slice-from-raw-parts-mut.rs | 2 +- .../slice-from-raw-parts.rs | 2 +- .../slice-get_unchecked.rs | 2 +- .../slice-get_unchecked_mut.rs | 2 +- .../precondition-checks/str-get_unchecked.rs | 2 +- .../str-get_unchecked_mut.rs | 2 +- .../swap-nonoverlapping.rs | 2 +- tests/ui/precondition-checks/unchecked_add.rs | 2 +- tests/ui/precondition-checks/unchecked_mul.rs | 2 +- tests/ui/precondition-checks/unchecked_shl.rs | 2 +- tests/ui/precondition-checks/unchecked_shr.rs | 2 +- tests/ui/precondition-checks/unchecked_sub.rs | 2 +- .../unreachable_unchecked.rs | 2 +- tests/ui/precondition-checks/write.rs | 2 +- tests/ui/precondition-checks/write_bytes.rs | 2 +- .../ui/precondition-checks/write_volatile.rs | 2 +- 46 files changed, 128 insertions(+), 76 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 380f67f91f947..2f5b889d08029 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -131,7 +131,7 @@ impl Layout { assert_unsafe_precondition!( check_library_ub, "Layout::from_size_align_unchecked requires that align is a power of 2 \ - and the rounded-up allocation size does not exceed isize::MAX", + and the rounded-up allocation size does not exceed isize::MAX (size:{size}, align:{align})", ( size: usize = size, align: usize = align, diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index 0b72b4780f163..cb5352be34ad0 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -507,7 +507,7 @@ impl AsciiChar { pub const unsafe fn digit_unchecked(d: u8) -> Self { assert_unsafe_precondition!( check_language_ub, - "`ascii::Char::digit_unchecked` input cannot exceed 9.", + "`ascii::Char::digit_unchecked` input cannot exceed 9. (d:{d})", (d: u8 = d) => d < 10 ); diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 78cd89fefae71..69b63999e7fd6 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -28,7 +28,7 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { unsafe { assert_unsafe_precondition!( check_language_ub, - "invalid value for `char`", + "invalid value for `char` ({i})", (i: u32 = i) => char_try_from_u32(i).is_ok() ); transmute(i) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 5683d5ec92dc7..d9e237d32df3b 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -517,6 +517,7 @@ macro_rules! int_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -659,6 +660,7 @@ macro_rules! int_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -801,6 +803,7 @@ macro_rules! int_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -1227,6 +1230,7 @@ macro_rules! int_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, ) => !lhs.overflowing_neg().1, @@ -1349,6 +1353,7 @@ macro_rules! int_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + // FIXME: concat! prevents adding formatting ( rhs: u32 = rhs, ) => rhs < <$ActualT>::BITS, @@ -1465,6 +1470,7 @@ macro_rules! int_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + // FIXME: concat! prevents adding formatting ( rhs: u32 = rhs, ) => rhs < <$ActualT>::BITS, diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 0fa066c8f7e38..74a9a4f3987d2 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -399,6 +399,7 @@ where ub_checks::assert_unsafe_precondition!( check_language_ub, "NonZero::new_unchecked requires the argument to be non-zero", + // FIXME: Can't print n here because of how the check is written () => false, ); intrinsics::unreachable() @@ -440,6 +441,7 @@ where ub_checks::assert_unsafe_precondition!( check_library_ub, "NonZero::from_mut_unchecked requires the argument to dereference as non-zero", + // FIXME: Can't print n here because of how the check is written () => false, ); intrinsics::unreachable() diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 9cadbd47ab6a5..f105cf48a7084 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -586,6 +586,7 @@ macro_rules! uint_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_add cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -768,6 +769,7 @@ macro_rules! uint_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -943,6 +945,7 @@ macro_rules! uint_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"), + // FIXME: concat! prevents adding formatting ( lhs: $SelfT = self, rhs: $SelfT = rhs, @@ -1631,6 +1634,7 @@ macro_rules! uint_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"), + // FIXME: concat! prevents adding formatting ( rhs: u32 = rhs, ) => rhs < <$ActualT>::BITS, @@ -1747,6 +1751,7 @@ macro_rules! uint_impl { assert_unsafe_precondition!( check_language_ub, concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"), + // FIXME: concat! prevents adding formatting ( rhs: u32 = rhs, ) => rhs < <$ActualT>::BITS, diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 507fa9460bea6..1f9e21297ccc1 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -23,7 +23,8 @@ impl IndexRange { pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self { ub_checks::assert_unsafe_precondition!( check_library_ub, - "IndexRange::new_unchecked requires `start <= end`", + "IndexRange::new_unchecked requires `start <= end` \ + (start:{start}, end:{end})", (start: usize = start, end: usize = end) => start <= end, ); IndexRange { start, end } diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 3e66e271f03b6..84f5600522597 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -77,7 +77,8 @@ impl Alignment { pub const unsafe fn new_unchecked(align: usize) -> Self { assert_unsafe_precondition!( check_language_ub, - "Alignment::new_unchecked requires a power of two", + "Alignment::new_unchecked requires a power of two \ + (align:{align})", (align: usize = align) => align.is_power_of_two() ); diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 27b0c6830db61..dc959d7b50e0d 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -424,7 +424,8 @@ impl *const T { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::offset requires the address calculation to not overflow", + "ptr::offset requires the address calculation to not overflow \ + (ptr:{this:?}, count:{count}, size:{size})", ( this: *const () = self as *const (), count: isize = count, @@ -768,7 +769,8 @@ impl *const T { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::offset_from_unsigned requires `self >= origin`", + "ptr::offset_from_unsigned requires `self >= origin` \ + (self:{this:?}, origin:{origin:?})", ( this: *const () = self as *const (), origin: *const () = origin as *const (), @@ -903,7 +905,8 @@ impl *const T { #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild. ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::add requires that the address calculation does not overflow", + "ptr::add requires that the address calculation does not overflow \ + (self:{this:?}, count:{count}, size:{size})", ( this: *const () = self as *const (), count: usize = count, @@ -1008,7 +1011,8 @@ impl *const T { #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild. ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::sub requires that the address calculation does not overflow", + "ptr::sub requires that the address calculation does not overflow \ + (self:{this:?}, count:{count}, size:{size})", ( this: *const () = self as *const (), count: usize = count, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index fe8c6f830341c..0f2aed6f6331d 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -522,7 +522,8 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us ub_checks::assert_unsafe_precondition!( check_language_ub, "ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null \ - and the specified memory ranges do not overlap", + and the specified memory ranges do not overlap \ + (src{src:?}, dst:{dst:?}, size:{size:?}, align:{align:?}, count:{count:?})", ( src: *const () = src as *const (), dst: *mut () = dst as *mut (), @@ -620,7 +621,8 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::copy requires that both pointer arguments are aligned and non-null", + "ptr::copy requires that both pointer arguments are aligned and non-null \ + (src{src:?}, dst:{dst:?}, align:{align:?})", ( src: *const () = src as *const (), dst: *mut () = dst as *mut (), @@ -694,7 +696,8 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::write_bytes requires that the destination pointer is aligned and non-null", + "ptr::write_bytes requires that the destination pointer is aligned and non-null \ + (dst:{addr:?}, align:{align})", ( addr: *const () = dst as *const (), align: usize = align_of::(), @@ -1384,7 +1387,8 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { ub_checks::assert_unsafe_precondition!( check_library_ub, "ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null \ - and the specified memory ranges do not overlap", + and the specified memory ranges do not overlap \ + (x:{x:?}, y:{y:?}, size:{size}, align:{align}, count:{count})", ( x: *mut () = x as *mut (), y: *mut () = y as *mut (), @@ -1569,7 +1573,8 @@ pub const unsafe fn replace(dst: *mut T, src: T) -> T { unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::replace requires that the pointer argument is aligned and non-null", + "ptr::replace requires that the pointer argument is aligned and non-null\ + (dst:{addr:?}, (align:{align}))", ( addr: *const () = dst as *const (), align: usize = align_of::(), @@ -1722,7 +1727,8 @@ pub const unsafe fn read(src: *const T) -> T { #[cfg(debug_assertions)] // Too expensive to always enable (for now?) ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::read requires that the pointer argument is aligned and non-null", + "ptr::read requires that the pointer argument is aligned and non-null \ + (src:{addr:?}, align:{align})", ( addr: *const () = src as *const (), align: usize = align_of::(), @@ -1922,7 +1928,8 @@ pub const unsafe fn write(dst: *mut T, src: T) { #[cfg(debug_assertions)] // Too expensive to always enable (for now?) ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::write requires that the pointer argument is aligned and non-null", + "ptr::write requires that the pointer argument is aligned and non-null \ + (dst:{addr:?}, align:{align})", ( addr: *mut () = dst as *mut (), align: usize = align_of::(), @@ -2090,7 +2097,8 @@ pub unsafe fn read_volatile(src: *const T) -> T { unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::read_volatile requires that the pointer argument is aligned and non-null", + "ptr::read_volatile requires that the pointer argument is aligned and non-null \ + (src:{addr:?}, align:{align})", ( addr: *const () = src as *const (), align: usize = align_of::(), @@ -2170,7 +2178,8 @@ pub unsafe fn write_volatile(dst: *mut T, src: T) { unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::write_volatile requires that the pointer argument is aligned and non-null", + "ptr::write_volatile requires that the pointer argument is aligned and non-null \ + (dst:{addr:?}, align:{align})", ( addr: *mut () = dst as *mut (), align: usize = align_of::(), diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 73efdf0445412..7b9346bfe22aa 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -422,7 +422,8 @@ impl *mut T { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::offset requires the address calculation to not overflow", + "ptr::offset requires the address calculation to not overflow \ + (self:{this:?}, count:{count}, size:{size})", ( this: *const () = self as *const (), count: isize = count, @@ -996,7 +997,8 @@ impl *mut T { #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild. ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::add requires that the address calculation does not overflow", + "ptr::add requires that the address calculation does not overflow \ + (self:{this:?}, count:{count}, size:{size})", ( this: *const () = self as *const (), count: usize = count, @@ -1101,7 +1103,8 @@ impl *mut T { #[cfg(debug_assertions)] // Expensive, and doesn't catch much in the wild. ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::sub requires that the address calculation does not overflow", + "ptr::sub requires that the address calculation does not overflow \ + (self:{this:?}, count:{count}, size:{size})", ( this: *const () = self as *const (), count: usize = count, diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c26c3a32ef3a2..57a449be0a8eb 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -228,7 +228,7 @@ impl NonNull { unsafe { assert_unsafe_precondition!( check_language_ub, - "NonNull::new_unchecked requires that the pointer is non-null", + "NonNull::new_unchecked requires that the pointer is non-null (ptr:{ptr:?})", (ptr: *mut () = ptr as *mut ()) => !ptr.is_null() ); NonNull { pointer: ptr as _ } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index f725c3fdd94cc..54d96baae083a 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -236,8 +236,9 @@ unsafe impl SliceIndex<[T]> for usize { unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { assert_unsafe_precondition!( check_language_ub, - "slice::get_unchecked requires that the index is within the slice", - (this: usize = self, len: usize = slice.len()) => this < len + "slice::get_unchecked requires that the index is within the slice \ + (index:{index}, len:{len})", + (index: usize = self, len: usize = slice.len()) => index < len ); // SAFETY: the caller guarantees that `slice` is not dangling, so it // cannot be longer than `isize::MAX`. They also guarantee that @@ -256,8 +257,9 @@ unsafe impl SliceIndex<[T]> for usize { unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T { assert_unsafe_precondition!( check_library_ub, - "slice::get_unchecked_mut requires that the index is within the slice", - (this: usize = self, len: usize = slice.len()) => this < len + "slice::get_unchecked_mut requires that the index is within the slice \ + (index:{index}, len:{len})", + (index: usize = self, len: usize = slice.len()) => index < len ); // SAFETY: see comments for `get_unchecked` above. unsafe { slice_get_unchecked(slice, self) } @@ -306,7 +308,8 @@ unsafe impl SliceIndex<[T]> for ops::IndexRange { unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { assert_unsafe_precondition!( check_library_ub, - "slice::get_unchecked requires that the index is within the slice", + "slice::get_unchecked requires that the index is within the slice \ + (end:{end}, len:{len})", (end: usize = self.end(), len: usize = slice.len()) => end <= len ); // SAFETY: the caller guarantees that `slice` is not dangling, so it @@ -321,7 +324,8 @@ unsafe impl SliceIndex<[T]> for ops::IndexRange { unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { assert_unsafe_precondition!( check_library_ub, - "slice::get_unchecked_mut requires that the index is within the slice", + "slice::get_unchecked_mut requires that the index is within the slice \ + (end:{end}, len:{len})", (end: usize = self.end(), len: usize = slice.len()) => end <= len ); @@ -387,7 +391,8 @@ unsafe impl SliceIndex<[T]> for ops::Range { unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { assert_unsafe_precondition!( check_library_ub, - "slice::get_unchecked requires that the range is within the slice", + "slice::get_unchecked requires that the range is within the slice \ + (range:{start}..{end}, len:{len})", ( start: usize = self.start, end: usize = self.end, @@ -412,7 +417,8 @@ unsafe impl SliceIndex<[T]> for ops::Range { unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { assert_unsafe_precondition!( check_library_ub, - "slice::get_unchecked_mut requires that the range is within the slice", + "slice::get_unchecked_mut requires that the range is within the slice \ + (range:{start}..{end}, len:{len})", ( start: usize = self.start, end: usize = self.end, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 3a3f44c6b8546..fcd85e30f978a 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -942,7 +942,8 @@ impl [T] { pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) { assert_unsafe_precondition!( check_library_ub, - "slice::swap_unchecked requires that the indices are within the slice", + "slice::swap_unchecked requires that the indices are within the slice \ + (a:{a}, b:{b}, len:{len})", ( len: usize = self.len(), a: usize = a, @@ -1315,7 +1316,8 @@ impl [T] { pub const unsafe fn as_chunks_unchecked(&self) -> &[[T; N]] { assert_unsafe_precondition!( check_language_ub, - "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks", + "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks \ + (N:{n}, len:{len})", (n: usize = N, len: usize = self.len()) => n != 0 && len % n == 0, ); // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length @@ -1511,7 +1513,8 @@ impl [T] { pub const unsafe fn as_chunks_unchecked_mut(&mut self) -> &mut [[T; N]] { assert_unsafe_precondition!( check_language_ub, - "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks", + "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks \ + (N:{n}, len:{len})", (n: usize = N, len: usize = self.len()) => n != 0 && len % n == 0 ); // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length @@ -2078,7 +2081,8 @@ impl [T] { assert_unsafe_precondition!( check_library_ub, - "slice::split_at_unchecked requires the index to be within the slice", + "slice::split_at_unchecked requires the index to be within the slice \ + (mid:{mid}, len:{len})", (mid: usize = mid, len: usize = len) => mid <= len, ); @@ -2128,7 +2132,8 @@ impl [T] { assert_unsafe_precondition!( check_library_ub, - "slice::split_at_mut_unchecked requires the index to be within the slice", + "slice::split_at_mut_unchecked requires the index to be within the slice \ + (mid:{mid}, len:{len})", (mid: usize = mid, len: usize = len) => mid <= len, ); diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 80b2176933dab..d86ac0b51a471 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -126,7 +126,8 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`", + "slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX` \ + (data:{data:?}, size:{size}, align:{align}, len:{len})", ( data: *mut () = data as *mut (), size: usize = size_of::(), @@ -181,7 +182,8 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m unsafe { ub_checks::assert_unsafe_precondition!( check_language_ub, - "slice::from_raw_parts_mut requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`", + "slice::from_raw_parts_mut requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX` \ + (data:{data:?}, size:{size}, align:{align}, len:{len})", ( data: *mut () = data as *mut (), size: usize = size_of::(), diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index b9559c8317133..01b927d5aef1d 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -198,7 +198,8 @@ unsafe impl SliceIndex for ops::Range { // `str::get_unchecked` without adding a special function // to `SliceIndex` just for this. check_library_ub, - "str::get_unchecked requires that the range is within the string slice", + "str::get_unchecked requires that the range is within the string slice \ + (range:{start}..{end}, len:{len})", ( start: usize = self.start, end: usize = self.end, @@ -220,7 +221,8 @@ unsafe impl SliceIndex for ops::Range { assert_unsafe_precondition!( check_library_ub, - "str::get_unchecked_mut requires that the range is within the string slice", + "str::get_unchecked_mut requires that the range is within the string slice \ + (range:{start}..{end}, len:{len})", ( start: usize = self.start, end: usize = self.end, @@ -302,7 +304,8 @@ unsafe impl SliceIndex for range::Range { // `str::get_unchecked` without adding a special function // to `SliceIndex` just for this. check_library_ub, - "str::get_unchecked requires that the range is within the string slice", + "str::get_unchecked requires that the range is within the string slice \ + (range:{start}..{end}, len:{len})", ( start: usize = self.start, end: usize = self.end, @@ -324,7 +327,8 @@ unsafe impl SliceIndex for range::Range { assert_unsafe_precondition!( check_library_ub, - "str::get_unchecked_mut requires that the range is within the string slice", + "str::get_unchecked_mut requires that the range is within the string slice \ + (range:{start}..{end}, len:{len})", ( start: usize = self.start, end: usize = self.end, diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index a7caaeb95cdba..41ce0f93a00cb 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -64,13 +64,17 @@ macro_rules! assert_unsafe_precondition { #[inline] #[rustc_nounwind] #[track_caller] + #[rustc_allow_const_fn_unstable(const_eval_select)] const fn precondition_check($($name:$ty),*) { - if !$e { - let msg = concat!("unsafe precondition(s) violated: ", $message, - "\n\nThis indicates a bug in the program. \ - This Undefined Behavior check is optional, and cannot be relied on for safety."); - ::core::panicking::panic_nounwind_fmt(::core::fmt::Arguments::new_const(&[msg]), false); - } + if $e { return; } + crate::intrinsics::const_eval_select!( + @capture { $($name: $ty),* }: + if const { + ::core::panicking::panic_nounwind($message); + } else #[allow(unused)] { + ::core::panicking::panic_nounwind_fmt(format_args!($message), false); + } + ) } if ::core::ub_checks::$kind() { diff --git a/tests/ui/precondition-checks/alignment.rs b/tests/ui/precondition-checks/alignment.rs index 92400528fa07f..1e9048b6b9838 100644 --- a/tests/ui/precondition-checks/alignment.rs +++ b/tests/ui/precondition-checks/alignment.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: Alignment::new_unchecked requires +//@ error-pattern: Alignment::new_unchecked requires #![feature(ptr_alignment_type)] diff --git a/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs index 30c6f79fb08f0..c0007edba00ab 100644 --- a/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs +++ b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: `ascii::Char::digit_unchecked` input cannot exceed 9 +//@ error-pattern: `ascii::Char::digit_unchecked` input cannot exceed 9 #![feature(ascii_char)] diff --git a/tests/ui/precondition-checks/assert_unchecked.rs b/tests/ui/precondition-checks/assert_unchecked.rs index 22b2b41455021..805c43d9ce8b3 100644 --- a/tests/ui/precondition-checks/assert_unchecked.rs +++ b/tests/ui/precondition-checks/assert_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: hint::assert_unchecked must never be called when the condition is false +//@ error-pattern: hint::assert_unchecked must never be called when the condition is false fn main() { unsafe { diff --git a/tests/ui/precondition-checks/char-from_u32_unchecked.rs b/tests/ui/precondition-checks/char-from_u32_unchecked.rs index d950f20c77208..90a0323f0581a 100644 --- a/tests/ui/precondition-checks/char-from_u32_unchecked.rs +++ b/tests/ui/precondition-checks/char-from_u32_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: invalid value for `char` +//@ error-pattern: invalid value for `char` fn main() { unsafe { diff --git a/tests/ui/precondition-checks/copy-nonoverlapping.rs b/tests/ui/precondition-checks/copy-nonoverlapping.rs index eacaa63e543af..dee3e00221306 100644 --- a/tests/ui/precondition-checks/copy-nonoverlapping.rs +++ b/tests/ui/precondition-checks/copy-nonoverlapping.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::copy_nonoverlapping requires +//@ error-pattern: ptr::copy_nonoverlapping requires //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/copy.rs b/tests/ui/precondition-checks/copy.rs index 1fadd90bf70bd..4988673c49489 100644 --- a/tests/ui/precondition-checks/copy.rs +++ b/tests/ui/precondition-checks/copy.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::copy requires +//@ error-pattern: ptr::copy requires //@ revisions: null_src null_dst misaligned_src misaligned_dst #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/layout.rs b/tests/ui/precondition-checks/layout.rs index 4ee66cc932886..5b068487d92e0 100644 --- a/tests/ui/precondition-checks/layout.rs +++ b/tests/ui/precondition-checks/layout.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: Layout::from_size_align_unchecked requires +//@ error-pattern: Layout::from_size_align_unchecked requires //@ revisions: toolarge badalign fn main() { diff --git a/tests/ui/precondition-checks/nonnull.rs b/tests/ui/precondition-checks/nonnull.rs index 6b8edd4e5825e..1be965000bd7d 100644 --- a/tests/ui/precondition-checks/nonnull.rs +++ b/tests/ui/precondition-checks/nonnull.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: NonNull::new_unchecked requires +//@ error-pattern: NonNull::new_unchecked requires fn main() { unsafe { diff --git a/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs index 46ce7dc356fe2..4239e5aede2d5 100644 --- a/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs +++ b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: NonZero::from_mut_unchecked requires +//@ error-pattern: NonZero::from_mut_unchecked requires #![feature(nonzero_from_mut)] diff --git a/tests/ui/precondition-checks/nonzero-new_unchecked.rs b/tests/ui/precondition-checks/nonzero-new_unchecked.rs index 7827a42844fd4..bd327376cd774 100644 --- a/tests/ui/precondition-checks/nonzero-new_unchecked.rs +++ b/tests/ui/precondition-checks/nonzero-new_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: NonZero::new_unchecked requires +//@ error-pattern: NonZero::new_unchecked requires fn main() { unsafe { diff --git a/tests/ui/precondition-checks/read.rs b/tests/ui/precondition-checks/read.rs index d5ab7773987fc..336cec6175770 100644 --- a/tests/ui/precondition-checks/read.rs +++ b/tests/ui/precondition-checks/read.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::read requires +//@ error-pattern: ptr::read requires //@ revisions: null misaligned //@ ignore-test (unimplemented) diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs index ada8932c398ce..2d53cf77580bc 100644 --- a/tests/ui/precondition-checks/read_volatile.rs +++ b/tests/ui/precondition-checks/read_volatile.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires +//@ error-pattern: ptr::read_volatile requires //@ revisions: null misaligned #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/replace.rs b/tests/ui/precondition-checks/replace.rs index 44afbd8174c03..d6fec0e7a18b9 100644 --- a/tests/ui/precondition-checks/replace.rs +++ b/tests/ui/precondition-checks/replace.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::replace requires +//@ error-pattern: ptr::replace requires //@ revisions: null misaligned #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs index 9b9ded69a83b6..219bfdbb7ceda 100644 --- a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs +++ b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts_mut requires +//@ error-pattern: slice::from_raw_parts_mut requires //@ revisions: null misaligned toolarge #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/slice-from-raw-parts.rs b/tests/ui/precondition-checks/slice-from-raw-parts.rs index 96578c1eae58b..f794972910488 100644 --- a/tests/ui/precondition-checks/slice-from-raw-parts.rs +++ b/tests/ui/precondition-checks/slice-from-raw-parts.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts requires +//@ error-pattern: slice::from_raw_parts requires //@ revisions: null misaligned toolarge #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/slice-get_unchecked.rs b/tests/ui/precondition-checks/slice-get_unchecked.rs index 1d8188fb9531a..7285c97162c5a 100644 --- a/tests/ui/precondition-checks/slice-get_unchecked.rs +++ b/tests/ui/precondition-checks/slice-get_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked requires +//@ error-pattern: slice::get_unchecked requires //@ revisions: usize range range_to range_from backwards_range fn main() { diff --git a/tests/ui/precondition-checks/slice-get_unchecked_mut.rs b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs index 34c1454af438d..3500d84602e73 100644 --- a/tests/ui/precondition-checks/slice-get_unchecked_mut.rs +++ b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked_mut requires +//@ error-pattern: slice::get_unchecked_mut requires //@ revisions: usize range range_to range_from backwards_range fn main() { diff --git a/tests/ui/precondition-checks/str-get_unchecked.rs b/tests/ui/precondition-checks/str-get_unchecked.rs index 14d17f997ec9b..df3699fd019ed 100644 --- a/tests/ui/precondition-checks/str-get_unchecked.rs +++ b/tests/ui/precondition-checks/str-get_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: str::get_unchecked requires +//@ error-pattern: str::get_unchecked requires //@ revisions: range range_to range_from backwards_range fn main() { diff --git a/tests/ui/precondition-checks/str-get_unchecked_mut.rs b/tests/ui/precondition-checks/str-get_unchecked_mut.rs index ca1b169005559..353c5dd5b93f0 100644 --- a/tests/ui/precondition-checks/str-get_unchecked_mut.rs +++ b/tests/ui/precondition-checks/str-get_unchecked_mut.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: str::get_unchecked_mut requires +//@ error-pattern: str::get_unchecked_mut requires //@ revisions: range range_to range_from backwards_range fn main() { diff --git a/tests/ui/precondition-checks/swap-nonoverlapping.rs b/tests/ui/precondition-checks/swap-nonoverlapping.rs index ea1f6f36ad787..f17ee88a82110 100644 --- a/tests/ui/precondition-checks/swap-nonoverlapping.rs +++ b/tests/ui/precondition-checks/swap-nonoverlapping.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires +//@ error-pattern: ptr::swap_nonoverlapping requires //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping #![allow(invalid_null_arguments)] diff --git a/tests/ui/precondition-checks/unchecked_add.rs b/tests/ui/precondition-checks/unchecked_add.rs index f44a6ea32ad8f..a669f625444d9 100644 --- a/tests/ui/precondition-checks/unchecked_add.rs +++ b/tests/ui/precondition-checks/unchecked_add.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow +//@ error-pattern: u8::unchecked_add cannot overflow fn main() { unsafe { diff --git a/tests/ui/precondition-checks/unchecked_mul.rs b/tests/ui/precondition-checks/unchecked_mul.rs index 66655dda136e9..eae371b417916 100644 --- a/tests/ui/precondition-checks/unchecked_mul.rs +++ b/tests/ui/precondition-checks/unchecked_mul.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow +//@ error-pattern: u8::unchecked_add cannot overflow fn main() { unsafe { diff --git a/tests/ui/precondition-checks/unchecked_shl.rs b/tests/ui/precondition-checks/unchecked_shl.rs index 1c96db0b1ec71..27031219bbd8f 100644 --- a/tests/ui/precondition-checks/unchecked_shl.rs +++ b/tests/ui/precondition-checks/unchecked_shl.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shl cannot overflow +//@ error-pattern: u8::unchecked_shl cannot overflow #![feature(unchecked_shifts)] diff --git a/tests/ui/precondition-checks/unchecked_shr.rs b/tests/ui/precondition-checks/unchecked_shr.rs index 4a6d9ffb1d35b..1c43edc105389 100644 --- a/tests/ui/precondition-checks/unchecked_shr.rs +++ b/tests/ui/precondition-checks/unchecked_shr.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shr cannot overflow +//@ error-pattern: u8::unchecked_shr cannot overflow #![feature(unchecked_shifts)] diff --git a/tests/ui/precondition-checks/unchecked_sub.rs b/tests/ui/precondition-checks/unchecked_sub.rs index 545dde0e27809..a8d18ec10d4f0 100644 --- a/tests/ui/precondition-checks/unchecked_sub.rs +++ b/tests/ui/precondition-checks/unchecked_sub.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_sub cannot overflow +//@ error-pattern: u8::unchecked_sub cannot overflow fn main() { unsafe { diff --git a/tests/ui/precondition-checks/unreachable_unchecked.rs b/tests/ui/precondition-checks/unreachable_unchecked.rs index 2435450c4b5a1..19b12cfe9b2e2 100644 --- a/tests/ui/precondition-checks/unreachable_unchecked.rs +++ b/tests/ui/precondition-checks/unreachable_unchecked.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached +//@ error-pattern: hint::unreachable_unchecked must never be reached fn main() { unsafe { diff --git a/tests/ui/precondition-checks/write.rs b/tests/ui/precondition-checks/write.rs index 5d6b9586fad7d..937db484f2076 100644 --- a/tests/ui/precondition-checks/write.rs +++ b/tests/ui/precondition-checks/write.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::write requires +//@ error-pattern: ptr::write requires //@ revisions: null misaligned //@ ignore-test (unimplemented) diff --git a/tests/ui/precondition-checks/write_bytes.rs b/tests/ui/precondition-checks/write_bytes.rs index be4f5a089f035..845de7c90433c 100644 --- a/tests/ui/precondition-checks/write_bytes.rs +++ b/tests/ui/precondition-checks/write_bytes.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::write requires +//@ error-pattern: ptr::write requires //@ revisions: null misaligned //@ ignore-test (unimplemented) diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs index 0d5ecb014b3d9..63b918d418e3b 100644 --- a/tests/ui/precondition-checks/write_volatile.rs +++ b/tests/ui/precondition-checks/write_volatile.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires +//@ error-pattern: ptr::write_volatile requires //@ revisions: null misaligned #![allow(invalid_null_arguments)]