Avoid superfluous UB checks in IndexRange · qinheping/verify-rust-std@de18ce1 (original) (raw)

Original file line number Diff line number Diff line change
@@ -45,7 +45,8 @@ impl IndexRange {
45 45 #[inline]
46 46 pub const fn len(&self) -> usize {
47 47 // SAFETY: By invariant, this cannot wrap
48 -unsafe { self.end.unchecked_sub(self.start) }
48 +// Using the intrinsic because a UB check here impedes LLVM optimization. (#131563)
49 +unsafe { crate::intrinsics::unchecked_sub(self.end, self.start) }
49 50 }
50 51
51 52 /// # Safety
@@ -82,7 +83,8 @@ impl IndexRange {
82 83 let mid = if n <= self.len() {
83 84 // SAFETY: We just checked that this will be between start and end,
84 85 // and thus the addition cannot overflow.
85 -unsafe { self.start.unchecked_add(n) }
86 +// Using the intrinsic avoids a superfluous UB check.
87 +unsafe { crate::intrinsics::unchecked_add(self.start, n) }
86 88 } else {
87 89 self.end
88 90 };
@@ -100,8 +102,9 @@ impl IndexRange {
100 102 pub fn take_suffix(&mut self, n: usize) -> Self {
101 103 let mid = if n <= self.len() {
102 104 // SAFETY: We just checked that this will be between start and end,
103 -// and thus the addition cannot overflow.
104 -unsafe { self.end.unchecked_sub(n) }
105 +// and thus the subtraction cannot overflow.
106 +// Using the intrinsic avoids a superfluous UB check.
107 +unsafe { crate::intrinsics::unchecked_sub(self.end, n) }
105 108 } else {
106 109 self.start
107 110 };