Skip to content

Commit

Permalink
Rollup merge of rust-lang#70234 - anp:tracked-std-traits, r=Amanieu
Browse files Browse the repository at this point in the history
#[track_caller] on core::ops::{Index, IndexMut}.

Applies the attribute to `core::ops::Index(Mut)` and enough std internals to cover the [functions listed in "tier 1" in the original RFC](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md#survey-of-panicking-standard-functions).

Split out from rust-lang#69251 to allow separate assessment of perf impact.

To my knowledge, this is the last piece of implementing RFC 2091.

Tracking issue: rust-lang#47809
  • Loading branch information
Centril authored Mar 24, 2020
2 parents 89feaf6 + a7ab7b1 commit 50d2f30
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/libcore/ops/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/rfc-2091-track-caller/std-panic-locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down Expand Up @@ -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]; });
}

0 comments on commit 50d2f30

Please sign in to comment.