Skip to content

Commit 0badab2

Browse files
committed
Fix condition in realloc() implementation of Vec
Poolable and Realloc trait method implementations for Vec operate on the vector itself rather than its underlying buffer. This is why Poolable::capacity() implementation calls Vec::len() and Realloc::realloc() implementation uses Vec::resize() rather than Vec::reserve() or Vec::reserve_exact(). However, the condition checking whether the vector should be resized called Vec::len() rather than Vec::capacity(). Apparently it was an attempt to call Poolable::capacity(&self), but by default ambiguous call is resolved to Vec::capacity(). The problem is resolved by calling .len() explicitly. Regression test and assertions failing for byte-pool 0.2.2 are added.
1 parent 2a50848 commit 0badab2

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/poolable.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ impl<T: Default + Clone> Realloc for Vec<T> {
4141
use std::cmp::Ordering::*;
4242

4343
assert!(new_size > 0);
44-
match new_size.cmp(&self.capacity()) {
44+
match new_size.cmp(&self.len()) {
4545
Greater => self.resize(new_size, T::default()),
4646
Less => {
4747
self.truncate(new_size);
48+
debug_assert_eq!(self.len(), new_size);
4849
self.shrink_to_fit();
50+
debug_assert_eq!(self.capacity(), new_size);
4951
}
5052
Equal => {}
5153
}
@@ -74,3 +76,25 @@ where
7476
}
7577
}
7678
}
79+
80+
#[cfg(test)]
81+
mod tests {
82+
use super::*;
83+
84+
/// Regression test for `Realloc` trait implementation of `Vec`.
85+
///
86+
/// Previously `Realloc::realloc()` called `self.capacity()` instead
87+
/// of `self.len()` when checking whether the vector should be expanded.
88+
/// As a result, it sometimes attempted to shrink the vector
89+
/// when it should be expanded, and effectively did nothing.
90+
#[test]
91+
fn realloc_vec() {
92+
let mut v: Vec<u8> = Poolable::alloc(100);
93+
94+
for i in 1..100 {
95+
let new_size = Poolable::capacity(&v) + i;
96+
v.realloc(new_size);
97+
assert_eq!(Poolable::capacity(&v), new_size);
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)