Skip to content

Commit fbea472

Browse files
Auto merge of #134938 - saethlin:include-precondition-args, r=<try>
Include arguments to the precondition check in failure messages
2 parents 8927649 + 103ca9c commit fbea472

Some content is hidden

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

57 files changed

+291
-92
lines changed

library/core/src/alloc/layout.rs

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

library/core/src/ascii/ascii_char.rs

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

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
@@ -1260,8 +1260,9 @@ impl char {
12601260
pub const unsafe fn as_ascii_unchecked(&self) -> ascii::Char {
12611261
assert_unsafe_precondition!(
12621262
check_library_ub,
1263-
"as_ascii_unchecked requires that the char is valid ASCII",
1264-
(it: &char = self) => it.is_ascii()
1263+
"as_ascii_unchecked requires that the char is valid ASCII \
1264+
(self:{it})",
1265+
(it: char = *self) => it.is_ascii()
12651266
);
12661267

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

library/core/src/displaywrapper.rs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
use core::fmt::{Display, Formatter, Result};
2+
3+
#[allow(missing_debug_implementations)]
4+
pub struct DisplayWrapper<T>(pub T);
5+
6+
macro_rules! display_int {
7+
($ty:ty) => {
8+
impl Display for DisplayWrapper<$ty> {
9+
#[inline]
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+
#[inline]
31+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
32+
display_int(self.0 as u128, false, f)
33+
}
34+
}
35+
};
36+
}
37+
38+
display_uint!(u8);
39+
display_uint!(u16);
40+
display_uint!(u32);
41+
display_uint!(u64);
42+
display_uint!(u128);
43+
display_uint!(usize);
44+
45+
impl Display for DisplayWrapper<*const ()> {
46+
#[inline]
47+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
48+
format_ptr(self.0.addr(), f)
49+
}
50+
}
51+
impl Display for DisplayWrapper<*mut ()> {
52+
#[inline]
53+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
54+
format_ptr(self.0.addr(), f)
55+
}
56+
}
57+
58+
#[inline]
59+
fn format_ptr(addr: usize, f: &mut Formatter<'_>) -> Result {
60+
const HEX: [u8; 16] = *b"0123456789abcdef";
61+
let mut buf = [0u8; 42];
62+
let mut cur = buf.len();
63+
64+
let mut n = addr;
65+
while n >= 16 {
66+
let d = n % 16;
67+
n /= 16;
68+
cur -= 1;
69+
buf[cur] = HEX[d];
70+
}
71+
cur -= 1;
72+
buf[cur] = HEX[n];
73+
74+
cur -= 1;
75+
buf[cur] = b'x';
76+
cur -= 1;
77+
buf[cur] = b'0';
78+
79+
// SAFETY: The buffer is initially ASCII and we only write ASCII bytes to it.
80+
let s = unsafe { core::str::from_utf8_unchecked(&buf[cur..]) };
81+
f.write_str(s)
82+
}
83+
84+
impl Display for DisplayWrapper<char> {
85+
#[inline]
86+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
87+
let mut buf = [0u8; 4];
88+
let s = self.0.encode_utf8(&mut buf);
89+
f.write_str(s)
90+
}
91+
}
92+
93+
impl Display for DisplayWrapper<bool> {
94+
#[inline]
95+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
96+
let s = match self.0 {
97+
true => "true",
98+
false => "false",
99+
};
100+
f.write_str(s)
101+
}
102+
}
103+
104+
#[inline]
105+
fn display_int(mut n: u128, is_negative: bool, f: &mut Formatter<'_>) -> Result {
106+
let mut buf = [0u8; 42];
107+
let mut cur = buf.len();
108+
109+
while n >= 10 {
110+
let d = n % 10;
111+
n /= 10;
112+
cur -= 1;
113+
buf[cur] = (d as u8) + b'0';
114+
}
115+
cur -= 1;
116+
buf[cur] = (n as u8) + b'0';
117+
if is_negative {
118+
cur -= 1;
119+
buf[cur] = b'-';
120+
}
121+
// SAFETY: The buffer is initially ASCII and we only write ASCII bytes to it.
122+
let s = unsafe { core::str::from_utf8_unchecked(&buf[cur..]) };
123+
f.write_str(s)
124+
}

library/core/src/fmt/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,7 @@ impl<'a> Formatter<'a> {
18831883
/// assert_eq!(format!("{Foo:0>8}"), "Foo");
18841884
/// ```
18851885
#[stable(feature = "rust1", since = "1.0.0")]
1886+
#[inline]
18861887
pub fn write_str(&mut self, data: &str) -> Result {
18871888
self.buf.write_str(data)
18881889
}

library/core/src/intrinsics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2388,7 +2388,7 @@ where
23882388
/// marked as `#[inline]`.
23892389
///
23902390
/// See [`const_eval_select()`] for the rules and requirements around that intrinsic.
2391-
pub(crate) macro const_eval_select {
2391+
pub macro const_eval_select {
23922392
(
23932393
@capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? :
23942394
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/num/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ impl u8 {
509509
assert_unsafe_precondition!(
510510
check_library_ub,
511511
"as_ascii_unchecked requires that the byte is valid ASCII",
512-
(it: &u8 = self) => it.is_ascii()
512+
(it: u8 = *self) => it.is_ascii()
513513
);
514514

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

library/core/src/ops/index_range.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ impl IndexRange {
2323
pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
2424
ub_checks::assert_unsafe_precondition!(
2525
check_library_ub,
26-
"IndexRange::new_unchecked requires `start <= end`",
26+
"IndexRange::new_unchecked requires `start <= end` \
27+
(start:{start}, end:{end})",
2728
(start: usize = start, end: usize = end) => start <= end,
2829
);
2930
IndexRange { start, end }

0 commit comments

Comments
 (0)