Skip to content

Commit dbfb913

Browse files
committed
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.
1 parent f3bda74 commit dbfb913

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

library/alloc/src/raw_vec/tests.rs

+84
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,87 @@ fn reserve_does_not_overallocate() {
7777
assert!(v.capacity() >= 12 + 12 / 2);
7878
}
7979
}
80+
81+
struct ZST;
82+
83+
// A `RawVec` holding zero-sized elements should always look like this.
84+
fn zst_sanity<T>(v: &RawVec<T>) {
85+
assert_eq!(v.capacity(), usize::MAX);
86+
assert_eq!(v.ptr(), core::ptr::Unique::<T>::dangling().as_ptr());
87+
assert_eq!(v.current_memory(), None);
88+
}
89+
90+
#[test]
91+
fn zst() {
92+
let cap_err = Err(crate::collections::TryReserveErrorKind::CapacityOverflow.into());
93+
94+
assert_eq!(std::mem::size_of::<ZST>(), 0);
95+
96+
// All these different ways of creating the RawVec produce the same thing.
97+
98+
let v: RawVec<ZST> = RawVec::new();
99+
zst_sanity(&v);
100+
101+
let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
102+
zst_sanity(&v);
103+
104+
let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
105+
zst_sanity(&v);
106+
107+
let v: RawVec<ZST> = RawVec::allocate_in(0, AllocInit::Uninitialized, Global);
108+
zst_sanity(&v);
109+
110+
let v: RawVec<ZST> = RawVec::allocate_in(100, AllocInit::Uninitialized, Global);
111+
zst_sanity(&v);
112+
113+
let mut v: RawVec<ZST> = RawVec::allocate_in(usize::MAX, AllocInit::Uninitialized, Global);
114+
zst_sanity(&v);
115+
116+
// Check all these operations work as expected with zero-sized elements.
117+
118+
assert!(!v.needs_to_grow(100, usize::MAX - 100));
119+
assert!(v.needs_to_grow(101, usize::MAX - 100));
120+
zst_sanity(&v);
121+
122+
v.reserve(100, usize::MAX - 100);
123+
//v.reserve(101, usize::MAX - 100); // panics, in `zst_reserve_panic` below
124+
zst_sanity(&v);
125+
126+
v.reserve_exact(100, usize::MAX - 100);
127+
//v.reserve_exact(101, usize::MAX - 100); // panics, in `zst_reserve_exact_panic` below
128+
zst_sanity(&v);
129+
130+
assert_eq!(v.try_reserve(100, usize::MAX - 100), Ok(()));
131+
assert_eq!(v.try_reserve(101, usize::MAX - 100), cap_err);
132+
zst_sanity(&v);
133+
134+
assert_eq!(v.try_reserve_exact(100, usize::MAX - 100), Ok(()));
135+
assert_eq!(v.try_reserve_exact(101, usize::MAX - 100), cap_err);
136+
zst_sanity(&v);
137+
138+
assert_eq!(v.grow_amortized(100, usize::MAX - 100), cap_err);
139+
assert_eq!(v.grow_amortized(101, usize::MAX - 100), cap_err);
140+
zst_sanity(&v);
141+
142+
assert_eq!(v.grow_exact(100, usize::MAX - 100), cap_err);
143+
assert_eq!(v.grow_exact(101, usize::MAX - 100), cap_err);
144+
zst_sanity(&v);
145+
}
146+
147+
#[test]
148+
#[should_panic(expected = "capacity overflow")]
149+
fn zst_reserve_panic() {
150+
let mut v: RawVec<ZST> = RawVec::new();
151+
zst_sanity(&v);
152+
153+
v.reserve(101, usize::MAX - 100);
154+
}
155+
156+
#[test]
157+
#[should_panic(expected = "capacity overflow")]
158+
fn zst_reserve_exact_panic() {
159+
let mut v: RawVec<ZST> = RawVec::new();
160+
zst_sanity(&v);
161+
162+
v.reserve_exact(101, usize::MAX - 100);
163+
}

0 commit comments

Comments
 (0)