|
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