about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-11-23 06:27:49 +0000
committerbors <bors@rust-lang.org>2015-11-23 06:27:49 +0000
commit4891c00634f209bcc66d7f00bc507eb35a0fe6a8 (patch)
treed6ff03ef233fcb1015438ce74358b2a5a0500d90
parent2ba44607fe09c4fb98a52ca2149b0c9869a87b4c (diff)
parent5c873be9c323f15f102720fe9085e2c4e982bb6d (diff)
downloadrust-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.rs26
-rw-r--r--src/libcore/str/mod.rs1
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",