|
1 | 1 | //! Trait implementations for `str`.
|
2 | 2 |
|
3 | 3 | use crate::cmp::Ordering;
|
| 4 | +use crate::intrinsics::assert_unsafe_precondition; |
4 | 5 | use crate::ops;
|
5 | 6 | use crate::ptr;
|
6 | 7 | use crate::slice::SliceIndex;
|
@@ -198,15 +199,31 @@ unsafe impl const SliceIndex<str> for ops::Range<usize> {
|
198 | 199 | let slice = slice as *const [u8];
|
199 | 200 | // SAFETY: the caller guarantees that `self` is in bounds of `slice`
|
200 | 201 | // which satisfies all the conditions for `add`.
|
201 |
| - let ptr = unsafe { slice.as_ptr().add(self.start) }; |
| 202 | + let ptr = unsafe { |
| 203 | + let this = ops::Range { ..self }; |
| 204 | + assert_unsafe_precondition!( |
| 205 | + "str::get_unchecked requires that the range is within the string slice", |
| 206 | + (this: ops::Range<usize>, slice: *const [u8]) => |
| 207 | + this.end >= this.start && this.end <= slice.len() |
| 208 | + ); |
| 209 | + slice.as_ptr().add(self.start) |
| 210 | + }; |
202 | 211 | let len = self.end - self.start;
|
203 | 212 | ptr::slice_from_raw_parts(ptr, len) as *const str
|
204 | 213 | }
|
205 | 214 | #[inline]
|
206 | 215 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
|
207 | 216 | let slice = slice as *mut [u8];
|
208 | 217 | // SAFETY: see comments for `get_unchecked`.
|
209 |
| - let ptr = unsafe { slice.as_mut_ptr().add(self.start) }; |
| 218 | + let ptr = unsafe { |
| 219 | + let this = ops::Range { ..self }; |
| 220 | + assert_unsafe_precondition!( |
| 221 | + "str::get_unchecked_mut requires that the range is within the string slice", |
| 222 | + (this: ops::Range<usize>, slice: *mut [u8]) => |
| 223 | + this.end >= this.start && this.end <= slice.len() |
| 224 | + ); |
| 225 | + slice.as_mut_ptr().add(self.start) |
| 226 | + }; |
210 | 227 | let len = self.end - self.start;
|
211 | 228 | ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
|
212 | 229 | }
|
@@ -276,15 +293,13 @@ unsafe impl const SliceIndex<str> for ops::RangeTo<usize> {
|
276 | 293 | }
|
277 | 294 | #[inline]
|
278 | 295 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
|
279 |
| - let slice = slice as *const [u8]; |
280 |
| - let ptr = slice.as_ptr(); |
281 |
| - ptr::slice_from_raw_parts(ptr, self.end) as *const str |
| 296 | + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
| 297 | + unsafe { (0..self.end).get_unchecked(slice) } |
282 | 298 | }
|
283 | 299 | #[inline]
|
284 | 300 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
|
285 |
| - let slice = slice as *mut [u8]; |
286 |
| - let ptr = slice.as_mut_ptr(); |
287 |
| - ptr::slice_from_raw_parts_mut(ptr, self.end) as *mut str |
| 301 | + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
| 302 | + unsafe { (0..self.end).get_unchecked_mut(slice) } |
288 | 303 | }
|
289 | 304 | #[inline]
|
290 | 305 | fn index(self, slice: &str) -> &Self::Output {
|
@@ -347,20 +362,15 @@ unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> {
|
347 | 362 | }
|
348 | 363 | #[inline]
|
349 | 364 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
|
350 |
| - let slice = slice as *const [u8]; |
351 |
| - // SAFETY: the caller guarantees that `self` is in bounds of `slice` |
352 |
| - // which satisfies all the conditions for `add`. |
353 |
| - let ptr = unsafe { slice.as_ptr().add(self.start) }; |
354 |
| - let len = slice.len() - self.start; |
355 |
| - ptr::slice_from_raw_parts(ptr, len) as *const str |
| 365 | + let len = (slice as *const [u8]).len(); |
| 366 | + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. |
| 367 | + unsafe { (self.start..len).get_unchecked(slice) } |
356 | 368 | }
|
357 | 369 | #[inline]
|
358 | 370 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
|
359 |
| - let slice = slice as *mut [u8]; |
360 |
| - // SAFETY: identical to `get_unchecked`. |
361 |
| - let ptr = unsafe { slice.as_mut_ptr().add(self.start) }; |
362 |
| - let len = slice.len() - self.start; |
363 |
| - ptr::slice_from_raw_parts_mut(ptr, len) as *mut str |
| 371 | + let len = (slice as *mut [u8]).len(); |
| 372 | + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. |
| 373 | + unsafe { (self.start..len).get_unchecked_mut(slice) } |
364 | 374 | }
|
365 | 375 | #[inline]
|
366 | 376 | fn index(self, slice: &str) -> &Self::Output {
|
@@ -456,35 +466,29 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
|
456 | 466 | type Output = str;
|
457 | 467 | #[inline]
|
458 | 468 | fn get(self, slice: &str) -> Option<&Self::Output> {
|
459 |
| - if self.end == usize::MAX { None } else { (..self.end + 1).get(slice) } |
| 469 | + (0..=self.end).get(slice) |
460 | 470 | }
|
461 | 471 | #[inline]
|
462 | 472 | fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
|
463 |
| - if self.end == usize::MAX { None } else { (..self.end + 1).get_mut(slice) } |
| 473 | + (0..=self.end).get_mut(slice) |
464 | 474 | }
|
465 | 475 | #[inline]
|
466 | 476 | unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
|
467 | 477 | // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
|
468 |
| - unsafe { (..self.end + 1).get_unchecked(slice) } |
| 478 | + unsafe { (0..=self.end).get_unchecked(slice) } |
469 | 479 | }
|
470 | 480 | #[inline]
|
471 | 481 | unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
|
472 | 482 | // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
|
473 |
| - unsafe { (..self.end + 1).get_unchecked_mut(slice) } |
| 483 | + unsafe { (0..=self.end).get_unchecked_mut(slice) } |
474 | 484 | }
|
475 | 485 | #[inline]
|
476 | 486 | fn index(self, slice: &str) -> &Self::Output {
|
477 |
| - if self.end == usize::MAX { |
478 |
| - str_index_overflow_fail(); |
479 |
| - } |
480 |
| - (..self.end + 1).index(slice) |
| 487 | + (0..=self.end).index(slice) |
481 | 488 | }
|
482 | 489 | #[inline]
|
483 | 490 | fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
484 |
| - if self.end == usize::MAX { |
485 |
| - str_index_overflow_fail(); |
486 |
| - } |
487 |
| - (..self.end + 1).index_mut(slice) |
| 491 | + (0..=self.end).index_mut(slice) |
488 | 492 | }
|
489 | 493 | }
|
490 | 494 |
|
|
0 commit comments