Skip to content

Commit 103ca9c

Browse files
committed
Change to a generics-based impl
1 parent ae8af35 commit 103ca9c

File tree

3 files changed

+105
-150
lines changed

3 files changed

+105
-150
lines changed

library/core/src/displaywrapper.rs

Lines changed: 100 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,124 @@
11
use core::fmt::{Display, Formatter, Result};
22

33
#[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-
}
4+
pub struct DisplayWrapper<T>(pub T);
135

14-
impl From<bool> for DisplayWrapper<'_> {
15-
fn from(b: bool) -> Self {
16-
Self::Bool(b)
17-
}
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+
};
1818
}
1919

20-
impl<'a> From<&'a str> for DisplayWrapper<'a> {
21-
fn from(s: &'a str) -> Self {
22-
Self::Str(s)
23-
}
24-
}
20+
display_int!(i8);
21+
display_int!(i16);
22+
display_int!(i32);
23+
display_int!(i64);
24+
display_int!(i128);
25+
display_int!(isize);
2526

26-
impl From<char> for DisplayWrapper<'_> {
27-
fn from(c: char) -> Self {
28-
Self::Char(c)
29-
}
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+
};
3036
}
3137

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-
}
38+
display_uint!(u8);
39+
display_uint!(u16);
40+
display_uint!(u32);
41+
display_uint!(u64);
42+
display_uint!(u128);
43+
display_uint!(usize);
4244

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)
45+
impl Display for DisplayWrapper<*const ()> {
46+
#[inline]
47+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
48+
format_ptr(self.0.addr(), f)
6649
}
6750
}
68-
impl From<usize> for DisplayWrapper<'_> {
69-
fn from(c: usize) -> Self {
70-
Self::Uint(c as u128)
51+
impl Display for DisplayWrapper<*mut ()> {
52+
#[inline]
53+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
54+
format_ptr(self.0.addr(), f)
7155
}
7256
}
7357

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-
}
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)
9882
}
99-
impl From<isize> for DisplayWrapper<'_> {
100-
fn from(c: isize) -> Self {
101-
Self::Int(c as i128)
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)
10290
}
10391
}
10492

105-
#[unstable(feature = "ub_checks", issue = "none")]
106-
impl Display for DisplayWrapper<'_> {
93+
impl Display for DisplayWrapper<bool> {
10794
#[inline]
10895
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..]) };
96+
let s = match self.0 {
97+
true => "true",
98+
false => "false",
99+
};
166100
f.write_str(s)
167101
}
168102
}
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/ub_checks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ macro_rules! assert_unsafe_precondition {
7474
::core::panicking::panic_nounwind($message);
7575
} else #[allow(unused)] {
7676
$(
77-
let $name = ::core::displaywrapper::DisplayWrapper::from($name);
77+
let $name = ::core::displaywrapper::DisplayWrapper($name);
7878
)*
7979
::core::panicking::panic_nounwind_fmt(format_args!($message), false);
8080
}

tests/codegen-units/item-collection/opaque-return-impls.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,10 @@ pub fn foo3() -> Box<dyn Iterator<Item = usize>> {
8787
//~ MONO_ITEM fn std::boxed::Box::<Counter>::new
8888
//~ MONO_ITEM fn Counter::new
8989
//~ MONO_ITEM fn core::fmt::rt::<impl std::fmt::Arguments<'_>>::new_const::<1>
90-
//~ MONO_ITEM fn <core::displaywrapper::DisplayWrapper<'_> as std::fmt::Display>::fmt
9190
//~ MONO_ITEM fn <std::ops::Range<usize> as std::slice::SliceIndex<[T]>>::get_unchecked::precondition_check
9291
//~ MONO_ITEM fn <std::ops::Range<usize> as std::slice::SliceIndex<[T]>>::get_unchecked::precondition_check::runtime
9392
//~ MONO_ITEM fn <std::ops::RangeFrom<usize> as std::slice::SliceIndex<[u8]>>::index
94-
//~ MONO_ITEM fn std::char::encode_utf8_raw
95-
//~ MONO_ITEM fn std::char::encode_utf8_raw_unchecked
96-
//~ MONO_ITEM fn std::slice::from_raw_parts_mut::precondition_check
97-
//~ MONO_ITEM fn std::slice::from_raw_parts_mut::precondition_check::runtime
93+
//~ MONO_ITEM fn <core::displaywrapper::DisplayWrapper<*mut ()> as std::fmt::Display>::fmt
94+
//~ MONO_ITEM fn <core::displaywrapper::DisplayWrapper<usize> as std::fmt::Display>::fmt
95+
//~ MONO_ITEM fn core::displaywrapper::display_int
96+
//~ MONO_ITEM fn core::displaywrapper::format_ptr

0 commit comments

Comments
 (0)