Skip to content

Trying to shrink_to greater than capacity should be no-op #81335

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

Merged
merged 1 commit into from
Jan 27, 2021
Merged
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
3 changes: 1 addition & 2 deletions library/alloc/src/collections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,8 +870,7 @@ impl<T> BinaryHeap<T> {
/// The capacity will remain at least as large as both the length
/// and the supplied value.
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
Expand Down
10 changes: 4 additions & 6 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,8 +761,7 @@ impl<T> VecDeque<T> {
/// The capacity will remain at least as large as both the length
/// and the supplied value.
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
Expand All @@ -780,10 +779,9 @@ impl<T> VecDeque<T> {
/// ```
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
pub fn shrink_to(&mut self, min_capacity: usize) {
assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");

// +1 since the ringbuffer always leaves one space empty
// len + 1 can't overflow for an existing, well-formed ringbuffer.
let min_capacity = cmp::min(min_capacity, self.capacity());
// We don't have to worry about an overflow as neither `self.len()` nor `self.capacity()`
// can ever be `usize::MAX`. +1 as the ringbuffer always leaves one space empty.
let target_cap = cmp::max(cmp::max(min_capacity, self.len()) + 1, MINIMUM_CAPACITY + 1)
.next_power_of_two();

Expand Down
3 changes: 1 addition & 2 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,8 +1036,7 @@ impl String {
/// The capacity will remain at least as large as both the length
/// and the supplied value.
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
Expand Down
12 changes: 6 additions & 6 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ mod spec_extend;
/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`
/// and then filling it back up to the same [`len`] should incur no calls to
/// the allocator. If you wish to free up unused memory, use
/// [`shrink_to_fit`].
/// [`shrink_to_fit`] or [`shrink_to`].
///
/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
Expand Down Expand Up @@ -360,6 +360,7 @@ mod spec_extend;
/// [`String`]: crate::string::String
/// [`&str`]: type@str
/// [`shrink_to_fit`]: Vec::shrink_to_fit
/// [`shrink_to`]: Vec::shrink_to
/// [`capacity`]: Vec::capacity
/// [`mem::size_of::<T>`]: core::mem::size_of
/// [`len`]: Vec::len
Expand Down Expand Up @@ -909,10 +910,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// The capacity will remain at least as large as both the length
/// and the supplied value.
///
/// # Panics
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
Expand All @@ -929,7 +927,9 @@ impl<T, A: Allocator> Vec<T, A> {
#[doc(alias = "realloc")]
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.buf.shrink_to_fit(cmp::max(self.len, min_capacity));
if self.capacity() > min_capacity {
self.buf.shrink_to_fit(cmp::max(self.len, min_capacity));
}
}

/// Converts the vector into [`Box<[T]>`][owned slice].
Expand Down
4 changes: 1 addition & 3 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,7 @@ where
/// down no lower than the supplied limit while maintaining the internal rules
/// and possibly leaving some space in accordance with the resize policy.
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
Expand All @@ -679,7 +678,6 @@ where
#[inline]
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
pub fn shrink_to(&mut self, min_capacity: usize) {
assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
self.base.shrink_to(min_capacity);
}

Expand Down
4 changes: 1 addition & 3 deletions library/std/src/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,7 @@ where
/// down no lower than the supplied limit while maintaining the internal rules
/// and possibly leaving some space in accordance with the resize policy.
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
///
/// If the current capacity is less than the lower limit, this is a no-op.
/// # Examples
///
/// ```
Expand Down
3 changes: 1 addition & 2 deletions library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ impl OsString {
/// The capacity will remain at least as large as both the length
/// and the supplied value.
///
/// Panics if the current capacity is smaller than the supplied
/// minimum capacity.
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
Expand Down
8 changes: 0 additions & 8 deletions src/test/codegen/vec-shrink-panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,3 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
// CHECK-NOT: panic
iter.iter().copied().collect()
}

// Sanity-check that we do see a possible panic for an arbitrary `Vec::shrink_to`.
// CHECK-LABEL: @shrink_to
#[no_mangle]
pub fn shrink_to(vec: &mut Vec<u32>) {
// CHECK: panic
vec.shrink_to(42);
}