mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #70234 - anp:tracked-std-traits, r=Amanieu
#[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 #69251 to allow separate assessment of perf impact. To my knowledge, this is the last piece of implementing RFC 2091. Tracking issue: https://github.com/rust-lang/rust/issues/47809
This commit is contained in:
commit
50d2f302cb
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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]; });
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user