Skip to content

Commit 89e4193

Browse files
authored
add missing Iterator::size_hint overrides, most of which cause ExactSizeIterator::len to panic (#22035)
# Objective - Fixes `ExactSizeIterator::len` panic in a few of these iterators. Note: the std default impl of `ExactSizeIterator::len` has `assert_eq!(Some(lower), upper);`. I am facing this issue myself with `<index_set::Iter as ExactSizeIterator>::len`. - Should slightly improve performance in some cases, where the more precise `size_hint` causes less allocations (for example when collecting into a `Vec`) ## Solution - Add `size_hint` overrides that forward to inner iterators or an `ExactSizeIterator::len` override in one specific case. ## Testing - Since the overrides are pretty simple, I mostly didn't add any tests. - I didn't feel 100% confident in the `WriteBatchIds::size_hint` implementation, so I added a test there.
1 parent 25d4ced commit 89e4193

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

crates/bevy_ecs/src/entity/hash_map.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ impl<'a, V> Iterator for Keys<'a, V> {
176176
fn next(&mut self) -> Option<Self::Item> {
177177
self.0.next()
178178
}
179+
180+
fn size_hint(&self) -> (usize, Option<usize>) {
181+
self.0.size_hint()
182+
}
179183
}
180184

181185
impl<V> ExactSizeIterator for Keys<'_, V> {}
@@ -234,6 +238,10 @@ impl<V> Iterator for IntoKeys<V> {
234238
fn next(&mut self) -> Option<Self::Item> {
235239
self.0.next()
236240
}
241+
242+
fn size_hint(&self) -> (usize, Option<usize>) {
243+
self.0.size_hint()
244+
}
237245
}
238246

239247
impl<V> ExactSizeIterator for IntoKeys<V> {}

crates/bevy_ecs/src/entity/hash_set.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ impl<'a> Iterator for Iter<'a> {
238238
fn next(&mut self) -> Option<Self::Item> {
239239
self.0.next()
240240
}
241+
242+
fn size_hint(&self) -> (usize, Option<usize>) {
243+
self.0.size_hint()
244+
}
241245
}
242246

243247
impl ExactSizeIterator for Iter<'_> {}
@@ -293,6 +297,10 @@ impl Iterator for IntoIter {
293297
fn next(&mut self) -> Option<Self::Item> {
294298
self.0.next()
295299
}
300+
301+
fn size_hint(&self) -> (usize, Option<usize>) {
302+
self.0.size_hint()
303+
}
296304
}
297305

298306
impl ExactSizeIterator for IntoIter {}
@@ -345,6 +353,10 @@ impl<'a> Iterator for Drain<'a> {
345353
fn next(&mut self) -> Option<Self::Item> {
346354
self.0.next()
347355
}
356+
357+
fn size_hint(&self) -> (usize, Option<usize>) {
358+
self.0.size_hint()
359+
}
348360
}
349361

350362
impl ExactSizeIterator for Drain<'_> {}
@@ -394,6 +406,10 @@ impl<'a, F: FnMut(&Entity) -> bool> Iterator for ExtractIf<'a, F> {
394406
fn next(&mut self) -> Option<Self::Item> {
395407
self.0.next()
396408
}
409+
410+
fn size_hint(&self) -> (usize, Option<usize>) {
411+
self.0.size_hint()
412+
}
397413
}
398414

399415
impl<F: FnMut(&Entity) -> bool> FusedIterator for ExtractIf<'_, F> {}

crates/bevy_ecs/src/entity/index_map.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,10 @@ impl<'a, V> Iterator for Iter<'a, V> {
861861
fn next(&mut self) -> Option<Self::Item> {
862862
self.0.next()
863863
}
864+
865+
fn size_hint(&self) -> (usize, Option<usize>) {
866+
self.0.size_hint()
867+
}
864868
}
865869

866870
impl<V> DoubleEndedIterator for Iter<'_, V> {
@@ -934,6 +938,10 @@ impl<'a, V> Iterator for IterMut<'a, V> {
934938
fn next(&mut self) -> Option<Self::Item> {
935939
self.0.next()
936940
}
941+
942+
fn size_hint(&self) -> (usize, Option<usize>) {
943+
self.0.size_hint()
944+
}
937945
}
938946

939947
impl<V> DoubleEndedIterator for IterMut<'_, V> {
@@ -1004,6 +1012,10 @@ impl<V> Iterator for IntoIter<V> {
10041012
fn next(&mut self) -> Option<Self::Item> {
10051013
self.0.next()
10061014
}
1015+
1016+
fn size_hint(&self) -> (usize, Option<usize>) {
1017+
self.0.size_hint()
1018+
}
10071019
}
10081020

10091021
impl<V> DoubleEndedIterator for IntoIter<V> {
@@ -1072,6 +1084,10 @@ impl<V> Iterator for Drain<'_, V> {
10721084
fn next(&mut self) -> Option<Self::Item> {
10731085
self.0.next()
10741086
}
1087+
1088+
fn size_hint(&self) -> (usize, Option<usize>) {
1089+
self.0.size_hint()
1090+
}
10751091
}
10761092

10771093
impl<V> DoubleEndedIterator for Drain<'_, V> {
@@ -1120,6 +1136,10 @@ impl<'a, V> Iterator for Keys<'a, V> {
11201136
fn next(&mut self) -> Option<Self::Item> {
11211137
self.0.next()
11221138
}
1139+
1140+
fn size_hint(&self) -> (usize, Option<usize>) {
1141+
self.0.size_hint()
1142+
}
11231143
}
11241144

11251145
impl<V> DoubleEndedIterator for Keys<'_, V> {
@@ -1188,6 +1208,10 @@ impl<V> Iterator for IntoKeys<V> {
11881208
fn next(&mut self) -> Option<Self::Item> {
11891209
self.0.next()
11901210
}
1211+
1212+
fn size_hint(&self) -> (usize, Option<usize>) {
1213+
self.0.size_hint()
1214+
}
11911215
}
11921216

11931217
impl<V> DoubleEndedIterator for IntoKeys<V> {

crates/bevy_ecs/src/entity/index_set.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,10 @@ impl<'a> Iterator for Iter<'a> {
582582
fn next(&mut self) -> Option<Self::Item> {
583583
self.0.next()
584584
}
585+
586+
fn size_hint(&self) -> (usize, Option<usize>) {
587+
self.0.size_hint()
588+
}
585589
}
586590

587591
impl DoubleEndedIterator for Iter<'_> {
@@ -651,6 +655,10 @@ impl Iterator for IntoIter {
651655
fn next(&mut self) -> Option<Self::Item> {
652656
self.0.next()
653657
}
658+
659+
fn size_hint(&self) -> (usize, Option<usize>) {
660+
self.0.size_hint()
661+
}
654662
}
655663

656664
impl DoubleEndedIterator for IntoIter {
@@ -723,6 +731,10 @@ impl<'a> Iterator for Drain<'a> {
723731
fn next(&mut self) -> Option<Self::Item> {
724732
self.0.next()
725733
}
734+
735+
fn size_hint(&self) -> (usize, Option<usize>) {
736+
self.0.size_hint()
737+
}
726738
}
727739

728740
impl DoubleEndedIterator for Drain<'_> {

crates/bevy_ecs/src/message/messages.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ impl<E: Message> Iterator for WriteBatchIds<E> {
382382

383383
result
384384
}
385+
386+
fn size_hint(&self) -> (usize, Option<usize>) {
387+
let len = <Self as ExactSizeIterator>::len(self);
388+
(len, Some(len))
389+
}
385390
}
386391

387392
impl<E: Message> ExactSizeIterator for WriteBatchIds<E> {
@@ -425,4 +430,19 @@ mod tests {
425430
assert_eq!(test_messages.len(), 2); // Messages are double-buffered, so we see 2 + 0 = 2
426431
assert_eq!(test_messages.iter_current_update_messages().count(), 0);
427432
}
433+
434+
#[test]
435+
fn write_batch_iter_size_hint() {
436+
#[derive(Message, Clone, Copy)]
437+
struct TestMessage;
438+
439+
let mut test_messages = Messages::<TestMessage>::default();
440+
let write_batch_ids = test_messages.write_batch([TestMessage; 4]);
441+
let expected_len = 4;
442+
assert_eq!(write_batch_ids.len(), expected_len);
443+
assert_eq!(
444+
write_batch_ids.size_hint(),
445+
(expected_len, Some(expected_len))
446+
);
447+
}
428448
}

crates/bevy_mesh/src/index.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ where
3333
FourIterators::Fourth(iter) => iter.next(),
3434
}
3535
}
36+
37+
fn size_hint(&self) -> (usize, Option<usize>) {
38+
match self {
39+
FourIterators::First(iter) => iter.size_hint(),
40+
FourIterators::Second(iter) => iter.size_hint(),
41+
FourIterators::Third(iter) => iter.size_hint(),
42+
FourIterators::Fourth(iter) => iter.size_hint(),
43+
}
44+
}
3645
}
3746

3847
/// An error that occurred while trying to invert the winding of a [`Mesh`](super::Mesh).

0 commit comments

Comments
 (0)