Skip to content

Commit c7fe794

Browse files
Auto merge of #134938 - saethlin:include-precondition-args, r=<try>
Include arguments to the precondition check in failure messages
2 parents 2300c2a + c678970 commit c7fe794

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

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

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)