Skip to content

Commit

Permalink
Auto merge of #75677 - cuviper:shrink-towel, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
Don't panic in Vec::shrink_to_fit

We can help the compiler see that `Vec::shrink_to_fit` will never reach the panic case in `RawVec::shrink_to_fit`, just by guarding the call only for cases where the capacity is strictly greater. A capacity less than the length is only possible through an unsafe call to `set_len`, which would break the `Vec` invariants, so `shrink_to_fit` can just ignore that.

This removes the panicking code from the examples in both #71861 and #75636.
  • Loading branch information
bors committed Aug 19, 2020
2 parents 1656582 + 7551f3f commit c03c213
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
5 changes: 4 additions & 1 deletion library/alloc/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,10 @@ impl<T> Vec<T> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn shrink_to_fit(&mut self) {
if self.capacity() != self.len {
// The capacity is never less than the length, and there's nothing to do when
// they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit`
// by only calling it with a greater capacity.
if self.capacity() > self.len {
self.buf.shrink_to_fit(self.len);
}
}
Expand Down
36 changes: 36 additions & 0 deletions src/test/codegen/vec-shrink-panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// compile-flags: -O
// ignore-debug: the debug assertions get in the way
#![crate_type = "lib"]
#![feature(shrink_to)]

// Make sure that `Vec::shrink_to_fit` never emits panics via `RawVec::shrink_to_fit`,
// "Tried to shrink to a larger capacity", because the length is *always* <= capacity.

// CHECK-LABEL: @shrink_to_fit
#[no_mangle]
pub fn shrink_to_fit(vec: &mut Vec<u32>) {
// CHECK-NOT: panic
vec.shrink_to_fit();
}

// CHECK-LABEL: @issue71861
#[no_mangle]
pub fn issue71861(n: usize) -> Box<[u32]> {
// CHECK-NOT: panic
vec![0; n].into_boxed_slice()
}

// CHECK-LABEL: @issue75636
#[no_mangle]
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);
}

0 comments on commit c03c213

Please sign in to comment.