@@ -171,14 +171,16 @@ impl Instant {
171
171
/// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
172
172
/// otherwise.
173
173
pub fn checked_add ( & self , duration : Duration ) -> Option < Instant > {
174
- self . 0 . checked_add ( duration. as_nanos ( ) as u64 ) . map ( Instant )
174
+ let total_nanos = u64:: try_from ( duration. as_nanos ( ) ) . ok ( ) ?;
175
+ self . 0 . checked_add ( total_nanos) . map ( Instant )
175
176
}
176
177
177
178
/// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
178
179
/// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
179
180
/// otherwise.
180
181
pub fn checked_sub ( & self , duration : Duration ) -> Option < Instant > {
181
- self . 0 . checked_sub ( duration. as_nanos ( ) as u64 ) . map ( Instant )
182
+ let total_nanos = u64:: try_from ( duration. as_nanos ( ) ) . ok ( ) ?;
183
+ self . 0 . checked_sub ( total_nanos) . map ( Instant )
182
184
}
183
185
}
184
186
@@ -371,4 +373,31 @@ mod tests {
371
373
assert_eq ! ( t4. 0 , 1440 ) ;
372
374
} )
373
375
}
376
+
377
+ // Test fix for issue #109
378
+ #[ test]
379
+ #[ cfg_attr(
380
+ all( target_arch = "wasm32" , target_os = "unknown" ) ,
381
+ wasm_bindgen_test:: wasm_bindgen_test
382
+ ) ]
383
+ fn checked_arithmetic_u64_overflow ( ) {
384
+ fn nanos_to_dur ( total_nanos : u128 ) -> Duration {
385
+ let nanos_per_sec = Duration :: from_secs ( 1 ) . as_nanos ( ) ;
386
+ let secs = total_nanos / nanos_per_sec;
387
+ let nanos = total_nanos % nanos_per_sec;
388
+ let dur = Duration :: new ( secs as _ , nanos as _ ) ;
389
+ assert_eq ! ( dur. as_nanos( ) , total_nanos) ;
390
+ dur
391
+ }
392
+
393
+ let dur = nanos_to_dur ( 1 << 64 ) ;
394
+ let now = Instant :: now ( ) ;
395
+
396
+ let behind = now. checked_sub ( dur) ;
397
+ let ahead = now. checked_add ( dur) ;
398
+
399
+ assert_ne ! ( Duration :: ZERO , dur) ;
400
+ assert_ne ! ( Some ( now) , behind) ;
401
+ assert_ne ! ( Some ( now) , ahead) ;
402
+ }
374
403
}
0 commit comments