Use unchecked_sub in str indexing

This commit is contained in:
Ben Kimock 2024-04-06 11:33:09 -04:00
parent 83d0a940c6
commit 712aab72df
2 changed files with 37 additions and 6 deletions

View File

@ -1,6 +1,7 @@
//! Trait implementations for `str`. //! Trait implementations for `str`.
use crate::cmp::Ordering; use crate::cmp::Ordering;
use crate::intrinsics::unchecked_sub;
use crate::ops; use crate::ops;
use crate::ptr; use crate::ptr;
use crate::slice::SliceIndex; use crate::slice::SliceIndex;
@ -210,9 +211,10 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
// SAFETY: the caller guarantees that `self` is in bounds of `slice` // SAFETY: the caller guarantees that `self` is in bounds of `slice`
// which satisfies all the conditions for `add`. // which satisfies all the conditions for `add`.
let ptr = unsafe { slice.as_ptr().add(self.start) }; unsafe {
let len = self.end - self.start; let new_len = unchecked_sub(self.end, self.start);
ptr::slice_from_raw_parts(ptr, len) as *const str ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str
}
} }
#[inline] #[inline]
unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
@ -229,9 +231,10 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
); );
// SAFETY: see comments for `get_unchecked`. // SAFETY: see comments for `get_unchecked`.
let ptr = unsafe { slice.as_mut_ptr().add(self.start) }; unsafe {
let len = self.end - self.start; let new_len = unchecked_sub(self.end, self.start);
ptr::slice_from_raw_parts_mut(ptr, len) as *mut str ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str
}
} }
#[inline] #[inline]
fn index(self, slice: &str) -> &Self::Output { fn index(self, slice: &str) -> &Self::Output {

View File

@ -32,3 +32,31 @@ pub unsafe fn get_unchecked_mut_by_range(x: &mut [i32], r: Range<usize>) -> &mut
// CHECK: sub nuw i64 // CHECK: sub nuw i64
x.get_unchecked_mut(r) x.get_unchecked_mut(r)
} }
// CHECK-LABEL: @str_index_by_range(
#[no_mangle]
pub fn str_index_by_range(x: &str, r: Range<usize>) -> &str {
// CHECK: sub nuw i64
&x[r]
}
// CHECK-LABEL: @str_get_unchecked_by_range(
#[no_mangle]
pub unsafe fn str_get_unchecked_by_range(x: &str, r: Range<usize>) -> &str {
// CHECK: sub nuw i64
x.get_unchecked(r)
}
// CHECK-LABEL: @str_index_mut_by_range(
#[no_mangle]
pub fn str_index_mut_by_range(x: &mut str, r: Range<usize>) -> &mut str {
// CHECK: sub nuw i64
&mut x[r]
}
// CHECK-LABEL: @str_get_unchecked_mut_by_range(
#[no_mangle]
pub unsafe fn str_get_unchecked_mut_by_range(x: &mut str, r: Range<usize>) -> &mut str {
// CHECK: sub nuw i64
x.get_unchecked_mut(r)
}