diff options
| author | bors <bors@rust-lang.org> | 2015-11-23 06:27:49 +0000 | 
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-11-23 06:27:49 +0000 | 
| commit | 4891c00634f209bcc66d7f00bc507eb35a0fe6a8 (patch) | |
| tree | d6ff03ef233fcb1015438ce74358b2a5a0500d90 | |
| parent | 2ba44607fe09c4fb98a52ca2149b0c9869a87b4c (diff) | |
| parent | 5c873be9c323f15f102720fe9085e2c4e982bb6d (diff) | |
| download | rust-4891c00634f209bcc66d7f00bc507eb35a0fe6a8.tar.gz rust-4891c00634f209bcc66d7f00bc507eb35a0fe6a8.zip | |
Auto merge of #29984 - Manishearth:slice-assert, r=alexcrichton
I'd like to have the message print out the index and length values like it does elsewhere, but I'm not sure how to do that without affecting perf here. Will `assert!(cond, "index out of bounds got {} but len is ", idx, len)` make things slower? It calls `panic_fmt` which is marked as cold but also calls `format_args!`, and I don't know if that allocates or does any heavy lifting.
cc @alexcrichton @Gankro
| -rw-r--r-- | src/libcore/slice.rs | 26 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 1 | 
2 files changed, 23 insertions, 4 deletions
| diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index efb782fece8..890ca43580b 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -566,14 +566,29 @@ impl<T> ops::IndexMut<usize> for [T] { } } +#[inline(never)] +#[cold] +fn slice_index_len_fail(index: usize, len: usize) -> ! { + panic!("index {} out of range for slice of length {}", index, len); +} + +#[inline(never)] +#[cold] +fn slice_index_order_fail(index: usize, end: usize) -> ! { + panic!("slice index starts at {} but ends at {}", index, end); +} + #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::Index<ops::Range<usize>> for [T] { type Output = [T]; #[inline] fn index(&self, index: ops::Range<usize>) -> &[T] { - assert!(index.start <= index.end); - assert!(index.end <= self.len()); + if index.start > index.end { + slice_index_order_fail(index.start, index.end); + } else if index.end > self.len() { + slice_index_len_fail(index.end, self.len()); + } unsafe { from_raw_parts ( self.as_ptr().offset(index.start as isize), @@ -614,8 +629,11 @@ impl<T> ops::Index<RangeFull> for [T] { impl<T> ops::IndexMut<ops::Range<usize>> for [T] { #[inline] fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] { - assert!(index.start <= index.end); - assert!(index.end <= self.len()); + if index.start > index.end { + slice_index_order_fail(index.start, index.end); + } else if index.end > self.len() { + slice_index_len_fail(index.end, self.len()); + } unsafe { from_raw_parts_mut( self.as_mut_ptr().offset(index.start as isize), diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index c246b310543..c620bec54a2 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1441,6 +1441,7 @@ pub trait StrExt { } #[inline(never)] +#[cold] fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { assert!(begin <= end); panic!("index {} and/or {} in `{}` do not lie on character boundary", | 
