|
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