|
1 | 1 | //! Indexing implementations for `[T]`.
|
2 | 2 |
|
| 3 | +use crate::intrinsics::assert_unsafe_precondition; |
3 | 4 | use crate::intrinsics::const_eval_select;
|
4 | 5 | use crate::intrinsics::unchecked_sub;
|
5 | 6 | use crate::ops;
|
6 |
| -use crate::panic::debug_assert_nounwind; |
7 | 7 | use crate::ptr;
|
8 | 8 |
|
9 | 9 | #[stable(feature = "rust1", since = "1.0.0")]
|
@@ -225,28 +225,36 @@ unsafe impl<T> SliceIndex<[T]> for usize {
|
225 | 225 |
|
226 | 226 | #[inline]
|
227 | 227 | unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
|
228 |
| - debug_assert_nounwind!( |
229 |
| - self < slice.len(), |
230 |
| - "slice::get_unchecked requires that the index is within the slice", |
231 |
| - ); |
232 | 228 | // SAFETY: the caller guarantees that `slice` is not dangling, so it
|
233 | 229 | // cannot be longer than `isize::MAX`. They also guarantee that
|
234 | 230 | // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
235 | 231 | // so the call to `add` is safe.
|
236 | 232 | unsafe {
|
237 |
| - crate::hint::assert_unchecked(self < slice.len()); |
| 233 | + assert_unsafe_precondition!( |
| 234 | + "slice::get_unchecked requires that the index is within the slice", |
| 235 | + ( |
| 236 | + this: usize = self, |
| 237 | + len: usize = slice.len() |
| 238 | + ) => this < len |
| 239 | + ); |
| 240 | + crate::intrinsics::assume(self < slice.len()); |
238 | 241 | slice.as_ptr().add(self)
|
239 | 242 | }
|
240 | 243 | }
|
241 | 244 |
|
242 | 245 | #[inline]
|
243 | 246 | unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
|
244 |
| - debug_assert_nounwind!( |
245 |
| - self < slice.len(), |
246 |
| - "slice::get_unchecked_mut requires that the index is within the slice", |
247 |
| - ); |
248 | 247 | // SAFETY: see comments for `get_unchecked` above.
|
249 |
| - unsafe { slice.as_mut_ptr().add(self) } |
| 248 | + unsafe { |
| 249 | + assert_unsafe_precondition!( |
| 250 | + "slice::get_unchecked_mut requires that the index is within the slice", |
| 251 | + ( |
| 252 | + this: usize = self, |
| 253 | + len: usize = slice.len() |
| 254 | + ) => this < len |
| 255 | + ); |
| 256 | + slice.as_mut_ptr().add(self) |
| 257 | + } |
250 | 258 | }
|
251 | 259 |
|
252 | 260 | #[inline]
|
@@ -290,25 +298,36 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
|
290 | 298 |
|
291 | 299 | #[inline]
|
292 | 300 | unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
|
293 |
| - debug_assert_nounwind!( |
294 |
| - self.end() <= slice.len(), |
295 |
| - "slice::get_unchecked requires that the index is within the slice" |
296 |
| - ); |
297 | 301 | // SAFETY: the caller guarantees that `slice` is not dangling, so it
|
298 | 302 | // cannot be longer than `isize::MAX`. They also guarantee that
|
299 | 303 | // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
300 | 304 | // so the call to `add` is safe.
|
301 |
| - unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len()) } |
| 305 | + unsafe { |
| 306 | + assert_unsafe_precondition!( |
| 307 | + "slice::get_unchecked requires that the index is within the slice", |
| 308 | + ( |
| 309 | + end: usize = self.end(), |
| 310 | + len: usize = slice.len() |
| 311 | + ) => end <= len |
| 312 | + ); |
| 313 | + ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len()) |
| 314 | + } |
302 | 315 | }
|
303 | 316 |
|
304 | 317 | #[inline]
|
305 | 318 | unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
|
306 |
| - debug_assert_nounwind!( |
307 |
| - self.end() <= slice.len(), |
308 |
| - "slice::get_unchecked_mut requires that the index is within the slice", |
309 |
| - ); |
310 | 319 | // SAFETY: see comments for `get_unchecked` above.
|
311 |
| - unsafe { ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len()) } |
| 320 | + unsafe { |
| 321 | + assert_unsafe_precondition!( |
| 322 | + "slice::get_unchecked_mut requires that the index is within the slice", |
| 323 | + ( |
| 324 | + end: usize = self.end(), |
| 325 | + len: usize = slice.len() |
| 326 | + ) => end <= len |
| 327 | + ); |
| 328 | + |
| 329 | + ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len()) |
| 330 | + } |
312 | 331 | }
|
313 | 332 |
|
314 | 333 | #[inline]
|
@@ -359,28 +378,36 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
|
359 | 378 |
|
360 | 379 | #[inline]
|
361 | 380 | unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
|
362 |
| - debug_assert_nounwind!( |
363 |
| - self.end >= self.start && self.end <= slice.len(), |
364 |
| - "slice::get_unchecked requires that the range is within the slice", |
365 |
| - ); |
366 | 381 | // SAFETY: the caller guarantees that `slice` is not dangling, so it
|
367 | 382 | // cannot be longer than `isize::MAX`. They also guarantee that
|
368 | 383 | // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
369 | 384 | // so the call to `add` is safe and the length calculation cannot overflow.
|
370 | 385 | unsafe {
|
| 386 | + assert_unsafe_precondition!( |
| 387 | + "slice::get_unchecked requires that the range is within the slice", |
| 388 | + ( |
| 389 | + end: usize = self.end, |
| 390 | + start: usize = self.start, |
| 391 | + len: usize = slice.len() |
| 392 | + ) => end >= start && end <= len |
| 393 | + ); |
371 | 394 | let new_len = unchecked_sub(self.end, self.start);
|
372 | 395 | ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len)
|
373 | 396 | }
|
374 | 397 | }
|
375 | 398 |
|
376 | 399 | #[inline]
|
377 | 400 | unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
|
378 |
| - debug_assert_nounwind!( |
379 |
| - self.end >= self.start && self.end <= slice.len(), |
380 |
| - "slice::get_unchecked_mut requires that the range is within the slice", |
381 |
| - ); |
382 | 401 | // SAFETY: see comments for `get_unchecked` above.
|
383 | 402 | unsafe {
|
| 403 | + assert_unsafe_precondition!( |
| 404 | + "slice::get_unchecked_mut requires that the range is within the slice", |
| 405 | + ( |
| 406 | + end: usize = self.end, |
| 407 | + start: usize = self.start, |
| 408 | + len: usize = slice.len() |
| 409 | + ) => end >= start && end <= len |
| 410 | + ); |
384 | 411 | let new_len = unchecked_sub(self.end, self.start);
|
385 | 412 | ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
|
386 | 413 | }
|
|
0 commit comments