@@ -565,123 +565,134 @@ mod imp {
565565} 
566566impl_Exp ! ( i128 ,  u128  as  u128  via to_u128 named exp_u128) ; 
567567
568+ const  U128_MAX_DEC_N :  usize  = u128:: MAX . ilog ( 10 )  as  usize  + 1 ; 
569+ 
568570#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
569571impl  fmt:: Display  for  u128  { 
570572    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
571-         fmt_u128 ( * self ,  true ,  f) 
573+         let  mut  buf = [ MaybeUninit :: < u8 > :: uninit ( ) ;  U128_MAX_DEC_N ] ; 
574+ 
575+         f. pad_integral ( true ,  "" ,  self . _fmt ( & mut  buf) ) 
572576    } 
573577} 
574578
575579#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
576580impl  fmt:: Display  for  i128  { 
577581    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
578-         fmt_u128 ( self . unsigned_abs ( ) ,  * self  >= 0 ,  f) 
582+         // This is not a typo, we use the maximum number of digits of `u128`, hence why we use 
583+         // `U128_MAX_DEC_N`. 
584+         let  mut  buf = [ MaybeUninit :: < u8 > :: uninit ( ) ;  U128_MAX_DEC_N ] ; 
585+ 
586+         let  is_nonnegative = * self  >= 0 ; 
587+         f. pad_integral ( is_nonnegative,  "" ,  self . unsigned_abs ( ) . _fmt ( & mut  buf) ) 
579588    } 
580589} 
581590
582- /// Format optimized for u128. Computation of 128 bits is limited by proccessing 
583- /// in batches of 16 decimals at a time. 
584- fn  fmt_u128 ( n :  u128 ,  is_nonnegative :  bool ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
585-     // Optimize common-case zero, which would also need special treatment due to 
586-     // its "leading" zero. 
587-     if  n == 0  { 
588-         return  f. pad_integral ( true ,  "" ,  "0" ) ; 
589-     } 
591+ impl  u128  { 
592+     /// Format optimized for u128. Computation of 128 bits is limited by proccessing 
593+ /// in batches of 16 decimals at a time. 
594+ #[ doc( hidden) ]  
595+     #[ unstable(  
596+         feature = "fmt_internals" ,  
597+         reason = "specialized method meant to only be used by `SpecToString` implementation" ,  
598+         issue = "none"  
599+     ) ]  
600+     pub  fn  _fmt < ' a > ( self ,  buf :  & ' a  mut  [ MaybeUninit < u8 > ] )  -> & ' a  str  { 
601+         // Optimize common-case zero, which would also need special treatment due to 
602+         // its "leading" zero. 
603+         if  self  == 0  { 
604+             return  "0" ; 
605+         } 
590606
591-     // U128::MAX has 39 significant-decimals. 
592-     const  MAX_DEC_N :  usize  = u128:: MAX . ilog ( 10 )  as  usize  + 1 ; 
593-     // Buffer decimals with right alignment. 
594-     let  mut  buf = [ MaybeUninit :: < u8 > :: uninit ( ) ;  MAX_DEC_N ] ; 
595- 
596-     // Take the 16 least-significant decimals. 
597-     let  ( quot_1e16,  mod_1e16)  = div_rem_1e16 ( n) ; 
598-     let  ( mut  remain,  mut  offset)  = if  quot_1e16 == 0  { 
599-         ( mod_1e16,  MAX_DEC_N ) 
600-     }  else  { 
601-         // Write digits at buf[23..39]. 
602-         enc_16lsd :: < {  MAX_DEC_N  - 16  } > ( & mut  buf,  mod_1e16) ; 
603- 
604-         // Take another 16 decimals. 
605-         let  ( quot2,  mod2)  = div_rem_1e16 ( quot_1e16) ; 
606-         if  quot2 == 0  { 
607-             ( mod2,  MAX_DEC_N  - 16 ) 
607+         // Take the 16 least-significant decimals. 
608+         let  ( quot_1e16,  mod_1e16)  = div_rem_1e16 ( self ) ; 
609+         let  ( mut  remain,  mut  offset)  = if  quot_1e16 == 0  { 
610+             ( mod_1e16,  U128_MAX_DEC_N ) 
608611        }  else  { 
609-             // Write digits at buf[7..23]. 
610-             enc_16lsd :: < {  MAX_DEC_N  - 32  } > ( & mut  buf,  mod2) ; 
611-             // Quot2 has at most 7 decimals remaining after two 1e16 divisions. 
612-             ( quot2 as  u64 ,  MAX_DEC_N  - 32 ) 
613-         } 
614-     } ; 
612+             // Write digits at buf[23..39]. 
613+             enc_16lsd :: < {  U128_MAX_DEC_N  - 16  } > ( buf,  mod_1e16) ; 
615614
616-     // Format per four digits from the lookup table. 
617-     while  remain > 999  { 
618-         // SAFETY: All of the decimals fit in buf due to MAX_DEC_N 
619-         // and the while condition ensures at least 4 more decimals. 
620-         unsafe  {  core:: hint:: assert_unchecked ( offset >= 4 )  } 
621-         // SAFETY: The offset counts down from its initial buf.len() 
622-         // without underflow due to the previous precondition. 
623-         unsafe  {  core:: hint:: assert_unchecked ( offset <= buf. len ( ) )  } 
624-         offset -= 4 ; 
615+             // Take another 16 decimals. 
616+             let  ( quot2,  mod2)  = div_rem_1e16 ( quot_1e16) ; 
617+             if  quot2 == 0  { 
618+                 ( mod2,  U128_MAX_DEC_N  - 16 ) 
619+             }  else  { 
620+                 // Write digits at buf[7..23]. 
621+                 enc_16lsd :: < {  U128_MAX_DEC_N  - 32  } > ( buf,  mod2) ; 
622+                 // Quot2 has at most 7 decimals remaining after two 1e16 divisions. 
623+                 ( quot2 as  u64 ,  U128_MAX_DEC_N  - 32 ) 
624+             } 
625+         } ; 
625626
626-         // pull two pairs 
627-         let  quad = remain % 1_00_00 ; 
628-         remain /= 1_00_00 ; 
629-         let  pair1 = ( quad / 100 )  as  usize ; 
630-         let  pair2 = ( quad % 100 )  as  usize ; 
631-         buf[ offset + 0 ] . write ( DEC_DIGITS_LUT [ pair1 *  2  + 0 ] ) ; 
632-         buf[ offset + 1 ] . write ( DEC_DIGITS_LUT [ pair1 *  2  + 1 ] ) ; 
633-         buf[ offset + 2 ] . write ( DEC_DIGITS_LUT [ pair2 *  2  + 0 ] ) ; 
634-         buf[ offset + 3 ] . write ( DEC_DIGITS_LUT [ pair2 *  2  + 1 ] ) ; 
635-     } 
627+         // Format per four digits from the lookup table. 
628+         while  remain > 999  { 
629+             // SAFETY: All of the decimals fit in buf due to U128_MAX_DEC_N 
630+             // and the while condition ensures at least 4 more decimals. 
631+             unsafe  {  core:: hint:: assert_unchecked ( offset >= 4 )  } 
632+             // SAFETY: The offset counts down from its initial buf.len() 
633+             // without underflow due to the previous precondition. 
634+             unsafe  {  core:: hint:: assert_unchecked ( offset <= buf. len ( ) )  } 
635+             offset -= 4 ; 
636+ 
637+             // pull two pairs 
638+             let  quad = remain % 1_00_00 ; 
639+             remain /= 1_00_00 ; 
640+             let  pair1 = ( quad / 100 )  as  usize ; 
641+             let  pair2 = ( quad % 100 )  as  usize ; 
642+             buf[ offset + 0 ] . write ( DEC_DIGITS_LUT [ pair1 *  2  + 0 ] ) ; 
643+             buf[ offset + 1 ] . write ( DEC_DIGITS_LUT [ pair1 *  2  + 1 ] ) ; 
644+             buf[ offset + 2 ] . write ( DEC_DIGITS_LUT [ pair2 *  2  + 0 ] ) ; 
645+             buf[ offset + 3 ] . write ( DEC_DIGITS_LUT [ pair2 *  2  + 1 ] ) ; 
646+         } 
636647
637-     // Format per two digits from the lookup table. 
638-     if  remain > 9  { 
639-         // SAFETY: All of the decimals fit in buf due to MAX_DEC_N  
640-         // and the if condition ensures at least 2 more decimals. 
641-         unsafe  {  core:: hint:: assert_unchecked ( offset >= 2 )  } 
642-         // SAFETY: The offset counts down from its initial buf.len() 
643-         // without underflow due to the previous precondition. 
644-         unsafe  {  core:: hint:: assert_unchecked ( offset <= buf. len ( ) )  } 
645-         offset -= 2 ; 
646- 
647-         let  pair = ( remain % 100 )  as  usize ; 
648-         remain /= 100 ; 
649-         buf[ offset + 0 ] . write ( DEC_DIGITS_LUT [ pair *  2  + 0 ] ) ; 
650-         buf[ offset + 1 ] . write ( DEC_DIGITS_LUT [ pair *  2  + 1 ] ) ; 
651-     } 
648+          // Format per two digits from the lookup table. 
649+          if  remain > 9  { 
650+              // SAFETY: All of the decimals fit in buf due to U128_MAX_DEC_N  
651+              // and the if condition ensures at least 2 more decimals. 
652+              unsafe  {  core:: hint:: assert_unchecked ( offset >= 2 )  } 
653+              // SAFETY: The offset counts down from its initial buf.len() 
654+              // without underflow due to the previous precondition. 
655+              unsafe  {  core:: hint:: assert_unchecked ( offset <= buf. len ( ) )  } 
656+              offset -= 2 ; 
657+ 
658+              let  pair = ( remain % 100 )  as  usize ; 
659+              remain /= 100 ; 
660+              buf[ offset + 0 ] . write ( DEC_DIGITS_LUT [ pair *  2  + 0 ] ) ; 
661+              buf[ offset + 1 ] . write ( DEC_DIGITS_LUT [ pair *  2  + 1 ] ) ; 
662+          } 
652663
653-     // Format the last remaining digit, if any. 
654-     if  remain != 0  { 
655-         // SAFETY: All of the decimals fit in buf due to MAX_DEC_N  
656-         // and the if condition ensures (at least) 1 more decimals. 
657-         unsafe  {  core:: hint:: assert_unchecked ( offset >= 1 )  } 
658-         // SAFETY: The offset counts down from its initial buf.len() 
659-         // without underflow due to the previous precondition. 
660-         unsafe  {  core:: hint:: assert_unchecked ( offset <= buf. len ( ) )  } 
661-         offset -= 1 ; 
662- 
663-         // Either the compiler sees that remain < 10, or it prevents 
664-         // a boundary check up next. 
665-         let  last = ( remain &  15 )  as  usize ; 
666-         buf[ offset] . write ( DEC_DIGITS_LUT [ last *  2  + 1 ] ) ; 
667-         // not used: remain = 0; 
668-     } 
664+          // Format the last remaining digit, if any. 
665+          if  remain != 0  { 
666+              // SAFETY: All of the decimals fit in buf due to U128_MAX_DEC_N  
667+              // and the if condition ensures (at least) 1 more decimals. 
668+              unsafe  {  core:: hint:: assert_unchecked ( offset >= 1 )  } 
669+              // SAFETY: The offset counts down from its initial buf.len() 
670+              // without underflow due to the previous precondition. 
671+              unsafe  {  core:: hint:: assert_unchecked ( offset <= buf. len ( ) )  } 
672+              offset -= 1 ; 
673+ 
674+              // Either the compiler sees that remain < 10, or it prevents 
675+              // a boundary check up next. 
676+              let  last = ( remain &  15 )  as  usize ; 
677+              buf[ offset] . write ( DEC_DIGITS_LUT [ last *  2  + 1 ] ) ; 
678+              // not used: remain = 0; 
679+          } 
669680
670-     // SAFETY: All buf content since offset is set. 
671-     let  written = unsafe  {  buf. get_unchecked ( offset..)  } ; 
672-     // SAFETY: Writes use ASCII from the lookup table exclusively. 
673-     let  as_str =  unsafe  { 
674-         str:: from_utf8_unchecked ( slice:: from_raw_parts ( 
675-             MaybeUninit :: slice_as_ptr ( written) , 
676-             written. len ( ) , 
677-         ) ) 
678-     } ; 
679-     f . pad_integral ( is_nonnegative ,   "" ,  as_str ) 
681+          // SAFETY: All buf content since offset is set. 
682+          let  written = unsafe  {  buf. get_unchecked ( offset..)  } ; 
683+          // SAFETY: Writes use ASCII from the lookup table exclusively. 
684+          unsafe  { 
685+              str:: from_utf8_unchecked ( slice:: from_raw_parts ( 
686+                  MaybeUninit :: slice_as_ptr ( written) , 
687+                  written. len ( ) , 
688+              ) ) 
689+          } 
690+     } 
680691} 
681692
682693/// Encodes the 16 least-significant decimals of n into `buf[OFFSET .. OFFSET + 
683694/// 16 ]`. 
684- fn  enc_16lsd < const  OFFSET :  usize > ( buf :  & mut  [ MaybeUninit < u8 > ;   39 ] ,  n :  u64 )  { 
695+ fn  enc_16lsd < const  OFFSET :  usize > ( buf :  & mut  [ MaybeUninit < u8 > ] ,  n :  u64 )  { 
685696    // Consume the least-significant decimals from a working copy. 
686697    let  mut  remain = n; 
687698
0 commit comments