Skip to content

Commit a23180d

Browse files
committed
core: use specialization for more methods of impl Iterator for &mut I
...and get rid of `ByRefSized`. Most of the iterator methods can be forwarded to the inner iterator if we know that it is `Sized`, but this is currently only done for `fold` and `try_fold`. This PR adds the optimization for all applicable methods. It uses two private helper struct to hide the specialization from the public API: * `Iterator for ByRefDefault` only forwards the methods that can be used even when the iterator is not `Sized`, all other methods are left to the default. * `Iterator for ByRef` specializes on `Sized` and forwards to either the underlying iterator or to `ByRefDefault` This PR also removes `ByRefSized`, the `Iterator for &mut I` should now be good enough to be used everywhere.
1 parent 97fc1f6 commit a23180d

File tree

11 files changed

+588
-288
lines changed

11 files changed

+588
-288
lines changed

library/alloc/src/collections/vec_deque/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
use core::cmp::{self, Ordering};
1111
use core::hash::{Hash, Hasher};
12-
use core::iter::{ByRefSized, repeat_n, repeat_with};
12+
use core::iter::{repeat_n, repeat_with};
1313
// This is used in a bunch of intra-doc links.
1414
// FIXME: For some reason, `#[cfg(doc)]` wasn't sufficient, resulting in
1515
// failures in linkchecker even though rustdoc built the docs just fine.
@@ -477,11 +477,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
477477
unsafe { guard.deque.write_iter(dst, iter, &mut guard.written) };
478478
} else {
479479
unsafe {
480-
guard.deque.write_iter(
481-
dst,
482-
ByRefSized(&mut iter).take(head_room),
483-
&mut guard.written,
484-
);
480+
guard.deque.write_iter(dst, (&mut iter).take(head_room), &mut guard.written);
485481
guard.deque.write_iter(0, iter, &mut guard.written)
486482
};
487483
}

library/core/src/array/iter.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
260260
Fold: FnMut(Acc, Self::Item) -> Acc,
261261
{
262262
let data = &mut self.data;
263-
iter::ByRefSized(&mut self.alive).fold(init, |acc, idx| {
263+
(&mut self.alive).fold(init, |acc, idx| {
264264
// SAFETY: idx is obtained by folding over the `alive` range, which implies the
265265
// value is currently considered alive but as the range is being consumed each value
266266
// we read here will only be read once and then considered dead.
@@ -323,7 +323,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
323323
Fold: FnMut(Acc, Self::Item) -> Acc,
324324
{
325325
let data = &mut self.data;
326-
iter::ByRefSized(&mut self.alive).rfold(init, |acc, idx| {
326+
(&mut self.alive).rfold(init, |acc, idx| {
327327
// SAFETY: idx is obtained by folding over the `alive` range, which implies the
328328
// value is currently considered alive but as the range is being consumed each value
329329
// we read here will only be read once and then considered dead.

library/core/src/iter/adapters/array_chunks.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::array;
22
use crate::iter::adapters::SourceIter;
3-
use crate::iter::{
4-
ByRefSized, FusedIterator, InPlaceIterable, TrustedFused, TrustedRandomAccessNoCoerce,
5-
};
3+
use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedRandomAccessNoCoerce};
64
use crate::num::NonZero;
75
use crate::ops::{ControlFlow, NeverShortCircuit, Try};
86

@@ -128,7 +126,7 @@ where
128126
self.next_back_remainder();
129127

130128
let mut acc = init;
131-
let mut iter = ByRefSized(&mut self.iter).rev();
129+
let mut iter = (&mut self.iter).rev();
132130

133131
// NB remainder is handled by `next_back_remainder`, so
134132
// `next_chunk` can't return `Err` with non-empty remainder

0 commit comments

Comments
 (0)