about summary refs log tree commit diff
path: root/library/std/src/sys/pal/unix/time.rs
diff options
context:
space:
mode:
authorThe rustc-josh-sync Cronjob Bot <github-actions@github.com>2025-09-29 04:07:50 +0000
committerThe rustc-josh-sync Cronjob Bot <github-actions@github.com>2025-09-29 04:07:50 +0000
commit24f6f94c5ad90be5d1ced24d83b8485712bcc27a (patch)
tree722e3fdf88fdae0903cd1ff43cfc801db18345d3 /library/std/src/sys/pal/unix/time.rs
parent50171eb172a9418e8a20ad7d813d256305add5f0 (diff)
parentf957826bff7a68b267ce75b1ea56352aed0cca0a (diff)
downloadrust-24f6f94c5ad90be5d1ced24d83b8485712bcc27a.tar.gz
rust-24f6f94c5ad90be5d1ced24d83b8485712bcc27a.zip
Merge ref 'f957826bff7a' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh.

Upstream ref: f957826bff7a68b267ce75b1ea56352aed0cca0a
Filtered ref: 7291893f9d875b6e8775a7a0e661abdaec15d3c1
Upstream diff: https://github.com/rust-lang/rust/compare/caccb4d0368bd918ef6668af8e13834d07040417...f957826bff7a68b267ce75b1ea56352aed0cca0a

This merge was created using https://github.com/rust-lang/josh-sync.
Diffstat (limited to 'library/std/src/sys/pal/unix/time.rs')
-rw-r--r--library/std/src/sys/pal/unix/time.rs27
1 files changed, 12 insertions, 15 deletions
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index bd7f74fea6a..c207f41cad4 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -134,28 +134,25 @@ impl Timespec {
     }
 
     pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        // When a >= b, the difference fits in u64.
+        fn sub_ge_to_unsigned(a: i64, b: i64) -> u64 {
+            debug_assert!(a >= b);
+            a.wrapping_sub(b).cast_unsigned()
+        }
+
         if self >= other {
-            // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
-            // to optimize it into a branchless form (see also #75545):
-            //
-            // 1. `self.tv_sec - other.tv_sec` shows up as a common expression
-            //    in both branches, i.e. the `else` must have its `- 1`
-            //    subtraction after the common one, not interleaved with it
-            //    (it used to be `self.tv_sec - 1 - other.tv_sec`)
-            //
-            // 2. the `Duration::new` call (or any other additional complexity)
-            //    is outside of the `if`-`else`, not duplicated in both branches
-            //
-            // Ideally this code could be rearranged such that it more
-            // directly expresses the lower-cost behavior we want from it.
             let (secs, nsec) = if self.tv_nsec.as_inner() >= other.tv_nsec.as_inner() {
                 (
-                    (self.tv_sec - other.tv_sec) as u64,
+                    sub_ge_to_unsigned(self.tv_sec, other.tv_sec),
                     self.tv_nsec.as_inner() - other.tv_nsec.as_inner(),
                 )
             } else {
+                // Following sequence of assertions explain why `self.tv_sec - 1` does not underflow.
+                debug_assert!(self.tv_nsec < other.tv_nsec);
+                debug_assert!(self.tv_sec > other.tv_sec);
+                debug_assert!(self.tv_sec > i64::MIN);
                 (
-                    (self.tv_sec - other.tv_sec - 1) as u64,
+                    sub_ge_to_unsigned(self.tv_sec - 1, other.tv_sec),
                     self.tv_nsec.as_inner() + (NSEC_PER_SEC as u32) - other.tv_nsec.as_inner(),
                 )
             };