diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2021-11-25 19:29:10 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2021-11-26 19:30:45 +1100 |
| commit | dbfb91385f7e4c27a6a48ecc3f683e3295af8b49 (patch) | |
| tree | 4ad107be9d95ef664d4cca178baffa28f2a8796c | |
| parent | f3bda74d363a060ade5e5caeb654ba59bfed51a4 (diff) | |
| download | rust-dbfb91385f7e4c27a6a48ecc3f683e3295af8b49.tar.gz rust-dbfb91385f7e4c27a6a48ecc3f683e3295af8b49.zip | |
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.
| -rw-r--r-- | library/alloc/src/raw_vec/tests.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/library/alloc/src/raw_vec/tests.rs b/library/alloc/src/raw_vec/tests.rs index 8c15a24409b..ff322f0da97 100644 --- a/library/alloc/src/raw_vec/tests.rs +++ b/library/alloc/src/raw_vec/tests.rs @@ -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); +} |
