Skip to content

Commit 3e9047e

Browse files
committed
assert that T is not a ZST
HeaderVec does not support ZST's, this will give a compiletime error when one tries to do so. Before it was a Divide by Zero runtime error in the offset calculation. Remove the ZST code from Drain too (was some remains from std Drain) Its unlikely that supporting ZST's in HeaderVec makes any sense. Forbiding this altogether make this clear. When someone comes up with a real use case this may be reviewed.
1 parent c42d26f commit 3e9047e

2 files changed

Lines changed: 13 additions & 29 deletions

File tree

src/drain.rs

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -99,24 +99,21 @@ impl<H, T> Drain<'_, H, T> {
9999
let unyielded_len = this.iter.len();
100100
let unyielded_ptr = this.iter.as_slice().as_ptr();
101101

102-
// ZSTs have no identity, so we don't need to move them around.
103-
if std::mem::size_of::<T>() != 0 {
104-
let start_ptr = source_vec.as_mut_ptr().add(start);
102+
let start_ptr = source_vec.as_mut_ptr().add(start);
105103

106-
// memmove back unyielded elements
107-
if unyielded_ptr != start_ptr {
108-
let src = unyielded_ptr;
109-
let dst = start_ptr;
104+
// memmove back unyielded elements
105+
if unyielded_ptr != start_ptr {
106+
let src = unyielded_ptr;
107+
let dst = start_ptr;
110108

111-
ptr::copy(src, dst, unyielded_len);
112-
}
109+
ptr::copy(src, dst, unyielded_len);
110+
}
113111

114-
// memmove back untouched tail
115-
if tail != (start + unyielded_len) {
116-
let src = source_vec.as_ptr().add(tail);
117-
let dst = start_ptr.add(unyielded_len);
118-
ptr::copy(src, dst, this.tail_len());
119-
}
112+
// memmove back untouched tail
113+
if tail != (start + unyielded_len) {
114+
let src = source_vec.as_ptr().add(tail);
115+
let dst = start_ptr.add(unyielded_len);
116+
ptr::copy(src, dst, this.tail_len());
120117
}
121118

122119
source_vec.set_len(start + unyielded_len + this.tail_len());
@@ -190,20 +187,6 @@ impl<H, T> Drop for Drain<'_, H, T> {
190187

191188
let mut vec = self.vec;
192189

193-
// unstable: if T::IS_ZST { instead we use size_of
194-
if mem::size_of::<T>() == 0 {
195-
// ZSTs have no identity, so we don't need to move them around, we only need to drop the correct amount.
196-
// this can be achieved by manipulating the Vec length instead of moving values out from `iter`.
197-
unsafe {
198-
let vec = vec.as_mut();
199-
let old_len = vec.len();
200-
vec.set_len(old_len + drop_len + self.tail_len());
201-
vec.truncate(old_len + self.tail_len());
202-
}
203-
204-
return;
205-
}
206-
207190
// ensure elements are moved back into their appropriate places, even when drop_in_place panics
208191
let _guard = DropGuard(self);
209192

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl<H, T> HeaderVec<H, T> {
8585
}
8686

8787
pub fn with_capacity(capacity: usize, head: H) -> Self {
88+
const { assert!(mem::size_of::<T>() > 0, "HeaderVec does not support ZST's") };
8889
// Allocate the initial memory, which is uninitialized.
8990
let layout = Self::layout(capacity);
9091
let ptr = unsafe { alloc::alloc::alloc(layout) } as *mut AlignedHeader<H, T>;

0 commit comments

Comments
 (0)