@@ -6,6 +6,15 @@ 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 {
14+ std:: mem:: transmute ( [ 0u8 ; std:: mem:: size_of :: < timespec > ( ) ] )
15+ }
16+ }
17+
918#[ cfg( any(
1019 all( feature = "time" , any( target_os = "android" , target_os = "linux" ) ) ,
1120 all(
@@ -20,7 +29,7 @@ use std::{cmp, fmt, ops};
2029 )
2130) ) ]
2231pub ( crate ) mod timer {
23- use crate :: sys:: time:: TimeSpec ;
32+ use crate :: sys:: time:: { TimeSpec , zero_init_timespec } ;
2433 use bitflags:: bitflags;
2534
2635 #[ derive( Debug , Clone , Copy ) ]
@@ -29,14 +38,8 @@ pub(crate) mod timer {
2938 impl TimerSpec {
3039 pub const fn none ( ) -> Self {
3140 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- } ,
41+ it_interval : zero_init_timespec ( ) ,
42+ it_value : zero_init_timespec ( ) ,
4043 } )
4144 }
4245 }
@@ -57,10 +60,7 @@ pub(crate) mod timer {
5760 fn from ( expiration : Expiration ) -> TimerSpec {
5861 match expiration {
5962 Expiration :: OneShot ( t) => TimerSpec ( libc:: itimerspec {
60- it_interval : libc:: timespec {
61- tv_sec : 0 ,
62- tv_nsec : 0 ,
63- } ,
63+ it_interval : zero_init_timespec ( ) ,
6464 it_value : * t. as_ref ( ) ,
6565 } ) ,
6666 Expiration :: IntervalDelayed ( start, interval) => {
@@ -118,6 +118,7 @@ pub(crate) mod timer {
118118 libc:: timespec {
119119 tv_sec : 0 ,
120120 tv_nsec : 0 ,
121+ ..
121122 } ,
122123 it_value : ts,
123124 } ) => Expiration :: OneShot ( ts. into ( ) ) ,
@@ -257,18 +258,17 @@ impl PartialOrd for TimeSpec {
257258
258259impl TimeValLike for TimeSpec {
259260 #[ inline]
261+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
262+ // https://github.com/rust-lang/libc/issues/1848
260263 fn seconds ( seconds : i64 ) -> TimeSpec {
261264 assert ! (
262265 ( TS_MIN_SECONDS ..=TS_MAX_SECONDS ) . contains( & seconds) ,
263266 "TimeSpec out of bounds; seconds={}" ,
264267 seconds
265268 ) ;
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- } )
269+ let mut ts = zero_init_timespec ( ) ;
270+ ts. tv_sec = seconds as time_t ;
271+ TimeSpec ( ts)
272272 }
273273
274274 #[ inline]
@@ -292,18 +292,18 @@ impl TimeValLike for TimeSpec {
292292
293293 /// Makes a new `TimeSpec` with given number of nanoseconds.
294294 #[ inline]
295+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
296+ // https://github.com/rust-lang/libc/issues/1848
295297 fn nanoseconds ( nanoseconds : i64 ) -> TimeSpec {
296298 let ( secs, nanos) = div_mod_floor_64 ( nanoseconds, NANOS_PER_SEC ) ;
297299 assert ! (
298300 ( TS_MIN_SECONDS ..=TS_MAX_SECONDS ) . contains( & secs) ,
299301 "TimeSpec out of bounds"
300302 ) ;
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- } )
303+ let mut ts = zero_init_timespec ( ) ;
304+ ts. tv_sec = secs as time_t ;
305+ ts. tv_nsec = nanos as timespec_tv_nsec_t ;
306+ TimeSpec ( ts)
307307 }
308308
309309 // The cast is not unnecessary on all platforms.
@@ -337,10 +337,10 @@ impl TimeSpec {
337337 /// Construct a new `TimeSpec` from its components
338338 #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ] // https://github.com/rust-lang/libc/issues/1848
339339 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- } )
340+ let mut ts = zero_init_timespec ( ) ;
341+ ts . tv_sec = seconds;
342+ ts . tv_nsec = nanoseconds;
343+ Self ( ts )
344344 }
345345
346346 fn nanos_mod_sec ( & self ) -> timespec_tv_nsec_t {
@@ -360,13 +360,13 @@ impl TimeSpec {
360360 self . 0 . tv_nsec
361361 }
362362
363+ #[ cfg_attr( target_env = "musl" , allow( deprecated) ) ]
364+ // https://github.com/rust-lang/libc/issues/1848
363365 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- } )
366+ let mut ts = zero_init_timespec ( ) ;
367+ ts. tv_sec = duration. as_secs ( ) as time_t ;
368+ ts. tv_nsec = duration. subsec_nanos ( ) as timespec_tv_nsec_t ;
369+ TimeSpec ( ts)
370370 }
371371
372372 pub const fn from_timespec ( timespec : timespec ) -> Self {
0 commit comments