Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4e431fa

Browse files
committed
Auto merge of #123561 - saethlin:str-unchecked-sub-index, r=scottmcm
Use unchecked_sub in str indexing #108763 applied this logic to indexing for slices, but of course `str` has its own separate impl. Found this by skimming over the codegen for https://github.com/oxidecomputer/hubris/; their dist builds enable overflow checks so the lack of `unchecked_sub` was producing an impossible-to-hit overflow check and also inhibiting some inlining. r? scottmcm
2 parents fc1a4c5 + 712aab7 commit 4e431fa

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

‎library/core/src/str/traits.rs‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Trait implementations for `str`.
22
33
use crate::cmp::Ordering;
4+
use crate::intrinsics::unchecked_sub;
45
use crate::ops;
56
use crate::ptr;
67
use crate::slice::SliceIndex;
@@ -210,9 +211,10 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
210211

211212
// SAFETY: the caller guarantees that `self` is in bounds of `slice`
212213
// which satisfies all the conditions for `add`.
213-
let ptr = unsafe { slice.as_ptr().add(self.start) };
214-
let len = self.end - self.start;
215-
ptr::slice_from_raw_parts(ptr, len) as *const str
214+
unsafe {
215+
let new_len = unchecked_sub(self.end, self.start);
216+
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str
217+
}
216218
}
217219
#[inline]
218220
unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
@@ -229,9 +231,10 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
229231
);
230232

231233
// SAFETY: see comments for `get_unchecked`.
232-
let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
233-
let len = self.end - self.start;
234-
ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
234+
unsafe {
235+
let new_len = unchecked_sub(self.end, self.start);
236+
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str
237+
}
235238
}
236239
#[inline]
237240
fn index(self, slice: &str) -> &Self::Output {

‎tests/codegen/slice-indexing.rs‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,31 @@ pub unsafe fn get_unchecked_mut_by_range(x: &mut [i32], r: Range<usize>) -> &mut
3232
// CHECK: sub nuw i64
3333
x.get_unchecked_mut(r)
3434
}
35+
36+
// CHECK-LABEL: @str_index_by_range(
37+
#[no_mangle]
38+
pub fn str_index_by_range(x: &str, r: Range<usize>) -> &str {
39+
// CHECK: sub nuw i64
40+
&x[r]
41+
}
42+
43+
// CHECK-LABEL: @str_get_unchecked_by_range(
44+
#[no_mangle]
45+
pub unsafe fn str_get_unchecked_by_range(x: &str, r: Range<usize>) -> &str {
46+
// CHECK: sub nuw i64
47+
x.get_unchecked(r)
48+
}
49+
50+
// CHECK-LABEL: @str_index_mut_by_range(
51+
#[no_mangle]
52+
pub fn str_index_mut_by_range(x: &mut str, r: Range<usize>) -> &mut str {
53+
// CHECK: sub nuw i64
54+
&mut x[r]
55+
}
56+
57+
// CHECK-LABEL: @str_get_unchecked_mut_by_range(
58+
#[no_mangle]
59+
pub unsafe fn str_get_unchecked_mut_by_range(x: &mut str, r: Range<usize>) -> &mut str {
60+
// CHECK: sub nuw i64
61+
x.get_unchecked_mut(r)
62+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /