@@ -6,6 +6,13 @@ use std::convert::From;
66use std:: time:: Duration ;
77use std:: { cmp, fmt, ops} ;
88
9+ const fn zero_init_timespec ( ) -> timespec {
10+ // `std::mem::zeroed()` is not yet a const fn (https://github.com/rust-lang/rust/issues/62061)
11+ // so we will instead initialize an array of the appropriate size to zero and then
12+ // transmute it to a timespec value.
13+ unsafe { std:: mem:: transmute ( [ 0u8 ; std:: mem:: size_of :: < timespec > ( ) ] ) }
14+ }
15+
916#[ cfg( any(
1017 all( feature = "time" , any( target_os = "android" , target_os = "linux" ) ) ,
1118 all(
@@ -20,7 +27,7 @@ use std::{cmp, fmt, ops};
2027 )
2128) ) ]
2229pub ( crate ) mod timer {
23- use crate :: sys:: time:: TimeSpec ;
30+ use crate :: sys:: time:: { zero_init_timespec , TimeSpec } ;
2431 use bitflags:: bitflags;
2532
2633 #[ derive( Debug , Clone , Copy ) ]
@@ -29,14 +36,8 @@ pub(crate) mod timer {
2936 impl TimerSpec {
3037 pub const fn none ( ) -> Self {
3138 Self ( libc:: itimerspec {
32- it_interval : libc:: timespec {
33- tv_sec : 0 ,
34- tv_nsec : 0 ,
35- } ,
36- it_value : libc:: timespec {
37- tv_sec : 0 ,
38- tv_nsec : 0 ,
39- } ,
39+ it_interval : zero_init_timespec ( ) ,
40+ it_value : zero_init_timespec ( ) ,
4041 } )
4142 }
4243 }
@@ -57,10 +58,7 @@ pub(crate) mod timer {
5758 fn from ( expiration : Expiration ) -> TimerSpec {
5859 match expiration {
5960 Expiration :: OneShot ( t) => TimerSpec ( libc:: itimerspec {
60- it_interval : libc:: timespec {
61- tv_sec : 0 ,
62- tv_nsec : 0 ,
63- } ,
61+ it_interval : zero_init_timespec ( ) ,
6462 it_value : * t. as_ref ( ) ,
6563 } ) ,
6664 Expiration :: IntervalDelayed ( start, interval) => {
@@ -118,6 +116,7 @@ pub(crate) mod timer {
118116 libc:: timespec {
119117 tv_sec : 0 ,
120118 tv_nsec : 0 ,
119+ ..
121120 } ,
122121 it_value : ts,
123122 } ) => Expiration :: OneShot ( ts. into ( ) ) ,
@@ -257,18 +256,17 @@ impl PartialOrd for TimeSpec {
257256
258257impl TimeValLike for TimeSpec {
259258 #[ inline]
259+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
260+ // https://github.com/rust-lang/libc/issues/1848
260261 fn seconds ( seconds : i64 ) -> TimeSpec {
261262 assert ! (
262263 ( TS_MIN_SECONDS ..=TS_MAX_SECONDS ) . contains( & seconds) ,
263264 "TimeSpec out of bounds; seconds={}" ,
264265 seconds
265266 ) ;
266- #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
267- // https://github.com/rust-lang/libc/issues/1848
268- TimeSpec ( timespec {
269- tv_sec : seconds as time_t ,
270- tv_nsec : 0 ,
271- } )
267+ let mut ts = zero_init_timespec ( ) ;
268+ ts. tv_sec = seconds as time_t ;
269+ TimeSpec ( ts)
272270 }
273271
274272 #[ inline]
@@ -292,18 +290,18 @@ impl TimeValLike for TimeSpec {
292290
293291 /// Makes a new `TimeSpec` with given number of nanoseconds.
294292 #[ inline]
293+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
294+ // https://github.com/rust-lang/libc/issues/1848
295295 fn nanoseconds ( nanoseconds : i64 ) -> TimeSpec {
296296 let ( secs, nanos) = div_mod_floor_64 ( nanoseconds, NANOS_PER_SEC ) ;
297297 assert ! (
298298 ( TS_MIN_SECONDS ..=TS_MAX_SECONDS ) . contains( & secs) ,
299299 "TimeSpec out of bounds"
300300 ) ;
301- #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
302- // https://github.com/rust-lang/libc/issues/1848
303- TimeSpec ( timespec {
304- tv_sec : secs as time_t ,
305- tv_nsec : nanos as timespec_tv_nsec_t ,
306- } )
301+ let mut ts = zero_init_timespec ( ) ;
302+ ts. tv_sec = secs as time_t ;
303+ ts. tv_nsec = nanos as timespec_tv_nsec_t ;
304+ TimeSpec ( ts)
307305 }
308306
309307 // The cast is not unnecessary on all platforms.
@@ -337,10 +335,10 @@ impl TimeSpec {
337335 /// Construct a new `TimeSpec` from its components
338336 #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ] // https://github.com/rust-lang/libc/issues/1848
339337 pub const fn new ( seconds : time_t , nanoseconds : timespec_tv_nsec_t ) -> Self {
340- Self ( timespec {
341- tv_sec : seconds,
342- tv_nsec : nanoseconds,
343- } )
338+ let mut ts = zero_init_timespec ( ) ;
339+ ts . tv_sec = seconds;
340+ ts . tv_nsec = nanoseconds;
341+ Self ( ts )
344342 }
345343
346344 fn nanos_mod_sec ( & self ) -> timespec_tv_nsec_t {
@@ -360,13 +358,13 @@ impl TimeSpec {
360358 self . 0 . tv_nsec
361359 }
362360
361+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
362+ // https://github.com/rust-lang/libc/issues/1848
363363 pub const fn from_duration ( duration : Duration ) -> Self {
364- #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
365- // https://github.com/rust-lang/libc/issues/1848
366- TimeSpec ( timespec {
367- tv_sec : duration. as_secs ( ) as time_t ,
368- tv_nsec : duration. subsec_nanos ( ) as timespec_tv_nsec_t ,
369- } )
364+ let mut ts = zero_init_timespec ( ) ;
365+ ts. tv_sec = duration. as_secs ( ) as time_t ;
366+ ts. tv_nsec = duration. subsec_nanos ( ) as timespec_tv_nsec_t ;
367+ TimeSpec ( ts)
370368 }
371369
372370 pub const fn from_timespec ( timespec : timespec ) -> Self {
0 commit comments