diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index aae0691122415..64dd633f75d2b 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -65,6 +65,7 @@ pub trait Index { /// Performs the indexing (`container[index]`) operation. #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), track_caller)] fn index(&self, index: Idx) -> &Self::Output; } @@ -166,5 +167,6 @@ see chapter in The Book : Index { /// Performs the mutable indexing (`container[index]`) operation. #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(not(bootstrap), track_caller)] fn index_mut(&mut self, index: Idx) -> &mut Self::Output; } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 0e12e6360da95..2140a7be9efe8 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2306,6 +2306,7 @@ impl [T] { /// assert_eq!(&bytes, b"Hello, Wello!"); /// ``` #[stable(feature = "copy_within", since = "1.37.0")] + #[track_caller] pub fn copy_within>(&mut self, src: R, dest: usize) where T: Copy, @@ -2721,18 +2722,21 @@ where #[inline(never)] #[cold] +#[track_caller] fn slice_index_len_fail(index: usize, len: usize) -> ! { panic!("index {} out of range for slice of length {}", index, len); } #[inline(never)] #[cold] +#[track_caller] fn slice_index_order_fail(index: usize, end: usize) -> ! { panic!("slice index starts at {} but ends at {}", index, end); } #[inline(never)] #[cold] +#[track_caller] fn slice_index_overflow_fail() -> ! { panic!("attempted to index slice up to maximum usize"); } @@ -2804,11 +2808,13 @@ pub trait SliceIndex: private_slice_index::Sealed { /// Returns a shared reference to the output at this location, panicking /// if out of bounds. #[unstable(feature = "slice_index_methods", issue = "none")] + #[cfg_attr(not(bootstrap), track_caller)] fn index(self, slice: &T) -> &Self::Output; /// Returns a mutable reference to the output at this location, panicking /// if out of bounds. #[unstable(feature = "slice_index_methods", issue = "none")] + #[cfg_attr(not(bootstrap), track_caller)] fn index_mut(self, slice: &mut T) -> &mut Self::Output; } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 6ad0e68a88f3b..013ca182c13cd 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1794,6 +1794,7 @@ mod traits { #[inline(never)] #[cold] + #[track_caller] fn str_index_overflow_fail() -> ! { 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)] #[cold] +#[track_caller] fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { const MAX_DISPLAY_LENGTH: usize = 256; let (truncated, s_trunc) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH); diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index be13076b8af52..35a2956ee26b8 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -2,10 +2,14 @@ // ignore-wasm32-bare compiled with panic=abort by default #![feature(option_expect_none, option_unwrap_none)] +#![allow(unconditional_panic)] //! Test that panic locations for `#[track_caller]` functions in std have the correct //! location reported. +use std::collections::{BTreeMap, HashMap, VecDeque}; +use std::ops::{Index, IndexMut}; + fn main() { // inspect the `PanicInfo` we receive to ensure the right file is the source std::panic::set_hook(Box::new(|info| { @@ -35,4 +39,22 @@ fn main() { let fine: Result<(), ()> = Ok(()); assert_panicked(|| fine.unwrap_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 = Default::default(); + assert_panicked(|| { sorted.index(&false); }); + assert_panicked(|| { sorted[&false]; }); + + let unsorted: HashMap = 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]; }); }