#[track_caller] on core::ops::{Index, IndexMut}.

This commit is contained in:
Adam Perry 2020-03-22 18:21:09 -07:00
parent 5aa8f199c3
commit a7ab7b136e
4 changed files with 32 additions and 0 deletions

View File

@ -65,6 +65,7 @@ pub trait Index<Idx: ?Sized> {
/// Performs the indexing (`container[index]`) operation. /// Performs the indexing (`container[index]`) operation.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index(&self, index: Idx) -> &Self::Output; fn index(&self, index: Idx) -> &Self::Output;
} }
@ -166,5 +167,6 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
pub trait IndexMut<Idx: ?Sized>: Index<Idx> { pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
/// Performs the mutable indexing (`container[index]`) operation. /// Performs the mutable indexing (`container[index]`) operation.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index_mut(&mut self, index: Idx) -> &mut Self::Output; fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
} }

View File

@ -2306,6 +2306,7 @@ impl<T> [T] {
/// assert_eq!(&bytes, b"Hello, Wello!"); /// assert_eq!(&bytes, b"Hello, Wello!");
/// ``` /// ```
#[stable(feature = "copy_within", since = "1.37.0")] #[stable(feature = "copy_within", since = "1.37.0")]
#[track_caller]
pub fn copy_within<R: ops::RangeBounds<usize>>(&mut self, src: R, dest: usize) pub fn copy_within<R: ops::RangeBounds<usize>>(&mut self, src: R, dest: usize)
where where
T: Copy, T: Copy,
@ -2721,18 +2722,21 @@ where
#[inline(never)] #[inline(never)]
#[cold] #[cold]
#[track_caller]
fn slice_index_len_fail(index: usize, len: usize) -> ! { fn slice_index_len_fail(index: usize, len: usize) -> ! {
panic!("index {} out of range for slice of length {}", index, len); panic!("index {} out of range for slice of length {}", index, len);
} }
#[inline(never)] #[inline(never)]
#[cold] #[cold]
#[track_caller]
fn slice_index_order_fail(index: usize, end: usize) -> ! { fn slice_index_order_fail(index: usize, end: usize) -> ! {
panic!("slice index starts at {} but ends at {}", index, end); panic!("slice index starts at {} but ends at {}", index, end);
} }
#[inline(never)] #[inline(never)]
#[cold] #[cold]
#[track_caller]
fn slice_index_overflow_fail() -> ! { fn slice_index_overflow_fail() -> ! {
panic!("attempted to index slice up to maximum usize"); panic!("attempted to index slice up to maximum usize");
} }
@ -2804,11 +2808,13 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// Returns a shared reference to the output at this location, panicking /// Returns a shared reference to the output at this location, panicking
/// if out of bounds. /// if out of bounds.
#[unstable(feature = "slice_index_methods", issue = "none")] #[unstable(feature = "slice_index_methods", issue = "none")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index(self, slice: &T) -> &Self::Output; fn index(self, slice: &T) -> &Self::Output;
/// Returns a mutable reference to the output at this location, panicking /// Returns a mutable reference to the output at this location, panicking
/// if out of bounds. /// if out of bounds.
#[unstable(feature = "slice_index_methods", issue = "none")] #[unstable(feature = "slice_index_methods", issue = "none")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index_mut(self, slice: &mut T) -> &mut Self::Output; fn index_mut(self, slice: &mut T) -> &mut Self::Output;
} }

View File

@ -1794,6 +1794,7 @@ mod traits {
#[inline(never)] #[inline(never)]
#[cold] #[cold]
#[track_caller]
fn str_index_overflow_fail() -> ! { fn str_index_overflow_fail() -> ! {
panic!("attempted to index str up to maximum usize"); panic!("attempted to index str up to maximum usize");
} }
@ -2185,6 +2186,7 @@ fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {
#[inline(never)] #[inline(never)]
#[cold] #[cold]
#[track_caller]
fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
const MAX_DISPLAY_LENGTH: usize = 256; const MAX_DISPLAY_LENGTH: usize = 256;
let (truncated, s_trunc) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH); let (truncated, s_trunc) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH);

View File

@ -2,10 +2,14 @@
// ignore-wasm32-bare compiled with panic=abort by default // ignore-wasm32-bare compiled with panic=abort by default
#![feature(option_expect_none, option_unwrap_none)] #![feature(option_expect_none, option_unwrap_none)]
#![allow(unconditional_panic)]
//! Test that panic locations for `#[track_caller]` functions in std have the correct //! Test that panic locations for `#[track_caller]` functions in std have the correct
//! location reported. //! location reported.
use std::collections::{BTreeMap, HashMap, VecDeque};
use std::ops::{Index, IndexMut};
fn main() { fn main() {
// inspect the `PanicInfo` we receive to ensure the right file is the source // inspect the `PanicInfo` we receive to ensure the right file is the source
std::panic::set_hook(Box::new(|info| { std::panic::set_hook(Box::new(|info| {
@ -35,4 +39,22 @@ fn main() {
let fine: Result<(), ()> = Ok(()); let fine: Result<(), ()> = Ok(());
assert_panicked(|| fine.unwrap_err()); assert_panicked(|| fine.unwrap_err());
assert_panicked(|| fine.expect_err("")); assert_panicked(|| fine.expect_err(""));
let mut small = [0]; // the implementation backing str, vec, etc
assert_panicked(move || { small.index(1); });
assert_panicked(move || { small[1]; });
assert_panicked(move || { small.index_mut(1); });
assert_panicked(move || { small[1] += 1; });
let sorted: BTreeMap<bool, bool> = Default::default();
assert_panicked(|| { sorted.index(&false); });
assert_panicked(|| { sorted[&false]; });
let unsorted: HashMap<bool, bool> = Default::default();
assert_panicked(|| { unsorted.index(&false); });
assert_panicked(|| { unsorted[&false]; });
let weirdo: VecDeque<()> = Default::default();
assert_panicked(|| { weirdo.index(1); });
assert_panicked(|| { weirdo[1]; });
} }