diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index b0abdc749f6..ef3e1acfbf5 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -219,11 +219,8 @@ fn debug_formatting_precision_zero() { #[test] fn debug_formatting_precision_two() { - // This might seem inconsistent with the other units, but printing - // fractional digits for nano seconds would imply more precision than is - // actually stored. - assert_eq!(format!("{:.2?}", Duration::new(0, 0)), "0ns"); - assert_eq!(format!("{:.2?}", Duration::new(0, 123)), "123ns"); + assert_eq!(format!("{:.2?}", Duration::new(0, 0)), "0.00ns"); + assert_eq!(format!("{:.2?}", Duration::new(0, 123)), "123.00ns"); assert_eq!(format!("{:.2?}", Duration::new(0, 1_000)), "1.00µs"); assert_eq!(format!("{:.2?}", Duration::new(0, 7_001)), "7.00µs"); @@ -244,3 +241,12 @@ fn debug_formatting_precision_two() { assert_eq!(format!("{:.2?}", Duration::new(2, 105_000_000)), "2.11s"); assert_eq!(format!("{:.2?}", Duration::new(8, 999_999_999)), "9.00s"); } + +#[test] +fn debug_formatting_precision_high() { + assert_eq!(format!("{:.5?}", Duration::new(0, 23_678)), "23.67800µs"); + + assert_eq!(format!("{:.9?}", Duration::new(1, 000_000_000)), "1.000000000s"); + assert_eq!(format!("{:.10?}", Duration::new(4, 001_000_000)), "4.0010000000s"); + assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s"); +} diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 34bf3637f29..9703c61fe92 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -511,9 +511,9 @@ impl fmt::Debug for Duration { // The next digit is written at this position let mut pos = 0; - // We can stop when there are no non-zero digits left or (when a - // precision was set and we already emitted that many digits). - while fractional_part > 0 && f.precision().map(|p| p > pos).unwrap_or(true) { + // 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; @@ -556,9 +556,13 @@ impl fmt::Debug for Duration { } } + // 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| ::cmp::min(p, 9)).unwrap_or(pos); + // If we haven't emitted a single fractional digit and the precision // wasn't set to a non-zero value, we don't print the decimal point. - let end = f.precision().unwrap_or(pos); if end == 0 { write!(f, "{}", integer_part) } else { @@ -568,7 +572,9 @@ impl fmt::Debug for Duration { ::str::from_utf8_unchecked(&buf[..end]) }; - write!(f, "{}.{}", integer_part, s) + // If the user request a precision > 9, we pad '0's at the end. + let w = f.precision().unwrap_or(pos); + write!(f, "{}.{:0