Skip to content

Commit 4891c00

Browse files
committed
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
2 parents 2ba4460 + 5c873be commit 4891c00

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/libcore/slice.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -566,14 +566,29 @@ impl<T> ops::IndexMut<usize> for [T] {
566566
}
567567
}
568568

569+
#[inline(never)]
570+
#[cold]
571+
fn slice_index_len_fail(index: usize, len: usize) -> ! {
572+
panic!("index {} out of range for slice of length {}", index, len);
573+
}
574+
575+
#[inline(never)]
576+
#[cold]
577+
fn slice_index_order_fail(index: usize, end: usize) -> ! {
578+
panic!("slice index starts at {} but ends at {}", index, end);
579+
}
580+
569581
#[stable(feature = "rust1", since = "1.0.0")]
570582
impl<T> ops::Index<ops::Range<usize>> for [T] {
571583
type Output = [T];
572584

573585
#[inline]
574586
fn index(&self, index: ops::Range<usize>) -> &[T] {
575-
assert!(index.start <= index.end);
576-
assert!(index.end <= self.len());
587+
if index.start > index.end {
588+
slice_index_order_fail(index.start, index.end);
589+
} else if index.end > self.len() {
590+
slice_index_len_fail(index.end, self.len());
591+
}
577592
unsafe {
578593
from_raw_parts (
579594
self.as_ptr().offset(index.start as isize),
@@ -614,8 +629,11 @@ impl<T> ops::Index<RangeFull> for [T] {
614629
impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
615630
#[inline]
616631
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
617-
assert!(index.start <= index.end);
618-
assert!(index.end <= self.len());
632+
if index.start > index.end {
633+
slice_index_order_fail(index.start, index.end);
634+
} else if index.end > self.len() {
635+
slice_index_len_fail(index.end, self.len());
636+
}
619637
unsafe {
620638
from_raw_parts_mut(
621639
self.as_mut_ptr().offset(index.start as isize),

src/libcore/str/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,7 @@ pub trait StrExt {
14411441
}
14421442

14431443
#[inline(never)]
1444+
#[cold]
14441445
fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
14451446
assert!(begin <= end);
14461447
panic!("index {} and/or {} in `{}` do not lie on character boundary",

0 commit comments

Comments
 (0)