Check capacity arithmetic
This commit is contained in:
+5
-1
@@ -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
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user