1
Fork 0

Add a unit test for zero-sized types in RawVec.

Because there's some subtle behaviour specific to zero-sized types and
it's currently not well tested.
This commit is contained in:
Nicholas Nethercote 2021-11-25 19:29:10 +11:00
parent f3bda74d36
commit dbfb91385f

View file

@ -77,3 +77,87 @@ fn reserve_does_not_overallocate() {
assert!(v.capacity() >= 12 + 12 / 2);
}
}
struct ZST;
// A `RawVec` holding zero-sized elements should always look like this.
fn zst_sanity<T>(v: &RawVec<T>) {
assert_eq!(v.capacity(), usize::MAX);
assert_eq!(v.ptr(), core::ptr::Unique::<T>::dangling().as_ptr());
assert_eq!(v.current_memory(), None);
}
#[test]
fn zst() {
let cap_err = Err(crate::collections::TryReserveErrorKind::CapacityOverflow.into());
assert_eq!(std::mem::size_of::<ZST>(), 0);
// All these different ways of creating the RawVec produce the same thing.
let v: RawVec<ZST> = RawVec::new();
zst_sanity(&v);
let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
zst_sanity(&v);
let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
zst_sanity(&v);
let v: RawVec<ZST> = RawVec::allocate_in(0, AllocInit::Uninitialized, Global);
zst_sanity(&v);
let v: RawVec<ZST> = RawVec::allocate_in(100, AllocInit::Uninitialized, Global);
zst_sanity(&v);
let mut v: RawVec<ZST> = RawVec::allocate_in(usize::MAX, AllocInit::Uninitialized, Global);
zst_sanity(&v);
// Check all these operations work as expected with zero-sized elements.
assert!(!v.needs_to_grow(100, usize::MAX - 100));
assert!(v.needs_to_grow(101, usize::MAX - 100));
zst_sanity(&v);
v.reserve(100, usize::MAX - 100);
//v.reserve(101, usize::MAX - 100); // panics, in `zst_reserve_panic` below
zst_sanity(&v);
v.reserve_exact(100, usize::MAX - 100);
//v.reserve_exact(101, usize::MAX - 100); // panics, in `zst_reserve_exact_panic` below
zst_sanity(&v);
assert_eq!(v.try_reserve(100, usize::MAX - 100), Ok(()));
assert_eq!(v.try_reserve(101, usize::MAX - 100), cap_err);
zst_sanity(&v);
assert_eq!(v.try_reserve_exact(100, usize::MAX - 100), Ok(()));
assert_eq!(v.try_reserve_exact(101, usize::MAX - 100), cap_err);
zst_sanity(&v);
assert_eq!(v.grow_amortized(100, usize::MAX - 100), cap_err);
assert_eq!(v.grow_amortized(101, usize::MAX - 100), cap_err);
zst_sanity(&v);
assert_eq!(v.grow_exact(100, usize::MAX - 100), cap_err);
assert_eq!(v.grow_exact(101, usize::MAX - 100), cap_err);
zst_sanity(&v);
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn zst_reserve_panic() {
let mut v: RawVec<ZST> = RawVec::new();
zst_sanity(&v);
v.reserve(101, usize::MAX - 100);
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn zst_reserve_exact_panic() {
let mut v: RawVec<ZST> = RawVec::new();
zst_sanity(&v);
v.reserve_exact(101, usize::MAX - 100);
}