Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add #[track_caller] to panicking Vec functions #83359

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,15 @@ impl<T, A: Allocator> RawVec<T, A> {
/// Like `with_capacity`, but parameterized over the choice of
/// allocator for the returned `RawVec`.
#[inline]
#[track_caller]
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
}

/// Like `with_capacity_zeroed`, but parameterized over the choice
/// of allocator for the returned `RawVec`.
#[inline]
#[track_caller]
pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
Self::allocate_in(capacity, AllocInit::Zeroed, alloc)
}
Expand Down Expand Up @@ -183,6 +185,7 @@ impl<T, A: Allocator> RawVec<T, A> {
}
}

#[track_caller]
fn allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Self {
if mem::size_of::<T>() == 0 {
Self::new_in(alloc)
Expand Down Expand Up @@ -315,6 +318,7 @@ impl<T, A: Allocator> RawVec<T, A> {
/// # vector.push_all(&[1, 3, 5, 7, 9]);
/// # }
/// ```
#[track_caller]
pub fn reserve(&mut self, len: usize, additional: usize) {
handle_reserve(self.try_reserve(len, additional));
}
Expand Down Expand Up @@ -345,6 +349,7 @@ impl<T, A: Allocator> RawVec<T, A> {
/// # Aborts
///
/// Aborts on OOM.
#[track_caller]
pub fn reserve_exact(&mut self, len: usize, additional: usize) {
handle_reserve(self.try_reserve_exact(len, additional));
}
Expand All @@ -368,6 +373,7 @@ impl<T, A: Allocator> RawVec<T, A> {
/// # Aborts
///
/// Aborts on OOM.
#[track_caller]
pub fn shrink_to_fit(&mut self, amount: usize) {
handle_reserve(self.shrink(amount));
}
Expand Down Expand Up @@ -503,6 +509,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {

// Central function for reserve error handling.
#[inline]
#[track_caller]
fn handle_reserve(result: Result<(), TryReserveError>) {
match result {
Err(CapacityOverflow) => capacity_overflow(),
Expand Down Expand Up @@ -532,6 +539,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
// One central function responsible for reporting capacity overflows. This'll
// ensure that the code generation related to these panics is minimal as there's
// only one location which panics rather than a bunch throughout the module.
#[track_caller]
fn capacity_overflow() -> ! {
panic!("capacity overflow");
}
17 changes: 16 additions & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert!(vec.capacity() >= 11);
/// ```
#[doc(alias = "realloc")]
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve(&mut self, additional: usize) {
self.buf.reserve(self.len, additional);
Expand All @@ -793,6 +794,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert!(vec.capacity() >= 11);
/// ```
#[doc(alias = "realloc")]
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve_exact(&mut self, additional: usize) {
self.buf.reserve_exact(self.len, additional);
Expand Down Expand Up @@ -893,6 +895,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert!(vec.capacity() >= 3);
/// ```
#[doc(alias = "realloc")]
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn shrink_to_fit(&mut self) {
// The capacity is never less than the length, and there's nothing to do when
Expand Down Expand Up @@ -923,6 +926,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert!(vec.capacity() >= 3);
/// ```
#[doc(alias = "realloc")]
#[track_caller]
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
pub fn shrink_to(&mut self, min_capacity: usize) {
if self.capacity() > min_capacity {
Expand Down Expand Up @@ -954,6 +958,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// let slice = vec.into_boxed_slice();
/// assert_eq!(slice.into_vec().capacity(), 3);
/// ```
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_boxed_slice(mut self) -> Box<[T], A> {
unsafe {
Expand Down Expand Up @@ -1620,6 +1625,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert_eq!(vec, [1, 2, 3]);
/// ```
#[inline]
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push(&mut self, value: T) {
// This will panic or abort if we would allocate > isize::MAX bytes
Expand Down Expand Up @@ -1673,6 +1679,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert_eq!(vec2, []);
/// ```
#[inline]
#[track_caller]
#[stable(feature = "append", since = "1.4.0")]
pub fn append(&mut self, other: &mut Self) {
unsafe {
Expand All @@ -1683,6 +1690,7 @@ impl<T, A: Allocator> Vec<T, A> {

/// Appends elements to `Self` from other buffer.
#[inline]
#[track_caller]
unsafe fn append_elements(&mut self, other: *const [T]) {
let count = unsafe { (*other).len() };
self.reserve(count);
Expand Down Expand Up @@ -2106,6 +2114,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
/// ```
///
/// [`extend`]: Vec::extend
#[track_caller]
#[stable(feature = "vec_extend_from_slice", since = "1.6.0")]
pub fn extend_from_slice(&mut self, other: &[T]) {
self.spec_extend(other.iter())
Expand Down Expand Up @@ -2183,6 +2192,7 @@ impl<T, F: FnMut() -> T> ExtendWith<T> for ExtendFunc<F> {

impl<T, A: Allocator> Vec<T, A> {
/// Extend the vector by `n` values, using the given generator.
#[track_caller]
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
self.reserve(n);

Expand Down Expand Up @@ -2397,6 +2407,7 @@ impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> FromIterator<T> for Vec<T> {
#[inline]
#[track_caller]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> {
<Self as SpecFromIter<T, I::IntoIter>>::from_iter(iter.into_iter())
}
Expand Down Expand Up @@ -2485,6 +2496,7 @@ impl<T, A: Allocator> Extend<T> for Vec<T, A> {
impl<T, A: Allocator> Vec<T, A> {
// leaf method to which various SpecFrom/SpecExtend implementations delegate when
// they have no further optimizations to apply
#[track_caller]
fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
// This is the case for a general iterator.
//
Expand Down Expand Up @@ -2618,16 +2630,19 @@ impl<T, A: Allocator> Vec<T, A> {
/// [`copy_from_slice`]: slice::copy_from_slice
#[stable(feature = "extend_ref", since = "1.2.0")]
impl<'a, T: Copy + 'a, A: Allocator + 'a> Extend<&'a T> for Vec<T, A> {
#[track_caller]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.spec_extend(iter.into_iter())
}

#[inline]
#[track_caller]
fn extend_one(&mut self, &item: &'a T) {
self.push(item);
}

#[inline]
#[track_caller]
fn extend_reserve(&mut self, additional: usize) {
self.reserve(additional);
}
Expand Down Expand Up @@ -2792,7 +2807,7 @@ impl<T, A: Allocator, const N: usize> TryFrom<Vec<T, A>> for [T; N] {
/// # Examples
///
/// ```
/// use std::convert::TryInto;
/// use std::convert::TryInto;k
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unintentional.

/// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
/// assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
/// ```
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/vec/spec_extend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
where
I: Iterator<Item = T>,
{
#[track_caller]
default fn spec_extend(&mut self, iter: I) {
self.extend_desugared(iter)
}
Expand All @@ -23,6 +24,7 @@ impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
where
I: TrustedLen<Item = T>,
{
#[track_caller]
default fn spec_extend(&mut self, iterator: I) {
// This is the case for a TrustedLen iterator.
let (low, high) = iterator.size_hint();
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/vec/spec_from_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ where
}

impl<T> SpecFromIter<T, IntoIter<T>> for Vec<T> {
#[track_caller]
fn from_iter(iterator: IntoIter<T>) -> Self {
// A common case is passing a vector into a function which immediately
// re-collects into a vector. We can short circuit this if the IntoIter
Expand Down Expand Up @@ -71,6 +72,7 @@ where
I: Iterator<Item = &'a T>,
T: Clone,
{
#[track_caller]
default fn from_iter(iterator: I) -> Self {
SpecFromIter::from_iter(iterator.cloned())
}
Expand Down