@@ -1043,7 +1043,7 @@ impl fmt::Debug for Duration {
10431043/// to the formatter's `width`, if specified. 
10441044fn  fmt_decimal ( 
10451045 f :  & mut  fmt:: Formatter < ' _ > , 
1046-  mut   integer_part :  u64 , 
1046+  integer_part :  u64 , 
10471047 mut  fractional_part :  u32 , 
10481048 mut  divisor :  u32 , 
10491049 prefix :  & str , 
@@ -1075,7 +1075,7 @@ impl fmt::Debug for Duration {
10751075 // normal floating point numbers. However, we only need to do work 
10761076 // when rounding up. This happens if the first digit of the 
10771077 // remaining ones is >= 5. 
1078-  if  fractional_part > 0  && fractional_part >= divisor *  5  { 
1078+  let  integer_part =  if  fractional_part > 0  && fractional_part >= divisor *  5  { 
10791079 // Round up the number contained in the buffer. We go through 
10801080 // the buffer backwards and keep track of the carry. 
10811081 let  mut  rev_pos = pos; 
@@ -1099,9 +1099,18 @@ impl fmt::Debug for Duration {
10991099 // the whole buffer to '0's and need to increment the integer 
11001100 // part. 
11011101 if  carry { 
1102-  integer_part += 1 ; 
1102+  // If `integer_part == u64::MAX` and precision < 9, any 
1103+  // carry of the overflow during rounding of the 
1104+  // `fractional_part` into the `integer_part` will cause the 
1105+  // `integer_part` itself to overflow. Avoid this by using an 
1106+  // `Option<u64>`, with `None` representing `u64::MAX + 1`. 
1107+  integer_part. checked_add ( 1 ) 
1108+  }  else  { 
1109+  Some ( integer_part) 
11031110 } 
1104-  } 
1111+  }  else  { 
1112+  Some ( integer_part) 
1113+  } ; 
11051114
11061115 // Determine the end of the buffer: if precision is set, we just 
11071116 // use as many digits from the buffer (capped to 9). If it isn't 
@@ -1111,7 +1120,12 @@ impl fmt::Debug for Duration {
11111120 // This closure emits the formatted duration without emitting any 
11121121 // padding (padding is calculated below). 
11131122 let  emit_without_padding = |f :  & mut  fmt:: Formatter < ' _ > | { 
1114-  write ! ( f,  "{}{}" ,  prefix,  integer_part) ?; 
1123+  if  let  Some ( integer_part)  = integer_part { 
1124+  write ! ( f,  "{}{}" ,  prefix,  integer_part) ?; 
1125+  }  else  { 
1126+  // u64::MAX + 1 == 18446744073709551616 
1127+  write ! ( f,  "{}18446744073709551616" ,  prefix) ?; 
1128+  } 
11151129
11161130 // Write the decimal point and the fractional part (if any). 
11171131 if  end > 0  { 
@@ -1141,12 +1155,17 @@ impl fmt::Debug for Duration {
11411155 // 2. The postfix: can be "µs" so we have to count UTF8 characters. 
11421156 let  mut  actual_w = prefix. len ( )  + postfix. chars ( ) . count ( ) ; 
11431157 // 3. The integer part: 
1144-  if  let  Some ( log)  = integer_part. checked_ilog10 ( )  { 
1145-  // integer_part is > 0, so has length log10(x)+1 
1146-  actual_w += 1  + log as  usize ; 
1158+  if  let  Some ( integer_part)  = integer_part { 
1159+  if  let  Some ( log)  = integer_part. checked_ilog10 ( )  { 
1160+  // integer_part is > 0, so has length log10(x)+1 
1161+  actual_w += 1  + log as  usize ; 
1162+  }  else  { 
1163+  // integer_part is 0, so has length 1. 
1164+  actual_w += 1 ; 
1165+  } 
11471166 }  else  { 
1148-  // integer_part is 0 , so has length 1.  
1149-  actual_w += 1 ; 
1167+  // integer_part is u64::MAX + 1 , so has length 20  
1168+  actual_w += 20 ; 
11501169 } 
11511170 // 4. The fractional part (if any): 
11521171 if  end > 0  { 
0 commit comments