From 25d6e48164bc75b08b5798a60d157ceafe199f59 Mon Sep 17 00:00:00 2001 From: Link Mauve Date: Wed, 4 Feb 2026 04:48:08 +0100 Subject: [PATCH] XXX: Unimplement core::fmt on u64, u128 and Duration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is required to make libcore link in the kernel on PowerPC, but is obviously a terrible terrible solution… --- src/fmt/num.rs | 102 ++++++--------------------------- src/time.rs | 153 +------------------------------------------------ 2 files changed, 19 insertions(+), 236 deletions(-) diff --git a/src/fmt/num.rs b/src/fmt/num.rs index 253a7b7..d356009 100644 --- a/src/fmt/num.rs +++ b/src/fmt/num.rs @@ -586,6 +586,20 @@ macro_rules! impl_Exp { }; } +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for i64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + unimplemented!("No i64::fmt()!!!"); + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for u64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + unimplemented!("No u64::fmt()!!!"); + } +} + impl_Debug! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize @@ -604,12 +618,12 @@ mod imp { mod imp { use super::*; impl_Display!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into display_u32); - impl_Display!(i64, u64; as u64 into display_u64); + //impl_Display!(i64, u64; as u64 into display_u64); impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize; as u32 into exp_u32); - impl_Exp!(i64, u64; as u64 into exp_u64); + //impl_Exp!(i64, u64; as u64 into exp_u64); } -impl_Exp!(i128, u128; as u128 into exp_u128); +//impl_Exp!(i128, u128; as u128 into exp_u128); const U128_MAX_DEC_N: usize = u128::MAX.ilog10() as usize + 1; @@ -653,87 +667,7 @@ impl u128 { } unsafe fn _fmt_inner(self, buf: &mut [MaybeUninit]) -> usize { - // Optimize common-case zero, which would also need special treatment due to - // its "leading" zero. - if self == 0 { - let offset = buf.len() - 1; - buf[offset].write(b'0'); - return offset; - } - // Take the 16 least-significant decimals. - let (quot_1e16, mod_1e16) = div_rem_1e16(self); - let (mut remain, mut offset) = if quot_1e16 == 0 { - (mod_1e16, U128_MAX_DEC_N) - } else { - // Write digits at buf[23..39]. - enc_16lsd::<{ U128_MAX_DEC_N - 16 }>(buf, mod_1e16); - - // Take another 16 decimals. - let (quot2, mod2) = div_rem_1e16(quot_1e16); - if quot2 == 0 { - (mod2, U128_MAX_DEC_N - 16) - } else { - // Write digits at buf[7..23]. - enc_16lsd::<{ U128_MAX_DEC_N - 32 }>(buf, mod2); - // Quot2 has at most 7 decimals remaining after two 1e16 divisions. - (quot2 as u64, U128_MAX_DEC_N - 32) - } - }; - - // Format per four digits from the lookup table. - while remain > 999 { - // SAFETY: All of the decimals fit in buf due to U128_MAX_DEC_N - // and the while condition ensures at least 4 more decimals. - unsafe { core::hint::assert_unchecked(offset >= 4) } - // SAFETY: The offset counts down from its initial buf.len() - // without underflow due to the previous precondition. - unsafe { core::hint::assert_unchecked(offset <= buf.len()) } - offset -= 4; - - // pull two pairs - let quad = remain % 1_00_00; - remain /= 1_00_00; - let pair1 = (quad / 100) as usize; - let pair2 = (quad % 100) as usize; - buf[offset + 0].write(DECIMAL_PAIRS[pair1 * 2 + 0]); - buf[offset + 1].write(DECIMAL_PAIRS[pair1 * 2 + 1]); - buf[offset + 2].write(DECIMAL_PAIRS[pair2 * 2 + 0]); - buf[offset + 3].write(DECIMAL_PAIRS[pair2 * 2 + 1]); - } - - // Format per two digits from the lookup table. - if remain > 9 { - // SAFETY: All of the decimals fit in buf due to U128_MAX_DEC_N - // and the if condition ensures at least 2 more decimals. - unsafe { core::hint::assert_unchecked(offset >= 2) } - // SAFETY: The offset counts down from its initial buf.len() - // without underflow due to the previous precondition. - unsafe { core::hint::assert_unchecked(offset <= buf.len()) } - offset -= 2; - - let pair = (remain % 100) as usize; - remain /= 100; - buf[offset + 0].write(DECIMAL_PAIRS[pair * 2 + 0]); - buf[offset + 1].write(DECIMAL_PAIRS[pair * 2 + 1]); - } - - // Format the last remaining digit, if any. - if remain != 0 { - // SAFETY: All of the decimals fit in buf due to U128_MAX_DEC_N - // and the if condition ensures (at least) 1 more decimals. - unsafe { core::hint::assert_unchecked(offset >= 1) } - // SAFETY: The offset counts down from its initial buf.len() - // without underflow due to the previous precondition. - unsafe { core::hint::assert_unchecked(offset <= buf.len()) } - offset -= 1; - - // Either the compiler sees that remain < 10, or it prevents - // a boundary check up next. - let last = (remain & 15) as usize; - buf[offset].write(DECIMAL_PAIRS[last * 2 + 1]); - // not used: remain = 0; - } - offset + unimplemented!("No u128::_fmt_inner()!!!"); } /// Allows users to write an integer (in signed decimal format) into a variable `buf` of diff --git a/src/time.rs b/src/time.rs index b4efc09..86277de 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1330,158 +1330,7 @@ impl fmt::Debug for Duration { prefix: &str, postfix: &str, ) -> fmt::Result { - // Encode the fractional part into a temporary buffer. The buffer - // only need to hold 9 elements, because `fractional_part` has to - // be smaller than 10^9. The buffer is prefilled with '0' digits - // to simplify the code below. - let mut buf = [b'0'; 9]; - - // The next digit is written at this position - let mut pos = 0; - - // We keep writing digits into the buffer while there are non-zero - // digits left and we haven't written enough digits yet. - while fractional_part > 0 && pos < f.precision().unwrap_or(9) { - // Write new digit into the buffer - buf[pos] = b'0' + (fractional_part / divisor) as u8; - - fractional_part %= divisor; - divisor /= 10; - pos += 1; - } - - // If a precision < 9 was specified, there may be some non-zero - // digits left that weren't written into the buffer. In that case we - // need to perform rounding to match the semantics of printing - // normal floating point numbers. However, we only need to do work - // when rounding up. This happens if the first digit of the - // remaining ones is >= 5. When the first digit is exactly 5, rounding - // follows IEEE-754 round-ties-to-even semantics: we only round up - // if the last written digit is odd. - let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 { - // For ties (fractional_part == divisor * 5), only round up if last digit is odd - let is_tie = fractional_part == divisor * 5; - let last_digit_is_odd = if pos > 0 { - (buf[pos - 1] - b'0') % 2 == 1 - } else { - // No fractional digits - check the integer part - (integer_part % 2) == 1 - }; - - if is_tie && !last_digit_is_odd { - Some(integer_part) - } else { - // Round up the number contained in the buffer. We go through - // the buffer backwards and keep track of the carry. - let mut rev_pos = pos; - let mut carry = true; - while carry && rev_pos > 0 { - rev_pos -= 1; - - // If the digit in the buffer is not '9', we just need to - // increment it and can stop then (since we don't have a - // carry anymore). Otherwise, we set it to '0' (overflow) - // and continue. - if buf[rev_pos] < b'9' { - buf[rev_pos] += 1; - carry = false; - } else { - buf[rev_pos] = b'0'; - } - } - - // If we still have the carry bit set, that means that we set - // the whole buffer to '0's and need to increment the integer - // part. - if carry { - // If `integer_part == u64::MAX` and precision < 9, any - // carry of the overflow during rounding of the - // `fractional_part` into the `integer_part` will cause the - // `integer_part` itself to overflow. Avoid this by using an - // `Option`, with `None` representing `u64::MAX + 1`. - integer_part.checked_add(1) - } else { - Some(integer_part) - } - } - } else { - Some(integer_part) - }; - - // Determine the end of the buffer: if precision is set, we just - // use as many digits from the buffer (capped to 9). If it isn't - // set, we only use all digits up to the last non-zero one. - let end = f.precision().map(|p| crate::cmp::min(p, 9)).unwrap_or(pos); - - // This closure emits the formatted duration without emitting any - // padding (padding is calculated below). - let emit_without_padding = |f: &mut fmt::Formatter<'_>| { - if let Some(integer_part) = integer_part { - write!(f, "{}{}", prefix, integer_part)?; - } else { - // u64::MAX + 1 == 18446744073709551616 - write!(f, "{}18446744073709551616", prefix)?; - } - - // Write the decimal point and the fractional part (if any). - if end > 0 { - // SAFETY: We are only writing ASCII digits into the buffer and - // it was initialized with '0's, so it contains valid UTF8. - let s = unsafe { crate::str::from_utf8_unchecked(&buf[..end]) }; - - // If the user request a precision > 9, we pad '0's at the end. - let w = f.precision().unwrap_or(pos); - write!(f, ".{:0 { - // No `width` specified. There's no need to calculate the - // length of the output in this case, just emit it. - emit_without_padding(f) - } - Some(requested_w) => { - // A `width` was specified. Calculate the actual width of - // the output in order to calculate the required padding. - // It consists of 4 parts: - // 1. The prefix: is either "+" or "", so we can just use len(). - // 2. The postfix: can be "µs" so we have to count UTF8 characters. - let mut actual_w = prefix.len() + postfix.chars().count(); - // 3. The integer part: - if let Some(integer_part) = integer_part { - if let Some(log) = integer_part.checked_ilog10() { - // integer_part is > 0, so has length log10(x)+1 - actual_w += 1 + log as usize; - } else { - // integer_part is 0, so has length 1. - actual_w += 1; - } - } else { - // integer_part is u64::MAX + 1, so has length 20 - actual_w += 20; - } - // 4. The fractional part (if any): - if end > 0 { - let frac_part_w = f.precision().unwrap_or(pos); - actual_w += 1 + frac_part_w; - } - - if requested_w <= actual_w { - // Output is already longer than `width`, so don't pad. - emit_without_padding(f) - } else { - // We need to add padding. Use the `Formatter::padding` helper function. - let default_align = fmt::Alignment::Left; - let post_padding = - f.padding((requested_w - actual_w) as u16, default_align)?; - emit_without_padding(f)?; - post_padding.write(f) - } - } - } + unimplemented!("No Duration::fmt_decimal()!!!"); } // Print leading '+' sign if requested -- 2.52.0