@@ -234,70 +234,76 @@ macro_rules! impl_Display {
234234 #[ cfg( not( feature = "optimize_for_size" ) ) ]
235235 impl $unsigned {
236236 fn _fmt( self , is_nonnegative: bool , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
237- // Buffer decimals for $unsigned type with fixed positions. Thus
238- // the least significant digit is located at the last buf byte.
239237 const MAX_DEC_N : usize = $unsigned:: MAX . ilog( 10 ) as usize + 1 ;
238+ // Buffer decimals for $unsigned with right alignment.
240239 let mut buf = [ MaybeUninit :: <u8 >:: uninit( ) ; MAX_DEC_N ] ;
241- // Leading zero count & write index in buf.
240+ // Count the number of bytes in buf that are not initialized .
242241 let mut offset = buf. len( ) ;
243- // Consume decimals from working copy until none left .
242+ // Consume the least-significant decimals from a working copy.
244243 let mut remain = self ;
245244
246245 // Format per four digits from the lookup table.
247246 // Four digits need a 16-bit $unsigned or wider.
248247 #[ allow( overflowing_literals) ]
249248 #[ allow( unused_comparisons) ]
250- while offset >= 4 && remain > 999 {
251- // SAFETY: Offset from the initial buf.len() gets deducted
252- // with underflow checks exclusively.
249+ while remain > 999 {
250+ // SAFETY: All of the decimals fit in buf due to MAX_DEC_N.
251+ unsafe { core:: hint:: assert_unchecked( offset >= 4 ) }
252+ // SAFETY: The offset counts down from its initial buf.len()
253+ // without underflow due to the previous assertion.
253254 unsafe { core:: hint:: assert_unchecked( offset <= buf. len( ) ) }
254255 offset -= 4 ;
255256
256257 let quad = remain % 100_00 ;
257258 remain /= 100_00 ;
258- let i1 = ( quad / 100 ) as usize ;
259- let i2 = ( quad % 100 ) as usize ;
260- buf[ offset + 0 ] . write( DEC_DIGITS_LUT [ i1 * 2 + 0 ] ) ;
261- buf[ offset + 1 ] . write( DEC_DIGITS_LUT [ i1 * 2 + 1 ] ) ;
262- buf[ offset + 2 ] . write( DEC_DIGITS_LUT [ i2 * 2 + 0 ] ) ;
263- buf[ offset + 3 ] . write( DEC_DIGITS_LUT [ i2 * 2 + 1 ] ) ;
259+ let pair1 = ( quad / 100 ) as usize ;
260+ let pair2 = ( quad % 100 ) as usize ;
261+ buf[ offset + 0 ] . write( DEC_DIGITS_LUT [ pair1 * 2 + 0 ] ) ;
262+ buf[ offset + 1 ] . write( DEC_DIGITS_LUT [ pair1 * 2 + 1 ] ) ;
263+ buf[ offset + 2 ] . write( DEC_DIGITS_LUT [ pair2 * 2 + 0 ] ) ;
264+ buf[ offset + 3 ] . write( DEC_DIGITS_LUT [ pair2 * 2 + 1 ] ) ;
264265 }
265266
266267 // Format per two digits from the lookup table.
267- if offset >= 2 && remain > 9 {
268- // SAFETY: Offset from the initial buf.len() gets deducted
269- // with underflow checks exclusively.
268+ if remain > 9 {
269+ // SAFETY: All of the decimals fit in buf due to MAX_DEC_N.
270+ unsafe { core:: hint:: assert_unchecked( offset >= 2 ) }
271+ // SAFETY: The offset counts down from its initial buf.len()
272+ // without underflow due to the previous assertion.
270273 unsafe { core:: hint:: assert_unchecked( offset <= buf. len( ) ) }
271274 offset -= 2 ;
272275
273- let i = ( remain % 100 ) as usize ;
276+ let pair = ( remain % 100 ) as usize ;
274277 remain /= 100 ;
275- buf[ offset + 0 ] . write( DEC_DIGITS_LUT [ i * 2 + 0 ] ) ;
276- buf[ offset + 1 ] . write( DEC_DIGITS_LUT [ i * 2 + 1 ] ) ;
278+ buf[ offset + 0 ] . write( DEC_DIGITS_LUT [ pair * 2 + 0 ] ) ;
279+ buf[ offset + 1 ] . write( DEC_DIGITS_LUT [ pair * 2 + 1 ] ) ;
277280 }
278281
279282 // Format the last remaining digit, if any.
280- if offset != 0 && remain != 0 || self == 0 {
281- // SAFETY: Offset from the initial buf.len() gets deducted
282- // with underflow checks exclusively.
283+ if remain != 0 || self == 0 {
284+ // SAFETY: All of the decimals fit in buf due to MAX_DEC_N.
285+ unsafe { core:: hint:: assert_unchecked( offset >= 1 ) }
286+ // SAFETY: The offset counts down from its initial buf.len()
287+ // without underflow due to the previous assertion.
283288 unsafe { core:: hint:: assert_unchecked( offset <= buf. len( ) ) }
284289 offset -= 1 ;
285290
286291 // Either the compiler sees that remain < 10, or it prevents
287292 // a boundary check up next.
288- let i = ( remain & 15 ) as usize ;
293+ let last = ( remain & 15 ) as usize ;
294+ buf[ offset] . write( DEC_DIGITS_LUT [ last * 2 + 1 ] ) ;
289295 // not used: remain = 0;
290- buf[ offset] . write( DEC_DIGITS_LUT [ i * 2 + 1 ] ) ;
291296 }
292297
298+ // SAFETY: Offset has been used as a write index.
299+ unsafe { core:: hint:: assert_unchecked( offset < buf. len( ) ) }
300+ let written = & buf[ offset..] ;
293301 // SAFETY: All buf content since offset is set with bytes form
294302 // the lookup table, which consists of valid ASCII exclusively.
295- let decimals = unsafe {
296- let written = & buf[ offset..] ;
303+ f. pad_integral( is_nonnegative, "" , unsafe {
297304 let as_init = MaybeUninit :: slice_assume_init_ref( written) ;
298305 str :: from_utf8_unchecked( as_init)
299- } ;
300- f. pad_integral( is_nonnegative, "" , decimals)
306+ } )
301307 }
302308 } ) *
303309
0 commit comments