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<Idx: ?Sized> {
 
     /// 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 <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// 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> [T] {
     /// assert_eq!(&bytes, b"Hello, Wello!");
     /// ```
     #[stable(feature = "copy_within", since = "1.37.0")]
+    #[track_caller]
     pub fn copy_within<R: ops::RangeBounds<usize>>(&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<T: ?Sized>: 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<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]; });
 }