Skip to content

Commit c03c213

Browse files
committed
Auto merge of #75677 - cuviper:shrink-towel, r=Mark-Simulacrum
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.
2 parents 1656582 + 7551f3f commit c03c213

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

library/alloc/src/vec.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,10 @@ impl<T> Vec<T> {
622622
/// ```
623623
#[stable(feature = "rust1", since = "1.0.0")]
624624
pub fn shrink_to_fit(&mut self) {
625-
if self.capacity() != self.len {
625+
// The capacity is never less than the length, and there's nothing to do when
626+
// they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit`
627+
// by only calling it with a greater capacity.
628+
if self.capacity() > self.len {
626629
self.buf.shrink_to_fit(self.len);
627630
}
628631
}

src/test/codegen/vec-shrink-panic.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// compile-flags: -O
2+
// ignore-debug: the debug assertions get in the way
3+
#![crate_type = "lib"]
4+
#![feature(shrink_to)]
5+
6+
// Make sure that `Vec::shrink_to_fit` never emits panics via `RawVec::shrink_to_fit`,
7+
// "Tried to shrink to a larger capacity", because the length is *always* <= capacity.
8+
9+
// CHECK-LABEL: @shrink_to_fit
10+
#[no_mangle]
11+
pub fn shrink_to_fit(vec: &mut Vec<u32>) {
12+
// CHECK-NOT: panic
13+
vec.shrink_to_fit();
14+
}
15+
16+
// CHECK-LABEL: @issue71861
17+
#[no_mangle]
18+
pub fn issue71861(n: usize) -> Box<[u32]> {
19+
// CHECK-NOT: panic
20+
vec![0; n].into_boxed_slice()
21+
}
22+
23+
// CHECK-LABEL: @issue75636
24+
#[no_mangle]
25+
pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
26+
// CHECK-NOT: panic
27+
iter.iter().copied().collect()
28+
}
29+
30+
// Sanity-check that we do see a possible panic for an arbitrary `Vec::shrink_to`.
31+
// CHECK-LABEL: @shrink_to
32+
#[no_mangle]
33+
pub fn shrink_to(vec: &mut Vec<u32>) {
34+
// CHECK: panic
35+
vec.shrink_to(42);
36+
}

0 commit comments

Comments
 (0)