Skip to content

Commit bd2db28

Browse files
authored
Rollup merge of #144519 - clarfonthey:const-system-time, r=jhpratt
Constify `SystemTime` methods This is separated out from #143949 due to the fact that it touches nontrivial system code. While the same arithmetic methods on `Instant` could be made const, since that type explicitly cannot be constructed at const-time, we don't bother. However, due to the fact that `SystemTime::UNIX_EPOCH` exists, it can be useful to create other anchors at other points in time, and thus these methods should be possible to use in const context. > Side comment: I would honestly like to just move every single implementation which is a thin wrapper over `Duration` or some integer clock into their own module which is tested on all targets, so that we don't have to worry about code for lower-tier targets not being tested. However, the comments in `std::sys_common` pointing out the desire to move things to `std::sys::common` confused me, particularly due to the fact that `std::sys::common` is taken from the hellish asterisk-import of `std::sys::pal::common` and others. > > I think that, for trivial types like this, we should just have a platform-independent module that can be tested on all platforms, to both ensure that the code is properly tested regardless of whether higher-tier platforms needed, and to avoid the extreme mental gymnastics required to determine where in the code it lies. > > However, since I'm not on any of the teams maintaining this code and am not involved, I'll settle for just copy-pasting like everyone else has been doing. I just want to express how I'm not happy about that. **Reviewer note: please only pay attention to the last commit of this PR, until its blocker is merged.** Since this depends on the previous PR: `@rustbot` blocked
2 parents fb9cd24 + 7ce620d commit bd2db28

11 files changed

Lines changed: 166 additions & 68 deletions

File tree

‎library/std/src/lib.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,11 @@
281281
#![feature(cfg_target_thread_local)]
282282
#![feature(cfi_encoding)]
283283
#![feature(char_max_len)]
284+
#![feature(const_trait_impl)]
284285
#![feature(core_float_math)]
285286
#![feature(decl_macro)]
286287
#![feature(deprecated_suggestion)]
288+
#![feature(derive_const)]
287289
#![feature(doc_cfg)]
288290
#![feature(doc_cfg_hide)]
289291
#![feature(doc_masked)]
@@ -329,6 +331,10 @@
329331
#![feature(bstr_internals)]
330332
#![feature(char_internals)]
331333
#![feature(clone_to_uninit)]
334+
#![feature(const_cmp)]
335+
#![feature(const_ops)]
336+
#![feature(const_option_ops)]
337+
#![feature(const_try)]
332338
#![feature(core_intrinsics)]
333339
#![feature(core_io_borrowed_buf)]
334340
#![feature(drop_guard)]

‎library/std/src/sys/pal/hermit/time.rs‎

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,15 @@ impl Timespec {
2525
Timespec{t:timespec{ tv_sec, tv_nsec }}
2626
}
2727

28-
fnsub_timespec(&self,other:&Timespec) -> Result<Duration,Duration>{
29-
ifself >= other {
28+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
29+
constfnsub_timespec(&self,other:&Timespec) -> Result<Duration,Duration>{
30+
// FIXME: const PartialOrd
31+
letmut cmp = self.t.tv_sec - other.t.tv_sec;
32+
if cmp == 0{
33+
cmp = self.t.tv_nsecasi64 - other.t.tv_nsecasi64;
34+
}
35+
36+
if cmp >= 0{
3037
Ok(ifself.t.tv_nsec >= other.t.tv_nsec{
3138
Duration::new(
3239
(self.t.tv_sec - other.t.tv_sec)asu64,
@@ -46,20 +53,22 @@ impl Timespec {
4653
}
4754
}
4855

49-
fnchecked_add_duration(&self,other:&Duration) -> Option<Timespec>{
56+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
57+
constfnchecked_add_duration(&self,other:&Duration) -> Option<Timespec>{
5058
letmut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;
5159

5260
// Nano calculations can't overflow because nanos are <1B which fit
5361
// in a u32.
54-
letmut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
55-
if nsec >= NSEC_PER_SEC.try_into().unwrap(){
56-
nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
62+
letmut nsec = other.subsec_nanos() + self.t.tv_nsecasu32;
63+
if nsec >= NSEC_PER_SECasu32{
64+
nsec -= NSEC_PER_SECasu32;
5765
secs = secs.checked_add(1)?;
5866
}
5967
Some(Timespec{t:timespec{tv_sec: secs,tv_nsec: nsec as_}})
6068
}
6169

62-
fnchecked_sub_duration(&self,other:&Duration) -> Option<Timespec>{
70+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
71+
constfnchecked_sub_duration(&self,other:&Duration) -> Option<Timespec>{
6372
letmut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;
6473

6574
// Similar to above, nanos can't overflow.
@@ -213,15 +222,18 @@ impl SystemTime {
213222
SystemTime(time)
214223
}
215224

216-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
225+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
226+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
217227
self.0.sub_timespec(&other.0)
218228
}
219229

220-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
230+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
231+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
221232
Some(SystemTime(self.0.checked_add_duration(other)?))
222233
}
223234

224-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
235+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
236+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
225237
Some(SystemTime(self.0.checked_sub_duration(other)?))
226238
}
227239
}

‎library/std/src/sys/pal/sgx/time.rs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,22 @@ impl SystemTime {
3232
SystemTime(usercalls::insecure_time())
3333
}
3434

35-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
36-
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
35+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
36+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
37+
// FIXME: ok_or_else with const closures
38+
matchself.0.checked_sub(other.0){
39+
Some(duration) => Ok(duration),
40+
None => Err(other.0 - self.0),
41+
}
3742
}
3843

39-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
44+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
45+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
4046
Some(SystemTime(self.0.checked_add(*other)?))
4147
}
4248

43-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
49+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
50+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
4451
Some(SystemTime(self.0.checked_sub(*other)?))
4552
}
4653
}

‎library/std/src/sys/pal/solid/time.rs‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,22 @@ impl SystemTime {
3939
Self(t)
4040
}
4141

42-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
42+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
43+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
4344
ifself.0 >= other.0{
4445
Ok(Duration::from_secs((self.0asu64).wrapping_sub(other.0asu64)))
4546
}else{
4647
Err(Duration::from_secs((other.0asu64).wrapping_sub(self.0asu64)))
4748
}
4849
}
4950

50-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
51+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
52+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
5153
Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
5254
}
5355

54-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
56+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
57+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
5558
Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
5659
}
5760
}

‎library/std/src/sys/pal/uefi/time.rs‎

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,32 @@ impl SystemTime {
8080
.unwrap_or_else(|| panic!("time not implemented on this platform"))
8181
}
8282

83-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
84-
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
83+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
84+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
85+
// FIXME: ok_or_else with const closures
86+
matchself.0.checked_sub(other.0){
87+
Some(duration) => Ok(duration),
88+
None => Err(other.0 - self.0),
89+
}
8590
}
8691

87-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
88-
let temp = Self(self.0.checked_add(*other)?);
92+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
93+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
94+
let temp = self.0.checked_add(*other)?;
8995

9096
// Check if can be represented in UEFI
91-
if temp <= MAX_UEFI_TIME{Some(temp)}else{None}
97+
// FIXME: const PartialOrd
98+
letmut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs();
99+
if cmp == 0{
100+
cmp = temp.subsec_nanos()asu64 - MAX_UEFI_TIME.0.subsec_nanos()asu64;
101+
}
102+
103+
if cmp <= 0{Some(SystemTime(temp))}else{None}
92104
}
93105

94-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
95-
self.0.checked_sub(*other).map(Self)
106+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
107+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
108+
Some(SystemTime(self.0.checked_sub(*other)?))
96109
}
97110
}
98111

‎library/std/src/sys/pal/unix/time.rs‎

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,18 @@ impl SystemTime {
3838
SystemTime{t:Timespec::now(libc::CLOCK_REALTIME)}
3939
}
4040

41-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
41+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
42+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
4243
self.t.sub_timespec(&other.t)
4344
}
4445

45-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
46+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
47+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
4648
Some(SystemTime{t:self.t.checked_add_duration(other)? })
4749
}
4850

49-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
51+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
52+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
5053
Some(SystemTime{t:self.t.checked_sub_duration(other)? })
5154
}
5255
}
@@ -133,8 +136,15 @@ impl Timespec {
133136
Timespec::new(t.tv_secasi64, t.tv_nsecasi64).unwrap()
134137
}
135138

136-
pubfnsub_timespec(&self,other:&Timespec) -> Result<Duration,Duration>{
137-
ifself >= other {
139+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
140+
pubconstfnsub_timespec(&self,other:&Timespec) -> Result<Duration,Duration>{
141+
// FIXME: const PartialOrd
142+
letmut cmp = self.tv_sec - other.tv_sec;
143+
if cmp == 0{
144+
cmp = self.tv_nsec.as_inner()asi64 - other.tv_nsec.as_inner()asi64;
145+
}
146+
147+
if cmp >= 0{
138148
// NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
139149
// to optimize it into a branchless form (see also #75545):
140150
//
@@ -169,7 +179,8 @@ impl Timespec {
169179
}
170180
}
171181

172-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<Timespec>{
182+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
183+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<Timespec>{
173184
letmut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?;
174185

175186
// Nano calculations can't overflow because nanos are <1B which fit
@@ -179,10 +190,11 @@ impl Timespec {
179190
nsec -= NSEC_PER_SECasu32;
180191
secs = secs.checked_add(1)?;
181192
}
182-
Some(unsafe{Timespec::new_unchecked(secs, nsec.into())})
193+
Some(unsafe{Timespec::new_unchecked(secs, nsecasi64)})
183194
}
184195

185-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<Timespec>{
196+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
197+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<Timespec>{
186198
letmut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?;
187199

188200
// Similar to above, nanos can't overflow.
@@ -191,7 +203,7 @@ impl Timespec {
191203
nsec += NSEC_PER_SECasi32;
192204
secs = secs.checked_sub(1)?;
193205
}
194-
Some(unsafe{Timespec::new_unchecked(secs, nsec.into())})
206+
Some(unsafe{Timespec::new_unchecked(secs, nsecasi64)})
195207
}
196208

197209
#[allow(dead_code)]

‎library/std/src/sys/pal/unsupported/time.rs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,22 @@ impl SystemTime {
3131
panic!("time not implemented on this platform")
3232
}
3333

34-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
35-
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
34+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
35+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
36+
// FIXME: ok_or_else with const closures
37+
matchself.0.checked_sub(other.0){
38+
Some(duration) => Ok(duration),
39+
None => Err(other.0 - self.0),
40+
}
3641
}
3742

38-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
43+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
44+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
3945
Some(SystemTime(self.0.checked_add(*other)?))
4046
}
4147

42-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
48+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
49+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
4350
Some(SystemTime(self.0.checked_sub(*other)?))
4451
}
4552
}

‎library/std/src/sys/pal/wasi/time.rs‎

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,34 @@ impl SystemTime {
4343
SystemTime(current_time(wasi::CLOCKID_REALTIME))
4444
}
4545

46-
pubfnfrom_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime{
46+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
47+
pubconstfnfrom_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime{
4748
SystemTime(Duration::from_nanos(ts))
4849
}
4950

50-
pubfnto_wasi_timestamp(&self) -> Option<wasi::Timestamp>{
51-
self.0.as_nanos().try_into().ok()
51+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
52+
pubconstfnto_wasi_timestamp(&self) -> Option<wasi::Timestamp>{
53+
// FIXME: const TryInto
54+
let ns = self.0.as_nanos();
55+
if ns <= u64::MAXasu128{Some(ns asu64)}else{None}
5256
}
5357

54-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
55-
self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
58+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
59+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
60+
// FIXME: ok_or_else with const closures
61+
matchself.0.checked_sub(other.0){
62+
Some(duration) => Ok(duration),
63+
None => Err(other.0 - self.0),
64+
}
5665
}
5766

58-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
67+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
68+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
5969
Some(SystemTime(self.0.checked_add(*other)?))
6070
}
6171

62-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
72+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
73+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
6374
Some(SystemTime(self.0.checked_sub(*other)?))
6475
}
6576
}

‎library/std/src/sys/pal/windows/time.rs‎

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ impl SystemTime {
7272
}
7373
}
7474

75-
fnfrom_intervals(intervals:i64) -> SystemTime{
75+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
76+
constfnfrom_intervals(intervals:i64) -> SystemTime{
7677
SystemTime{
7778
t: c::FILETIME{
7879
dwLowDateTime: intervals asu32,
@@ -81,11 +82,13 @@ impl SystemTime {
8182
}
8283
}
8384

84-
fnintervals(&self) -> i64{
85+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
86+
constfnintervals(&self) -> i64{
8587
(self.t.dwLowDateTimeasi64) | ((self.t.dwHighDateTimeasi64) << 32)
8688
}
8789

88-
pubfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
90+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
91+
pubconstfnsub_time(&self,other:&SystemTime) -> Result<Duration,Duration>{
8992
let me = self.intervals();
9093
let other = other.intervals();
9194
if me >= other {
@@ -95,12 +98,14 @@ impl SystemTime {
9598
}
9699
}
97100

98-
pubfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
101+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
102+
pubconstfnchecked_add_duration(&self,other:&Duration) -> Option<SystemTime>{
99103
let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?;
100104
Some(SystemTime::from_intervals(intervals))
101105
}
102106

103-
pubfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
107+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
108+
pubconstfnchecked_sub_duration(&self,other:&Duration) -> Option<SystemTime>{
104109
let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
105110
Some(SystemTime::from_intervals(intervals))
106111
}
@@ -150,15 +155,18 @@ impl Hash for SystemTime {
150155
}
151156
}
152157

153-
fnchecked_dur2intervals(dur:&Duration) -> Option<i64>{
154-
dur.as_secs()
158+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
159+
constfnchecked_dur2intervals(dur:&Duration) -> Option<i64>{
160+
// FIXME: const TryInto
161+
let secs = dur
162+
.as_secs()
155163
.checked_mul(INTERVALS_PER_SEC)?
156-
.checked_add(dur.subsec_nanos()asu64 / 100)?
157-
.try_into()
158-
.ok()
164+
.checked_add(dur.subsec_nanos()asu64 / 100)?;
165+
if secs <= i64::MAXasu64{Some(secs.cast_signed())}else{None}
159166
}
160167

161-
fnintervals2dur(intervals:u64) -> Duration{
168+
#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
169+
constfnintervals2dur(intervals:u64) -> Duration{
162170
Duration::new(intervals / INTERVALS_PER_SEC,((intervals % INTERVALS_PER_SEC)*100)asu32)
163171
}
164172

0 commit comments

Comments
 (0)