Auto merge of #81335 - thomwiggers:no-panic-shrink-to, r=Mark-Simulacrum
Trying to shrink_to greater than capacity should be no-op Per the discussion in https://github.com/rust-lang/rust/issues/56431, `shrink_to` shouldn't panic if you try to make a vector shrink to a capacity greater than its current capacity.
This commit is contained in:
commit
a2f8f62818
8 changed files with 15 additions and 32 deletions
|
@ -870,8 +870,7 @@ impl<T> BinaryHeap<T> {
|
||||||
/// The capacity will remain at least as large as both the length
|
/// The capacity will remain at least as large as both the length
|
||||||
/// and the supplied value.
|
/// and the supplied value.
|
||||||
///
|
///
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
/// minimum capacity.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -761,8 +761,7 @@ impl<T> VecDeque<T> {
|
||||||
/// The capacity will remain at least as large as both the length
|
/// The capacity will remain at least as large as both the length
|
||||||
/// and the supplied value.
|
/// and the supplied value.
|
||||||
///
|
///
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
/// minimum capacity.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -780,10 +779,9 @@ impl<T> VecDeque<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
|
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
|
||||||
pub fn shrink_to(&mut self, min_capacity: usize) {
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
||||||
assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity");
|
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()`
|
||||||
// +1 since the ringbuffer always leaves one space empty
|
// can ever be `usize::MAX`. +1 as the ringbuffer always leaves one space empty.
|
||||||
// len + 1 can't overflow for an existing, well-formed ringbuffer.
|
|
||||||
let target_cap = cmp::max(cmp::max(min_capacity, self.len()) + 1, MINIMUM_CAPACITY + 1)
|
let target_cap = cmp::max(cmp::max(min_capacity, self.len()) + 1, MINIMUM_CAPACITY + 1)
|
||||||
.next_power_of_two();
|
.next_power_of_two();
|
||||||
|
|
||||||
|
|
|
@ -1036,8 +1036,7 @@ impl String {
|
||||||
/// The capacity will remain at least as large as both the length
|
/// The capacity will remain at least as large as both the length
|
||||||
/// and the supplied value.
|
/// and the supplied value.
|
||||||
///
|
///
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
/// minimum capacity.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -321,7 +321,7 @@ mod spec_extend;
|
||||||
/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`
|
/// 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
|
/// 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
|
/// 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
|
/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
|
||||||
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
|
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
|
||||||
|
@ -360,6 +360,7 @@ mod spec_extend;
|
||||||
/// [`String`]: crate::string::String
|
/// [`String`]: crate::string::String
|
||||||
/// [`&str`]: type@str
|
/// [`&str`]: type@str
|
||||||
/// [`shrink_to_fit`]: Vec::shrink_to_fit
|
/// [`shrink_to_fit`]: Vec::shrink_to_fit
|
||||||
|
/// [`shrink_to`]: Vec::shrink_to
|
||||||
/// [`capacity`]: Vec::capacity
|
/// [`capacity`]: Vec::capacity
|
||||||
/// [`mem::size_of::<T>`]: core::mem::size_of
|
/// [`mem::size_of::<T>`]: core::mem::size_of
|
||||||
/// [`len`]: Vec::len
|
/// [`len`]: Vec::len
|
||||||
|
@ -909,10 +910,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
/// The capacity will remain at least as large as both the length
|
/// The capacity will remain at least as large as both the length
|
||||||
/// and the supplied value.
|
/// and the supplied value.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
///
|
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
|
||||||
/// minimum capacity.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -929,7 +927,9 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||||
#[doc(alias = "realloc")]
|
#[doc(alias = "realloc")]
|
||||||
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
|
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
|
||||||
pub fn shrink_to(&mut self, min_capacity: usize) {
|
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].
|
/// Converts the vector into [`Box<[T]>`][owned slice].
|
||||||
|
|
|
@ -658,8 +658,7 @@ where
|
||||||
/// down no lower than the supplied limit while maintaining the internal rules
|
/// down no lower than the supplied limit while maintaining the internal rules
|
||||||
/// and possibly leaving some space in accordance with the resize policy.
|
/// and possibly leaving some space in accordance with the resize policy.
|
||||||
///
|
///
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
/// minimum capacity.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -679,7 +678,6 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
|
#[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
|
||||||
pub fn shrink_to(&mut self, min_capacity: usize) {
|
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);
|
self.base.shrink_to(min_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -462,9 +462,7 @@ where
|
||||||
/// down no lower than the supplied limit while maintaining the internal rules
|
/// down no lower than the supplied limit while maintaining the internal rules
|
||||||
/// and possibly leaving some space in accordance with the resize policy.
|
/// and possibly leaving some space in accordance with the resize policy.
|
||||||
///
|
///
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
/// minimum capacity.
|
|
||||||
///
|
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -304,8 +304,7 @@ impl OsString {
|
||||||
/// The capacity will remain at least as large as both the length
|
/// The capacity will remain at least as large as both the length
|
||||||
/// and the supplied value.
|
/// and the supplied value.
|
||||||
///
|
///
|
||||||
/// Panics if the current capacity is smaller than the supplied
|
/// If the current capacity is less than the lower limit, this is a no-op.
|
||||||
/// minimum capacity.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -26,11 +26,3 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
|
||||||
// CHECK-NOT: panic
|
// CHECK-NOT: panic
|
||||||
iter.iter().copied().collect()
|
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);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue