diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2018-05-10 11:35:17 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-10 11:35:17 -0500 |
| commit | cff1a263c9e7744df286d2518e0c6ca3191dc681 (patch) | |
| tree | 2d39f779a1fba6ca894db351eac6242edae37f92 /src/libcore/slice | |
| parent | ecd9898b60b601f69113c64b77650a09d7678edf (diff) | |
| parent | f1d7b453fed6acefc68f90752922b37c6e3ac7a4 (diff) | |
| download | rust-cff1a263c9e7744df286d2518e0c6ca3191dc681.tar.gz rust-cff1a263c9e7744df286d2518e0c6ca3191dc681.zip | |
Rollup merge of #50010 - ExpHP:slice-bounds, r=alexcrichton
Give SliceIndex impls a test suite of girth befitting the implementation (and fix a UTF8 boundary check)
So one day I was writing something in my codebase that basically amounted to `impl SliceIndex for (Bound<usize>, Bound<usize>)`, and I said to myself:
*Boy, gee, golly! I never realized bounds checking was so tricky!*
At some point when I had around 60 lines of tests for it, I decided to go see how the standard library does it to see if I missed any edge cases. ...That's when I discovered that libcore only had about 40 lines of tests for slicing altogether, and none of them even used `..=`.
---
This PR includes:
* **Literally the first appearance of the word `get_unchecked_mut` in any directory named `test` or `tests`.**
* Likewise the first appearance of `get_mut` used with _any type of range argument_ in these directories.
* Tests for the panics on overflow with `..=`.
* I wanted to test on `[(); usize::MAX]` as well but that takes linear time in debug mode </3
* A horrible and ugly test-generating macro for the `should_panic` tests that increases the DRYness by a single order of magnitude (which IMO wasn't enough, but I didn't want to go any further and risk making the tests inaccessible to next guy).
* Same stuff for str!
* Actually, the existing `str` tests were pretty good. I just helped filled in the holes.
* [A fix for the bug it caught](https://github.com/rust-lang/rust/issues/50002). (only one ~~sadly~~)
Diffstat (limited to 'src/libcore/slice')
| -rw-r--r-- | src/libcore/slice/mod.rs | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 83e8a6e4b68..93ebc23ac0b 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2262,6 +2262,12 @@ fn slice_index_order_fail(index: usize, end: usize) -> ! { panic!("slice index starts at {} but ends at {}", index, end); } +#[inline(never)] +#[cold] +fn slice_index_overflow_fail() -> ! { + panic!("attempted to index slice up to maximum usize"); +} + /// A helper trait used for indexing operations. #[unstable(feature = "slice_get_slice", issue = "35729")] #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] @@ -2538,15 +2544,13 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> { #[inline] fn index(self, slice: &[T]) -> &[T] { - assert!(self.end != usize::max_value(), - "attempted to index slice up to maximum usize"); + if self.end == usize::max_value() { slice_index_overflow_fail(); } (self.start..self.end + 1).index(slice) } #[inline] fn index_mut(self, slice: &mut [T]) -> &mut [T] { - assert!(self.end != usize::max_value(), - "attempted to index slice up to maximum usize"); + if self.end == usize::max_value() { slice_index_overflow_fail(); } (self.start..self.end + 1).index_mut(slice) } } |
