Skip to content

Commit 342e907

Browse files
Fix a couple of iterator ZST handling oversights
1 parent b90915f commit 342e907

File tree

3 files changed

+116
-19
lines changed

3 files changed

+116
-19
lines changed

src/iterators.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<'a, T: 'a, const N: usize> Iterator for StaticVecIterConst<'a, T, N> {
170170
// Safety: see the comments for the implementation of this function in
171171
// 'core/slice/iter/macros.rs`, as they're equally applicable to us here.
172172
match size_of::<T>() {
173-
0 => &*zst_ptr_add(self.start, idx),
173+
0 => &*((self.start as usize + idx) as *const T),
174174
_ => &*self.start.add(idx),
175175
}
176176
}
@@ -368,7 +368,7 @@ impl<'a, T: 'a, const N: usize> Iterator for StaticVecIterMut<'a, T, N> {
368368
// Safety: see the comments for the implementation of this function in
369369
// 'core/slice/iter/macros.rs`, as they're equally applicable to us here.
370370
match size_of::<T>() {
371-
0 => &mut *zst_ptr_add_mut(self.start, idx),
371+
0 => &mut *((self.start as usize + idx) as *mut T),
372372
_ => &mut *self.start.add(idx),
373373
}
374374
}
@@ -655,13 +655,14 @@ impl<T: Clone, const N: usize> Clone for StaticVecIntoIter<T, N> {
655655
data: {
656656
let mut data = MaybeUninit::<[T; N]>::uninit();
657657
let new_data_ptr = data.as_mut_ptr() as *mut T;
658-
// Guaranteed safe assumption in this context.
659-
unsafe { assume(!new_data_ptr.is_null()) };
660658
let self_data_ptr = self.data.as_ptr() as *const T;
661-
// Guaranteed safe assumption in this context.
662-
unsafe { assume(!self_data_ptr.is_null()) };
663-
for i in self.start..self.end {
664-
unsafe { new_data_ptr.add(i).write((&*self_data_ptr.add(i)).clone()) };
659+
unsafe {
660+
// These are guaranteed safe assumptions in this context.
661+
assume(!new_data_ptr.is_null());
662+
assume(!self_data_ptr.is_null());
663+
for i in self.start..self.end {
664+
new_data_ptr.add(i).write((&*self_data_ptr.add(i)).clone());
665+
}
665666
}
666667
data
667668
},

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1991,7 +1991,10 @@ impl<T, const N: usize> StaticVec<T, N> {
19911991
unsafe {
19921992
// Set the length to `start` to avoid memory issues if anything goes wrong with the Drain.
19931993
self.set_len(start);
1994-
let start_ptr = self.ptr_at_unchecked(start);
1994+
let start_ptr = match size_of::<T>() {
1995+
0 => zst_ptr_add(self.as_ptr(), start),
1996+
_ => self.ptr_at_unchecked(start),
1997+
};
19951998
// `start_ptr` will never be null, so this is a safe assumption to give to
19961999
// the optimizer.
19972000
assume(!start_ptr.is_null());

test/test_staticvec.rs

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -488,10 +488,18 @@ fn drain_iter() {
488488
ZST {},
489489
ZST {},
490490
ZST {},
491-
ZST {}
491+
ZST {},
492+
ZST {},
493+
ZST {},
494+
ZST {},
495+
ZST {},
496+
ZST {},
497+
ZST {},
498+
ZST {},
499+
ZST {},
492500
];
493-
v5.drain_iter(0..4);
494-
assert_eq!(&v5[..], &[ZST {}, ZST {}, ZST {}, ZST {}]);
501+
assert_eq!(v5.drain_iter(6..12).len(), 6);
502+
assert_eq!(v5.len(), 10);
495503
assert_eq!(
496504
staticvec![1, 2, 3, 4]
497505
.drain_iter(1..3)
@@ -515,6 +523,11 @@ fn drain_filter() {
515523
let odds = numbers;
516524
assert_eq!(evens, [2, 4, 6, 8, 14]);
517525
assert_eq!(odds, [1, 3, 5, 9, 11, 13, 15]);
526+
let mut zsts1 = staticvec![ZST {}, ZST {}, ZST {}, ZST {}];
527+
let full = zsts1.drain_filter(|x| *x == ZST {});
528+
let empty = zsts1;
529+
assert_eq!(full, [ZST {}, ZST {}, ZST {}, ZST {}]);
530+
assert_eq!(empty, []);
518531
let mut empty: StaticVec<i32, 12> = StaticVec::from([]);
519532
assert_eq!(empty.drain_filter(|x| *x == 0), []);
520533
let mut structs: StaticVec<Box<Struct>, 4> = staticvec![
@@ -1025,10 +1038,27 @@ fn iter() {
10251038
assert_eq!(iter2.next(), Some((&ZST {}, &ZST {})));
10261039
assert_eq!(iter2.next(), Some((&ZST {}, &ZST {})));
10271040
assert_eq!(iter2.next(), None);
1028-
let a5 = staticvec![ZST {}, ZST {}, ZST {}, ZST {}];
1041+
let a5 = staticvec![
1042+
ZST {},
1043+
ZST {},
1044+
ZST {},
1045+
ZST {},
1046+
ZST {},
1047+
ZST {},
1048+
ZST {},
1049+
ZST {},
1050+
ZST {},
1051+
ZST {},
1052+
ZST {},
1053+
ZST {},
1054+
ZST {},
1055+
ZST {},
1056+
ZST {},
1057+
ZST {}
1058+
];
10291059
let mut iter3 = a5.iter();
10301060
unsafe {
1031-
assert_eq!(iter3.__iterator_get_unchecked(2), &ZST {});
1061+
assert_eq!(iter3.__iterator_get_unchecked(13), &ZST {});
10321062
}
10331063
}
10341064

@@ -1239,10 +1269,27 @@ fn iter_mut() {
12391269
a1.concat_clone(&a2),
12401270
staticvec![box 2, box 3, box 4, box 5, box 6, box 7]
12411271
);
1242-
let mut a3 = staticvec![ZST {}, ZST {}, ZST {}, ZST {}];
1272+
let mut a3 = staticvec![
1273+
ZST {},
1274+
ZST {},
1275+
ZST {},
1276+
ZST {},
1277+
ZST {},
1278+
ZST {},
1279+
ZST {},
1280+
ZST {},
1281+
ZST {},
1282+
ZST {},
1283+
ZST {},
1284+
ZST {},
1285+
ZST {},
1286+
ZST {},
1287+
ZST {},
1288+
ZST {}
1289+
];
12431290
let mut iter2 = a3.iter_mut();
12441291
unsafe {
1245-
assert_eq!(iter2.__iterator_get_unchecked(2), &ZST {});
1292+
assert_eq!(iter2.__iterator_get_unchecked(13), &ZST {});
12461293
}
12471294
}
12481295

@@ -1460,13 +1507,59 @@ fn into_iter() {
14601507
let iter3 = iter2.clone();
14611508
assert_eq!(iter2.as_slice(), iter3.as_slice());
14621509
// Needs to work properly with ZSTs too of course.
1463-
let a5 = staticvec![CloneableZST, CloneableZST, CloneableZST, CloneableZST, CloneableZST, CloneableZST];
1510+
let a5 = staticvec![
1511+
CloneableZST,
1512+
CloneableZST,
1513+
CloneableZST,
1514+
CloneableZST,
1515+
CloneableZST,
1516+
CloneableZST,
1517+
CloneableZST,
1518+
CloneableZST,
1519+
CloneableZST,
1520+
CloneableZST,
1521+
CloneableZST,
1522+
CloneableZST,
1523+
CloneableZST,
1524+
CloneableZST,
1525+
CloneableZST,
1526+
CloneableZST
1527+
];
14641528
let mut iter4 = a5.into_iter();
14651529
iter4.nth(0);
14661530
iter4.next_back();
14671531
iter4.next();
1468-
let iter5 = iter4.clone();
1469-
assert_eq!(iter4.as_slice(), iter5.as_slice());
1532+
let mut iter5 = iter4.clone();
1533+
assert_eq!(iter4.as_slice(), iter5.as_slice());
1534+
for x in iter4.as_slice().iter() {
1535+
assert_eq!(x, &CloneableZST);
1536+
}
1537+
for y in iter5.as_mut_slice().iter_mut() {
1538+
assert_eq!(y, &mut CloneableZST);
1539+
}
1540+
let mut i = 0;
1541+
for x in staticvec![
1542+
CloneableZST,
1543+
CloneableZST,
1544+
CloneableZST,
1545+
CloneableZST,
1546+
CloneableZST,
1547+
CloneableZST,
1548+
CloneableZST,
1549+
CloneableZST,
1550+
CloneableZST,
1551+
CloneableZST,
1552+
CloneableZST,
1553+
CloneableZST,
1554+
CloneableZST,
1555+
CloneableZST,
1556+
CloneableZST,
1557+
CloneableZST
1558+
] {
1559+
assert_eq!(x, CloneableZST);
1560+
i += 1;
1561+
}
1562+
assert_eq!(i, 16);
14701563
}
14711564

14721565
#[test]

0 commit comments

Comments
 (0)