Skip to content

Commit f6648f2

Browse files
committed
Auto merge of #126557 - GrigorenkoPV:vec_track_caller, r=joboet
Add `#[track_caller]` to allocating methods of `Vec` & `VecDeque` Part 4 in a lengthy saga. r? `@joshtriplett` because they were the reviewer the last 3 times. `@bors` rollup=never "[just in case this has perf effects, Vec is hot](#79323 (comment))" This was first attempted in #79323 by `@nvzqz.` It got approval from `@joshtriplett,` but rotted with merge conflicts and got closed. Then it got picked up by `@Dylan-DPC-zz` in #83359. A benchmark was run[^perf], the results (after a bit of thinking[^thinking]) were deemed ok[^ok], but there was a typo[^typo] and the PR was made from a wrong remote in the first place[^remote], so #83909 was opened instead. By the time #83909 rolled around, the methods in question had received some optimizations[^optimizations], so another perf run was conducted[^perf2]. The results were ok[^ok2]. There was a suggestion to add regression tests for panic behavior [^tests], but before it could be addressed, the PR fell victim to merge conflicts[^conflicts] and died again[^rip]. 3 years have passed, and (from what I can tell) this has not been tried again, so here I am now, reviving this old effort. Given how much time has passed and the fact that I've also touched `VecDeque` this time, it probably makes sense to `@bors` try `@rust-timer` [^perf]: #83359 (comment) [^thinking]: #83359 (comment) [^ok]: #83359 (comment) [^typo]: #83359 (comment) [^remote]: #83359 (comment) [^optimizations]: #83909 (comment) [^perf2]: #83909 (comment) [^ok2]: #83909 (comment) [^tests]: #83909 (comment) [^conflicts]: #83909 (comment) [^rip]: #83909 (comment)
2 parents 5ceb623 + 683ef60 commit f6648f2

14 files changed

+107
-3
lines changed

library/alloc/src/collections/vec_deque/mod.rs

+24
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ pub struct VecDeque<
103103

104104
#[stable(feature = "rust1", since = "1.0.0")]
105105
impl<T: Clone, A: Allocator + Clone> Clone for VecDeque<T, A> {
106+
#[track_caller]
106107
fn clone(&self) -> Self {
107108
let mut deq = Self::with_capacity_in(self.len(), self.allocator().clone());
108109
deq.extend(self.iter().cloned());
@@ -113,6 +114,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for VecDeque<T, A> {
113114
///
114115
/// This method is preferred over simply assigning `source.clone()` to `self`,
115116
/// as it avoids reallocation if possible.
117+
#[track_caller]
116118
fn clone_from(&mut self, source: &Self) {
117119
self.clear();
118120
self.extend(source.iter().cloned());
@@ -570,6 +572,7 @@ impl<T> VecDeque<T> {
570572
#[inline]
571573
#[stable(feature = "rust1", since = "1.0.0")]
572574
#[must_use]
575+
#[track_caller]
573576
pub fn with_capacity(capacity: usize) -> VecDeque<T> {
574577
Self::with_capacity_in(capacity, Global)
575578
}
@@ -625,6 +628,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
625628
/// let deque: VecDeque<u32> = VecDeque::with_capacity(10);
626629
/// ```
627630
#[unstable(feature = "allocator_api", issue = "32838")]
631+
#[track_caller]
628632
pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque<T, A> {
629633
VecDeque { head: 0, len: 0, buf: RawVec::with_capacity_in(capacity, alloc) }
630634
}
@@ -789,6 +793,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
789793
///
790794
/// [`reserve`]: VecDeque::reserve
791795
#[stable(feature = "rust1", since = "1.0.0")]
796+
#[track_caller]
792797
pub fn reserve_exact(&mut self, additional: usize) {
793798
let new_cap = self.len.checked_add(additional).expect("capacity overflow");
794799
let old_cap = self.capacity();
@@ -818,6 +823,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
818823
/// assert!(buf.capacity() >= 11);
819824
/// ```
820825
#[stable(feature = "rust1", since = "1.0.0")]
826+
#[track_caller]
821827
pub fn reserve(&mut self, additional: usize) {
822828
let new_cap = self.len.checked_add(additional).expect("capacity overflow");
823829
let old_cap = self.capacity();
@@ -949,6 +955,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
949955
/// assert!(buf.capacity() >= 4);
950956
/// ```
951957
#[stable(feature = "deque_extras_15", since = "1.5.0")]
958+
#[track_caller]
952959
pub fn shrink_to_fit(&mut self) {
953960
self.shrink_to(0);
954961
}
@@ -974,6 +981,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
974981
/// assert!(buf.capacity() >= 4);
975982
/// ```
976983
#[stable(feature = "shrink_to", since = "1.56.0")]
984+
#[track_caller]
977985
pub fn shrink_to(&mut self, min_capacity: usize) {
978986
let target_cap = min_capacity.max(self.len);
979987

@@ -1740,6 +1748,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
17401748
/// assert_eq!(d.front(), Some(&2));
17411749
/// ```
17421750
#[stable(feature = "rust1", since = "1.0.0")]
1751+
#[track_caller]
17431752
pub fn push_front(&mut self, value: T) {
17441753
if self.is_full() {
17451754
self.grow();
@@ -1767,6 +1776,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
17671776
/// ```
17681777
#[stable(feature = "rust1", since = "1.0.0")]
17691778
#[rustc_confusables("push", "put", "append")]
1779+
#[track_caller]
17701780
pub fn push_back(&mut self, value: T) {
17711781
if self.is_full() {
17721782
self.grow();
@@ -1876,6 +1886,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
18761886
/// assert_eq!(vec_deque, &['a', 'd', 'b', 'c']);
18771887
/// ```
18781888
#[stable(feature = "deque_extras_15", since = "1.5.0")]
1889+
#[track_caller]
18791890
pub fn insert(&mut self, index: usize, value: T) {
18801891
assert!(index <= self.len(), "index out of bounds");
18811892
if self.is_full() {
@@ -1979,6 +1990,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
19791990
#[inline]
19801991
#[must_use = "use `.truncate()` if you don't need the other half"]
19811992
#[stable(feature = "split_off", since = "1.4.0")]
1993+
#[track_caller]
19821994
pub fn split_off(&mut self, at: usize) -> Self
19831995
where
19841996
A: Clone,
@@ -2045,6 +2057,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
20452057
/// ```
20462058
#[inline]
20472059
#[stable(feature = "append", since = "1.4.0")]
2060+
#[track_caller]
20482061
pub fn append(&mut self, other: &mut Self) {
20492062
if T::IS_ZST {
20502063
self.len = self.len.checked_add(other.len).expect("capacity overflow");
@@ -2167,6 +2180,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
21672180
// be called in cold paths.
21682181
// This may panic or abort
21692182
#[inline(never)]
2183+
#[track_caller]
21702184
fn grow(&mut self) {
21712185
// Extend or possibly remove this assertion when valid use-cases for growing the
21722186
// buffer without it being full emerge
@@ -2205,6 +2219,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
22052219
/// assert_eq!(buf, [5, 10, 101, 102, 103]);
22062220
/// ```
22072221
#[stable(feature = "vec_resize_with", since = "1.33.0")]
2222+
#[track_caller]
22082223
pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut() -> T) {
22092224
let len = self.len;
22102225

@@ -2751,6 +2766,7 @@ impl<T: Clone, A: Allocator> VecDeque<T, A> {
27512766
/// assert_eq!(buf, [5, 10, 20, 20, 20]);
27522767
/// ```
27532768
#[stable(feature = "deque_extras", since = "1.16.0")]
2769+
#[track_caller]
27542770
pub fn resize(&mut self, new_len: usize, value: T) {
27552771
if new_len > self.len() {
27562772
let extra = new_len - self.len();
@@ -2870,6 +2886,7 @@ impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {
28702886

28712887
#[stable(feature = "rust1", since = "1.0.0")]
28722888
impl<T> FromIterator<T> for VecDeque<T> {
2889+
#[track_caller]
28732890
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> VecDeque<T> {
28742891
SpecFromIter::spec_from_iter(iter.into_iter())
28752892
}
@@ -2909,16 +2926,19 @@ impl<'a, T, A: Allocator> IntoIterator for &'a mut VecDeque<T, A> {
29092926

29102927
#[stable(feature = "rust1", since = "1.0.0")]
29112928
impl<T, A: Allocator> Extend<T> for VecDeque<T, A> {
2929+
#[track_caller]
29122930
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
29132931
<Self as SpecExtend<T, I::IntoIter>>::spec_extend(self, iter.into_iter());
29142932
}
29152933

29162934
#[inline]
2935+
#[track_caller]
29172936
fn extend_one(&mut self, elem: T) {
29182937
self.push_back(elem);
29192938
}
29202939

29212940
#[inline]
2941+
#[track_caller]
29222942
fn extend_reserve(&mut self, additional: usize) {
29232943
self.reserve(additional);
29242944
}
@@ -2934,16 +2954,19 @@ impl<T, A: Allocator> Extend<T> for VecDeque<T, A> {
29342954

29352955
#[stable(feature = "extend_ref", since = "1.2.0")]
29362956
impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for VecDeque<T, A> {
2957+
#[track_caller]
29372958
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
29382959
self.spec_extend(iter.into_iter());
29392960
}
29402961

29412962
#[inline]
2963+
#[track_caller]
29422964
fn extend_one(&mut self, &elem: &'a T) {
29432965
self.push_back(elem);
29442966
}
29452967

29462968
#[inline]
2969+
#[track_caller]
29472970
fn extend_reserve(&mut self, additional: usize) {
29482971
self.reserve(additional);
29492972
}
@@ -3041,6 +3064,7 @@ impl<T, const N: usize> From<[T; N]> for VecDeque<T> {
30413064
/// let deq2: VecDeque<_> = [1, 2, 3, 4].into();
30423065
/// assert_eq!(deq1, deq2);
30433066
/// ```
3067+
#[track_caller]
30443068
fn from(arr: [T; N]) -> Self {
30453069
let mut deq = VecDeque::with_capacity(N);
30463070
let arr = ManuallyDrop::new(arr);

library/alloc/src/collections/vec_deque/spec_extend.rs

+6
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ use crate::vec;
77

88
// Specialization trait used for VecDeque::extend
99
pub(super) trait SpecExtend<T, I> {
10+
#[track_caller]
1011
fn spec_extend(&mut self, iter: I);
1112
}
1213

1314
impl<T, I, A: Allocator> SpecExtend<T, I> for VecDeque<T, A>
1415
where
1516
I: Iterator<Item = T>,
1617
{
18+
#[track_caller]
1719
default fn spec_extend(&mut self, mut iter: I) {
1820
// This function should be the moral equivalent of:
1921
//
@@ -44,6 +46,7 @@ impl<T, I, A: Allocator> SpecExtend<T, I> for VecDeque<T, A>
4446
where
4547
I: TrustedLen<Item = T>,
4648
{
49+
#[track_caller]
4750
default fn spec_extend(&mut self, iter: I) {
4851
// This is the case for a TrustedLen iterator.
4952
let (low, high) = iter.size_hint();
@@ -76,6 +79,7 @@ where
7679
}
7780

7881
impl<T, A: Allocator> SpecExtend<T, vec::IntoIter<T>> for VecDeque<T, A> {
82+
#[track_caller]
7983
fn spec_extend(&mut self, mut iterator: vec::IntoIter<T>) {
8084
let slice = iterator.as_slice();
8185
self.reserve(slice.len());
@@ -93,6 +97,7 @@ where
9397
I: Iterator<Item = &'a T>,
9498
T: Copy,
9599
{
100+
#[track_caller]
96101
default fn spec_extend(&mut self, iterator: I) {
97102
self.spec_extend(iterator.copied())
98103
}
@@ -102,6 +107,7 @@ impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for VecDeque
102107
where
103108
T: Copy,
104109
{
110+
#[track_caller]
105111
fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
106112
let slice = iterator.as_slice();
107113
self.reserve(slice.len());

library/alloc/src/collections/vec_deque/spec_from_iter.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ impl<T, I> SpecFromIter<T, I> for VecDeque<T>
99
where
1010
I: Iterator<Item = T>,
1111
{
12+
#[track_caller]
1213
default fn spec_from_iter(iterator: I) -> Self {
1314
// Since converting is O(1) now, just re-use the `Vec` logic for
1415
// anything where we can't do something extra-special for `VecDeque`,

library/alloc/src/raw_vec.rs

+17
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod tests;
2020
// only one location which panics rather than a bunch throughout the module.
2121
#[cfg(not(no_global_oom_handling))]
2222
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
23+
#[track_caller]
2324
fn capacity_overflow() -> ! {
2425
panic!("capacity overflow");
2526
}
@@ -125,6 +126,7 @@ impl<T> RawVec<T, Global> {
125126
#[cfg(not(any(no_global_oom_handling, test)))]
126127
#[must_use]
127128
#[inline]
129+
#[track_caller]
128130
pub fn with_capacity(capacity: usize) -> Self {
129131
Self { inner: RawVecInner::with_capacity(capacity, T::LAYOUT), _marker: PhantomData }
130132
}
@@ -133,6 +135,7 @@ impl<T> RawVec<T, Global> {
133135
#[cfg(not(any(no_global_oom_handling, test)))]
134136
#[must_use]
135137
#[inline]
138+
#[track_caller]
136139
pub fn with_capacity_zeroed(capacity: usize) -> Self {
137140
Self {
138141
inner: RawVecInner::with_capacity_zeroed_in(capacity, Global, T::LAYOUT),
@@ -145,6 +148,7 @@ impl RawVecInner<Global> {
145148
#[cfg(not(any(no_global_oom_handling, test)))]
146149
#[must_use]
147150
#[inline]
151+
#[track_caller]
148152
fn with_capacity(capacity: usize, elem_layout: Layout) -> Self {
149153
match Self::try_allocate_in(capacity, AllocInit::Uninitialized, Global, elem_layout) {
150154
Ok(res) => res,
@@ -184,6 +188,7 @@ impl<T, A: Allocator> RawVec<T, A> {
184188
/// allocator for the returned `RawVec`.
185189
#[cfg(not(no_global_oom_handling))]
186190
#[inline]
191+
#[track_caller]
187192
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
188193
Self {
189194
inner: RawVecInner::with_capacity_in(capacity, alloc, T::LAYOUT),
@@ -205,6 +210,7 @@ impl<T, A: Allocator> RawVec<T, A> {
205210
/// of allocator for the returned `RawVec`.
206211
#[cfg(not(no_global_oom_handling))]
207212
#[inline]
213+
#[track_caller]
208214
pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
209215
Self {
210216
inner: RawVecInner::with_capacity_zeroed_in(capacity, alloc, T::LAYOUT),
@@ -324,6 +330,7 @@ impl<T, A: Allocator> RawVec<T, A> {
324330
/// Aborts on OOM.
325331
#[cfg(not(no_global_oom_handling))]
326332
#[inline]
333+
#[track_caller]
327334
pub fn reserve(&mut self, len: usize, additional: usize) {
328335
self.inner.reserve(len, additional, T::LAYOUT)
329336
}
@@ -332,6 +339,7 @@ impl<T, A: Allocator> RawVec<T, A> {
332339
/// caller to ensure `len == self.capacity()`.
333340
#[cfg(not(no_global_oom_handling))]
334341
#[inline(never)]
342+
#[track_caller]
335343
pub fn grow_one(&mut self) {
336344
self.inner.grow_one(T::LAYOUT)
337345
}
@@ -359,6 +367,7 @@ impl<T, A: Allocator> RawVec<T, A> {
359367
///
360368
/// Aborts on OOM.
361369
#[cfg(not(no_global_oom_handling))]
370+
#[track_caller]
362371
pub fn reserve_exact(&mut self, len: usize, additional: usize) {
363372
self.inner.reserve_exact(len, additional, T::LAYOUT)
364373
}
@@ -383,6 +392,7 @@ impl<T, A: Allocator> RawVec<T, A> {
383392
///
384393
/// Aborts on OOM.
385394
#[cfg(not(no_global_oom_handling))]
395+
#[track_caller]
386396
#[inline]
387397
pub fn shrink_to_fit(&mut self, cap: usize) {
388398
self.inner.shrink_to_fit(cap, T::LAYOUT)
@@ -408,6 +418,7 @@ impl<A: Allocator> RawVecInner<A> {
408418

409419
#[cfg(not(no_global_oom_handling))]
410420
#[inline]
421+
#[track_caller]
411422
fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self {
412423
match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) {
413424
Ok(this) => {
@@ -432,6 +443,7 @@ impl<A: Allocator> RawVecInner<A> {
432443

433444
#[cfg(not(no_global_oom_handling))]
434445
#[inline]
446+
#[track_caller]
435447
fn with_capacity_zeroed_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self {
436448
match Self::try_allocate_in(capacity, AllocInit::Zeroed, alloc, elem_layout) {
437449
Ok(res) => res,
@@ -526,6 +538,7 @@ impl<A: Allocator> RawVecInner<A> {
526538

527539
#[cfg(not(no_global_oom_handling))]
528540
#[inline]
541+
#[track_caller]
529542
fn reserve(&mut self, len: usize, additional: usize, elem_layout: Layout) {
530543
// Callers expect this function to be very cheap when there is already sufficient capacity.
531544
// Therefore, we move all the resizing and error-handling logic from grow_amortized and
@@ -550,6 +563,7 @@ impl<A: Allocator> RawVecInner<A> {
550563

551564
#[cfg(not(no_global_oom_handling))]
552565
#[inline]
566+
#[track_caller]
553567
fn grow_one(&mut self, elem_layout: Layout) {
554568
if let Err(err) = self.grow_amortized(self.cap.0, 1, elem_layout) {
555569
handle_error(err);
@@ -573,6 +587,7 @@ impl<A: Allocator> RawVecInner<A> {
573587
}
574588

575589
#[cfg(not(no_global_oom_handling))]
590+
#[track_caller]
576591
fn reserve_exact(&mut self, len: usize, additional: usize, elem_layout: Layout) {
577592
if let Err(err) = self.try_reserve_exact(len, additional, elem_layout) {
578593
handle_error(err);
@@ -597,6 +612,7 @@ impl<A: Allocator> RawVecInner<A> {
597612

598613
#[cfg(not(no_global_oom_handling))]
599614
#[inline]
615+
#[track_caller]
600616
fn shrink_to_fit(&mut self, cap: usize, elem_layout: Layout) {
601617
if let Err(err) = self.shrink(cap, elem_layout) {
602618
handle_error(err);
@@ -770,6 +786,7 @@ where
770786
#[cfg(not(no_global_oom_handling))]
771787
#[cold]
772788
#[optimize(size)]
789+
#[track_caller]
773790
fn handle_error(e: TryReserveError) -> ! {
774791
match e.kind() {
775792
CapacityOverflow => capacity_overflow(),

library/alloc/src/vec/cow.rs

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]>
5858
where
5959
T: Clone,
6060
{
61+
#[track_caller]
6162
fn from_iter<I: IntoIterator<Item = T>>(it: I) -> Cow<'a, [T]> {
6263
Cow::Owned(FromIterator::from_iter(it))
6364
}

library/alloc/src/vec/in_place_collect.rs

+2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ where
229229
I: Iterator<Item = T> + InPlaceCollect,
230230
<I as SourceIter>::Source: AsVecIntoIter,
231231
{
232+
#[track_caller]
232233
default fn from_iter(iterator: I) -> Self {
233234
// Select the implementation in const eval to avoid codegen of the dead branch to improve compile times.
234235
let fun: fn(I) -> Vec<T> = const {
@@ -246,6 +247,7 @@ where
246247
}
247248
}
248249

250+
#[track_caller]
249251
fn from_iter_in_place<I, T>(mut iterator: I) -> Vec<T>
250252
where
251253
I: Iterator<Item = T> + InPlaceCollect,

0 commit comments

Comments
 (0)