Check capacity arithmetic

This commit is contained in:
2026-07-31 03:35:20 +02:00
parent a3612a320f
commit 9b45b967e2
2 changed files with 33 additions and 5 deletions
+5 -1
View File
@@ -129,7 +129,11 @@ impl TypeErasedVec {
/// logical capacity.
#[must_use]
pub const fn capacity_bytes(&self) -> usize {
self.parts.cap * self.layout.size()
let capacity_bytes = self.parts.cap.checked_mul(self.layout.size());
// SAFETY: A valid Vec allocation cannot exceed usize::MAX bytes.
// ZST vectors multiply their logical capacity by zero.
unsafe { capacity_bytes.unwrap_unchecked() }
}
/// Access the erased capacity with a temporarily fixed type.
+28 -4
View File
@@ -16,11 +16,29 @@ impl DropTracker {
}
impl Drop for DropTracker {
#[expect(
clippy::panic,
reason = "overflow means the test's drop-count assertion can no longer be trusted"
)]
fn drop(&mut self) {
self.counter.set(self.counter.get() + 1);
let Some(next_count) = self.counter.get().checked_add(1) else {
panic!("drop counter overflow");
};
self.counter.set(next_count);
}
}
#[expect(
clippy::panic,
reason = "overflow means the test's capacity expectation is invalid"
)]
fn checked_product(left: usize, right: usize) -> usize {
let Some(product) = left.checked_mul(right) else {
panic!("test multiplication overflow");
};
product
}
#[track_caller]
fn assert_erased_state(erased: &TypeErasedVec, expected_len: usize, expected_layout: Layout) {
assert_eq!(erased.length(), expected_len, "Length mismatch");
@@ -28,7 +46,7 @@ fn assert_erased_state(erased: &TypeErasedVec, expected_len: usize, expected_lay
assert_eq!(erased.layout(), expected_layout, "Layout mismatch");
assert_eq!(
erased.capacity_bytes(),
erased.capacity() * expected_layout.size(),
checked_product(erased.capacity(), expected_layout.size()),
"Capacity bytes mismatch"
);
}
@@ -92,7 +110,10 @@ macro_rules! assert_thread_safe_erased_vec_api {
assert_eq!(erased.length(), 1);
assert!(!erased.is_empty());
assert!(erased.capacity() >= 1);
assert_eq!(erased.capacity_bytes(), erased.capacity() * 4);
assert_eq!(
erased.capacity_bytes(),
checked_product(erased.capacity(), 4)
);
erased.reserve(8);
assert!(erased.capacity() >= 9);
@@ -512,7 +533,10 @@ fn test_erased_layout_and_capacity_bytes() {
let erased = TypeErasedVec::new(vec);
assert_eq!(erased.layout(), Layout::new::<u64>());
assert_eq!(erased.capacity_bytes(), erased.capacity() * 8);
assert_eq!(
erased.capacity_bytes(),
checked_product(erased.capacity(), 8)
);
}
#[test]