@@ -234,70 +234,76 @@ macro_rules! impl_Display {
234
234
#[ cfg( not( feature = "optimize_for_size" ) ) ]
235
235
impl $unsigned {
236
236
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.
239
237
const MAX_DEC_N : usize = $unsigned:: MAX . ilog( 10 ) as usize + 1 ;
238
+ // Buffer decimals for $unsigned with right alignment.
240
239
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 .
242
241
let mut offset = buf. len( ) ;
243
- // Consume decimals from working copy until none left .
242
+ // Consume the least-significant decimals from a working copy.
244
243
let mut remain = self ;
245
244
246
245
// Format per four digits from the lookup table.
247
246
// Four digits need a 16-bit $unsigned or wider.
248
247
#[ allow( overflowing_literals) ]
249
248
#[ 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.
253
254
unsafe { core:: hint:: assert_unchecked( offset <= buf. len( ) ) }
254
255
offset -= 4 ;
255
256
256
257
let quad = remain % 100_00 ;
257
258
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 ] ) ;
264
265
}
265
266
266
267
// 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.
270
273
unsafe { core:: hint:: assert_unchecked( offset <= buf. len( ) ) }
271
274
offset -= 2 ;
272
275
273
- let i = ( remain % 100 ) as usize ;
276
+ let pair = ( remain % 100 ) as usize ;
274
277
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 ] ) ;
277
280
}
278
281
279
282
// 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.
283
288
unsafe { core:: hint:: assert_unchecked( offset <= buf. len( ) ) }
284
289
offset -= 1 ;
285
290
286
291
// Either the compiler sees that remain < 10, or it prevents
287
292
// 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 ] ) ;
289
295
// not used: remain = 0;
290
- buf[ offset] . write( DEC_DIGITS_LUT [ i * 2 + 1 ] ) ;
291
296
}
292
297
298
+ // SAFETY: Offset has been used as a write index.
299
+ unsafe { core:: hint:: assert_unchecked( offset < buf. len( ) ) }
300
+ let written = & buf[ offset..] ;
293
301
// SAFETY: All buf content since offset is set with bytes form
294
302
// 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 {
297
304
let as_init = MaybeUninit :: slice_assume_init_ref( written) ;
298
305
str :: from_utf8_unchecked( as_init)
299
- } ;
300
- f. pad_integral( is_nonnegative, "" , decimals)
306
+ } )
301
307
}
302
308
} ) *
303
309
0 commit comments