Skip to content

Include arguments to the precondition check in failure messages #134938

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
@@ -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,
2 changes: 1 addition & 1 deletion library/core/src/ascii/ascii_char.rs
Original file line number Diff line number Diff line change
@@ -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
);

2 changes: 1 addition & 1 deletion library/core/src/char/convert.rs
Original file line number Diff line number Diff line change
@@ -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)
6 changes: 6 additions & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
@@ -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,
2 changes: 2 additions & 0 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
@@ -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()
5 changes: 5 additions & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
@@ -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,
3 changes: 2 additions & 1 deletion library/core/src/ops/index_range.rs
Original file line number Diff line number Diff line change
@@ -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 }
3 changes: 2 additions & 1 deletion library/core/src/ptr/alignment.rs
Original file line number Diff line number Diff line change
@@ -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()
);

12 changes: 8 additions & 4 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
@@ -424,7 +424,8 @@ impl<T: PointeeSized> *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<T: PointeeSized> *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<T: PointeeSized> *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<T: PointeeSized> *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,
27 changes: 18 additions & 9 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
@@ -522,7 +522,8 @@ pub const unsafe fn copy_nonoverlapping<T>(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<T>(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<T>(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::<T>(),
@@ -1384,7 +1387,8 @@ pub const unsafe fn swap_nonoverlapping<T>(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<T>(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::<T>(),
@@ -1722,7 +1727,8 @@ pub const unsafe fn read<T>(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::<T>(),
@@ -1922,7 +1928,8 @@ pub const unsafe fn write<T>(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::<T>(),
@@ -2090,7 +2097,8 @@ pub unsafe fn read_volatile<T>(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::<T>(),
@@ -2170,7 +2178,8 @@ pub unsafe fn write_volatile<T>(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::<T>(),
9 changes: 6 additions & 3 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
@@ -422,7 +422,8 @@ impl<T: PointeeSized> *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<T: PointeeSized> *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<T: PointeeSized> *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,
2 changes: 1 addition & 1 deletion library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
@@ -228,7 +228,7 @@ impl<T: PointeeSized> NonNull<T> {
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 _ }
22 changes: 14 additions & 8 deletions library/core/src/slice/index.rs
Original file line number Diff line number Diff line change
@@ -236,8 +236,9 @@ unsafe impl<T> 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<T> 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<T> 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<T> 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<T> SliceIndex<[T]> for ops::Range<usize> {
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<T> SliceIndex<[T]> for ops::Range<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 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,
15 changes: 10 additions & 5 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -942,7 +942,8 @@ impl<T> [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> [T] {
pub const unsafe fn as_chunks_unchecked<const N: usize>(&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> [T] {
pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&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> [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> [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,
);

6 changes: 4 additions & 2 deletions library/core/src/slice/raw.rs
Original file line number Diff line number Diff line change
@@ -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::<T>(),
@@ -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::<T>(),
12 changes: 8 additions & 4 deletions library/core/src/str/traits.rs
Original file line number Diff line number Diff line change
@@ -198,7 +198,8 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
// `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<str> for ops::Range<usize> {

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<str> for range::Range<usize> {
// `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<str> for range::Range<usize> {

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,
16 changes: 10 additions & 6 deletions library/core/src/ub_checks.rs
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/alignment.rs
Original file line number Diff line number Diff line change
@@ -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)]

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/ascii-char-digit_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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)]

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/assert_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/char-from_u32_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/copy-nonoverlapping.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/copy.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/layout.rs
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/nonnull.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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)]

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/nonzero-new_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/read.rs
Original file line number Diff line number Diff line change
@@ -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)

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/read_volatile.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/replace.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/slice-from-raw-parts.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/slice-get_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/slice-get_unchecked_mut.rs
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/str-get_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/str-get_unchecked_mut.rs
Original file line number Diff line number Diff line change
@@ -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() {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/swap-nonoverlapping.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/unchecked_add.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/unchecked_mul.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/unchecked_shl.rs
Original file line number Diff line number Diff line change
@@ -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)]

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/unchecked_shr.rs
Original file line number Diff line number Diff line change
@@ -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)]

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/unchecked_sub.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/unreachable_unchecked.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/write.rs
Original file line number Diff line number Diff line change
@@ -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)

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/write_bytes.rs
Original file line number Diff line number Diff line change
@@ -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)

2 changes: 1 addition & 1 deletion tests/ui/precondition-checks/write_volatile.rs
Original file line number Diff line number Diff line change
@@ -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)]