Skip to content

Commit 627939d

Browse files
Auto merge of #134938 - saethlin:include-precondition-args, r=<try>
Include arguments to the precondition check in failure messages
2 parents 3be6803 + ae8af35 commit 627939d

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

+336
-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: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
use core::fmt::{Display, Formatter, Result};
2+
3+
#[allow(missing_debug_implementations)]
4+
#[unstable(feature = "ub_checks", issue = "none")]
5+
pub enum DisplayWrapper<'a> {
6+
Bool(bool),
7+
Char(char),
8+
Str(&'a str),
9+
Ptr(*const ()),
10+
Uint(u128),
11+
Int(i128),
12+
}
13+
14+
impl From<bool> for DisplayWrapper<'_> {
15+
fn from(b: bool) -> Self {
16+
Self::Bool(b)
17+
}
18+
}
19+
20+
impl<'a> From<&'a str> for DisplayWrapper<'a> {
21+
fn from(s: &'a str) -> Self {
22+
Self::Str(s)
23+
}
24+
}
25+
26+
impl From<char> for DisplayWrapper<'_> {
27+
fn from(c: char) -> Self {
28+
Self::Char(c)
29+
}
30+
}
31+
32+
impl From<*const ()> for DisplayWrapper<'_> {
33+
fn from(c: *const ()) -> Self {
34+
Self::Ptr(c)
35+
}
36+
}
37+
impl From<*mut ()> for DisplayWrapper<'_> {
38+
fn from(c: *mut ()) -> Self {
39+
Self::Ptr(c as *const ())
40+
}
41+
}
42+
43+
impl From<u8> for DisplayWrapper<'_> {
44+
fn from(c: u8) -> Self {
45+
Self::Uint(c as u128)
46+
}
47+
}
48+
impl From<u16> for DisplayWrapper<'_> {
49+
fn from(c: u16) -> Self {
50+
Self::Uint(c as u128)
51+
}
52+
}
53+
impl From<u32> for DisplayWrapper<'_> {
54+
fn from(c: u32) -> Self {
55+
Self::Uint(c as u128)
56+
}
57+
}
58+
impl From<u64> for DisplayWrapper<'_> {
59+
fn from(c: u64) -> Self {
60+
Self::Uint(c as u128)
61+
}
62+
}
63+
impl From<u128> for DisplayWrapper<'_> {
64+
fn from(c: u128) -> Self {
65+
Self::Uint(c as u128)
66+
}
67+
}
68+
impl From<usize> for DisplayWrapper<'_> {
69+
fn from(c: usize) -> Self {
70+
Self::Uint(c as u128)
71+
}
72+
}
73+
74+
impl From<i8> for DisplayWrapper<'_> {
75+
fn from(c: i8) -> Self {
76+
Self::Int(c as i128)
77+
}
78+
}
79+
impl From<i16> for DisplayWrapper<'_> {
80+
fn from(c: i16) -> Self {
81+
Self::Int(c as i128)
82+
}
83+
}
84+
impl From<i32> for DisplayWrapper<'_> {
85+
fn from(c: i32) -> Self {
86+
Self::Int(c as i128)
87+
}
88+
}
89+
impl From<i64> for DisplayWrapper<'_> {
90+
fn from(c: i64) -> Self {
91+
Self::Int(c as i128)
92+
}
93+
}
94+
impl From<i128> for DisplayWrapper<'_> {
95+
fn from(c: i128) -> Self {
96+
Self::Int(c as i128)
97+
}
98+
}
99+
impl From<isize> for DisplayWrapper<'_> {
100+
fn from(c: isize) -> Self {
101+
Self::Int(c as i128)
102+
}
103+
}
104+
105+
#[unstable(feature = "ub_checks", issue = "none")]
106+
impl Display for DisplayWrapper<'_> {
107+
#[inline]
108+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
109+
const HEX: [u8; 16] = *b"0123456789abcdef";
110+
let mut buf = [0u8; 42];
111+
let mut cur = buf.len();
112+
113+
match *self {
114+
Self::Bool(_) | Self::Str(_) => panic!(),
115+
Self::Char(c) => {
116+
let mut buf = [0u8; 4];
117+
let s = c.encode_utf8(&mut buf);
118+
return f.write_str(s);
119+
}
120+
Self::Ptr(ptr) => {
121+
let mut n = ptr.addr();
122+
while n >= 16 {
123+
let d = n % 16;
124+
n /= 16;
125+
cur -= 1;
126+
buf[cur] = HEX[d];
127+
}
128+
cur -= 1;
129+
buf[cur] = HEX[n];
130+
131+
cur -= 1;
132+
buf[cur] = b'x';
133+
cur -= 1;
134+
buf[cur] = b'0';
135+
}
136+
Self::Uint(mut n) => {
137+
while n >= 10 {
138+
let d = n % 10;
139+
n /= 10;
140+
cur -= 1;
141+
buf[cur] = (d as u8) + b'0';
142+
}
143+
cur -= 1;
144+
buf[cur] = (n as u8) + b'0';
145+
}
146+
Self::Int(n) => {
147+
let is_negative = n < 0;
148+
let mut n = (!(n as u128)).wrapping_add(1);
149+
150+
while n >= 10 {
151+
let d = n % 10;
152+
n /= 10;
153+
cur -= 1;
154+
buf[cur] = (d as u8) + b'0';
155+
}
156+
cur -= 1;
157+
buf[cur] = (n as u8) + b'0';
158+
if is_negative {
159+
cur -= 1;
160+
buf[cur] = b'-';
161+
}
162+
}
163+
}
164+
// SAFETY: The buffer is initially ASCII and we only write ASCII bytes to it.
165+
let s = unsafe { core::str::from_utf8_unchecked(&buf[cur..]) };
166+
f.write_str(s)
167+
}
168+
}

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)