Skip to content

Commit e159cd0

Browse files
committed
Auto merge of #134938 - saethlin:include-precondition-args, r=<try>
Include arguments to the precondition check in failure messages
2 parents 1a30ed9 + dcac2f6 commit e159cd0

56 files changed

Lines changed: 274 additions & 92 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

library/core/src/alloc/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl Layout {
133133
assert_unsafe_precondition!(
134134
check_library_ub,
135135
"Layout::from_size_align_unchecked requires that align is a power of 2 \
136-
and the rounded-up allocation size does not exceed isize::MAX",
136+
and the rounded-up allocation size does not exceed isize::MAX (size:{size}, align:{align})",
137137
(
138138
size: usize = size,
139139
align: usize = align,

library/core/src/ascii/ascii_char.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ impl AsciiChar {
521521
pub const unsafe fn digit_unchecked(d: u8) -> Self {
522522
assert_unsafe_precondition!(
523523
check_library_ub,
524-
"`ascii::Char::digit_unchecked` input cannot exceed 9.",
524+
"`ascii::Char::digit_unchecked` input cannot exceed 9. (d:{d})",
525525
(d: u8 = d) => d < 10
526526
);
527527

library/core/src/char/convert.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
2828
unsafe {
2929
assert_unsafe_precondition!(
3030
check_language_ub,
31-
"invalid value for `char`",
31+
"invalid value for `char` ({i})",
3232
(i: u32 = i) => char_try_from_u32(i).is_ok()
3333
);
3434
transmute(i)

library/core/src/char/methods.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,8 +1859,9 @@ impl char {
18591859
pub const unsafe fn as_ascii_unchecked(&self) -> ascii::Char {
18601860
assert_unsafe_precondition!(
18611861
check_library_ub,
1862-
"as_ascii_unchecked requires that the char is valid ASCII",
1863-
(it: &char = self) => it.is_ascii()
1862+
"as_ascii_unchecked requires that the char is valid ASCII \
1863+
(self:{it})",
1864+
(it: char = *self) => it.is_ascii()
18641865
);
18651866

18661867
// SAFETY: the caller promised that this char is ASCII.

library/core/src/displaywrapper.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use core::fmt::{Display, Formatter, Result};
2+
use core::num::NonZeroU128;
3+
4+
#[allow(missing_debug_implementations)]
5+
pub struct DisplayWrapper<T>(pub T);
6+
7+
macro_rules! display_int {
8+
($ty:ty) => {
9+
impl Display for DisplayWrapper<$ty> {
10+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
11+
let n = self.0;
12+
let is_negative = n < 0;
13+
let n = (!(n as u128)).wrapping_add(1);
14+
display_int(n, is_negative, f)
15+
}
16+
}
17+
};
18+
}
19+
20+
display_int!(i8);
21+
display_int!(i16);
22+
display_int!(i32);
23+
display_int!(i64);
24+
display_int!(i128);
25+
display_int!(isize);
26+
27+
macro_rules! display_uint {
28+
($ty:ty) => {
29+
impl Display for DisplayWrapper<$ty> {
30+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
31+
display_int(self.0 as u128, false, f)
32+
}
33+
}
34+
};
35+
}
36+
37+
display_uint!(u8);
38+
display_uint!(u16);
39+
display_uint!(u32);
40+
display_uint!(u64);
41+
display_uint!(u128);
42+
display_uint!(usize);
43+
44+
impl Display for DisplayWrapper<*const ()> {
45+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
46+
format_ptr(self.0.addr(), f)
47+
}
48+
}
49+
impl Display for DisplayWrapper<*mut ()> {
50+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
51+
format_ptr(self.0.addr(), f)
52+
}
53+
}
54+
55+
impl Display for DisplayWrapper<char> {
56+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
57+
let mut buf = [0u8; 4];
58+
let s = self.0.encode_utf8(&mut buf);
59+
f.write_str(s)
60+
}
61+
}
62+
63+
impl Display for DisplayWrapper<bool> {
64+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
65+
let s = match self.0 {
66+
true => "true",
67+
false => "false",
68+
};
69+
f.write_str(s)
70+
}
71+
}
72+
73+
const ALPHABET: &[u8; 16] = b"0123456789abcdef";
74+
75+
fn format_with_radix(mut n: u128, buf: &mut [u8], radix: NonZeroU128) -> usize {
76+
let mut cur = buf.len();
77+
while n >= radix.get() {
78+
let d = n % radix;
79+
n /= radix;
80+
cur = cur.wrapping_sub(1);
81+
buf[cur] = ALPHABET[d as usize];
82+
}
83+
cur = cur.wrapping_sub(1);
84+
buf[cur] = ALPHABET[n as usize];
85+
cur
86+
}
87+
88+
pub fn format_ptr(addr: usize, f: &mut Formatter<'_>) -> Result {
89+
let mut buf = [b'0'; 42];
90+
let mut cur =
91+
format_with_radix(addr as u128, &mut buf, const { NonZeroU128::new(16).unwrap() });
92+
93+
cur = cur.wrapping_sub(1);
94+
buf[cur] = b'x';
95+
cur = cur.wrapping_sub(1);
96+
97+
// SAFETY: The buffer is initially ASCII and we only write ASCII bytes to it.
98+
let s = unsafe { core::str::from_utf8_unchecked(&buf[cur..]) };
99+
f.write_str(s)
100+
}
101+
102+
pub fn display_int(n: u128, is_negative: bool, f: &mut Formatter<'_>) -> Result {
103+
let mut buf = [b'-'; 42];
104+
let mut cur = format_with_radix(n, &mut buf, const { NonZeroU128::new(10).unwrap() });
105+
if is_negative {
106+
cur = cur.wrapping_sub(1);
107+
}
108+
// SAFETY: The buffer is initially ASCII and we only write ASCII bytes to it.
109+
let s = unsafe { core::str::from_utf8_unchecked(&buf[cur..]) };
110+
f.write_str(s)
111+
}

library/core/src/fmt/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,7 @@ impl<'a> Formatter<'a> {
20962096
/// assert_eq!(format!("{Foo:0>8}"), "Foo");
20972097
/// ```
20982098
#[stable(feature = "rust1", since = "1.0.0")]
2099+
#[inline]
20992100
pub fn write_str(&mut self, data: &str) -> Result {
21002101
self.buf.write_str(data)
21012102
}

library/core/src/intrinsics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2424,7 +2424,7 @@ where
24242424
/// macro supports setting attributes for those functions. Both functions are marked as `#[inline]`.
24252425
///
24262426
/// See [`const_eval_select()`] for the rules and requirements around that intrinsic.
2427-
pub(crate) macro const_eval_select {
2427+
pub macro const_eval_select {
24282428
(
24292429
@capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? :
24302430
if const

library/core/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ pub mod alloc;
347347

348348
// note: does not need to be public
349349
mod bool;
350+
#[doc(hidden)]
351+
#[unstable(feature = "ub_checks", issue = "none")]
352+
pub mod displaywrapper;
350353
mod escape;
351354
mod tuple;
352355
mod unit;

library/core/src/mem/alignment.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ impl Alignment {
188188
pub const unsafe fn new_unchecked(align: usize) -> Self {
189189
assert_unsafe_precondition!(
190190
check_language_ub,
191-
"Alignment::new_unchecked requires a power of two",
191+
"Alignment::new_unchecked requires a power of two \
192+
(align:{align})",
192193
(align: usize = align) => align.is_power_of_two()
193194
);
194195

library/core/src/num/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ impl u8 {
651651
assert_unsafe_precondition!(
652652
check_library_ub,
653653
"as_ascii_unchecked requires that the byte is valid ASCII",
654-
(it: &u8 = self) => it.is_ascii()
654+
(it: u8 = *self) => it.is_ascii()
655655
);
656656

657657
// SAFETY: the caller promised that this byte is ASCII.

0 commit comments

Comments
 (0)