Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the genericity of closures in the iterator traits #62429

Merged
merged 24 commits into from
Aug 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e67620a
Reduce the genericity of closures in the iterator traits
cuviper Jul 6, 2019
95e2a4f
Use if-let in is_sorted_by
cuviper Jul 6, 2019
af1bfbe
Explicitly test Iterator::count overflows
cuviper Jul 8, 2019
6a04c76
Explicitly test Iterator::position overflows
cuviper Jul 8, 2019
755c091
Add codegen tests for the genericity of fold closures
cuviper Jul 8, 2019
0e300e4
Reduce the genericity of Map folds
cuviper Jul 8, 2019
7539fc6
Reduce genericity in Iterator::last
cuviper Jul 11, 2019
40ecbc7
Avoid closures in OnceWith and Successors
cuviper Jul 11, 2019
9ef95ff
Reduce genericity in FlattenCompat
cuviper Jul 11, 2019
27ddbf4
Avoid closures in the default <Zip as ZipImpl>::next
cuviper Jul 11, 2019
d940ddf
Reduce genericity in Copied and Cloned
cuviper Jul 11, 2019
b1fd3d0
Remove genericity in StepBy::size_hint
cuviper Jul 11, 2019
ac113f0
Reduce genericity in Filter and FilterMap
cuviper Jul 12, 2019
df3d686
Reduce genericity in Enumerate
cuviper Jul 12, 2019
ff60eca
Avoid closures in Peekable
cuviper Jul 12, 2019
5902522
Reduce genericity in SkipWhile
cuviper Jul 12, 2019
2d7fc4d
Reduce genericity in TakeWhile
cuviper Jul 12, 2019
46a62ca
Reduce genericity in Skip
cuviper Jul 12, 2019
0f82c0c
Reduce genericity in Take
cuviper Jul 12, 2019
f100354
Reduce genericity in Scan
cuviper Jul 12, 2019
fc4d037
Reduce genericity in Inspect
cuviper Jul 12, 2019
9c53396
Move run-pass/iter-map-fold-type-length.rs to iterators/
cuviper Jul 12, 2019
c4189a0
Move run-pass/iterators/* to ui/iterators/
cuviper Jul 12, 2019
bca6f28
Force optimization in 32-bit iter overflow tests
cuviper Aug 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 52 additions & 26 deletions src/libcore/iter/adapters/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,16 @@ where
if let elt@Some(_) = inner.next() { return elt }
}
match self.iter.next() {
None => return self.backiter.as_mut().and_then(|it| it.next()),
None => return self.backiter.as_mut()?.next(),
Some(inner) => self.frontiter = Some(inner.into_iter()),
}
}
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
let lo = flo.saturating_add(blo);
match (self.iter.size_hint(), fhi, bhi) {
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
Expand All @@ -250,20 +250,25 @@ where
fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
{
#[inline]
fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
frontiter: &'a mut Option<T::IntoIter>,
fold: &'a mut impl FnMut(Acc, T::Item) -> R,
) -> impl FnMut(Acc, T) -> R + 'a {
move |acc, x| {
let mut mid = x.into_iter();
let r = mid.try_fold(acc, &mut *fold);
*frontiter = Some(mid);
r
}
}

if let Some(ref mut front) = self.frontiter {
init = front.try_fold(init, &mut fold)?;
}
self.frontiter = None;

{
let frontiter = &mut self.frontiter;
init = self.iter.try_fold(init, |acc, x| {
let mut mid = x.into_iter();
let r = mid.try_fold(acc, &mut fold);
*frontiter = Some(mid);
r
})?;
}
init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
self.frontiter = None;

if let Some(ref mut back) = self.backiter {
Expand All @@ -275,13 +280,20 @@ where
}

#[inline]
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn flatten<U: Iterator, Acc>(
fold: &mut impl FnMut(Acc, U::Item) -> Acc,
) -> impl FnMut(Acc, U) -> Acc + '_ {
move |acc, iter| iter.fold(acc, &mut *fold)
}

self.frontiter.into_iter()
.chain(self.iter.map(IntoIterator::into_iter))
.chain(self.backiter)
.fold(init, |acc, iter| iter.fold(acc, &mut fold))
.fold(init, flatten(fold))
}
}

Expand All @@ -297,7 +309,7 @@ where
if let elt@Some(_) = inner.next_back() { return elt }
}
match self.iter.next_back() {
None => return self.frontiter.as_mut().and_then(|it| it.next_back()),
None => return self.frontiter.as_mut()?.next_back(),
next => self.backiter = next.map(IntoIterator::into_iter),
}
}
Expand All @@ -307,20 +319,27 @@ where
fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
{
if let Some(ref mut back) = self.backiter {
init = back.try_rfold(init, &mut fold)?;
}
self.backiter = None;

#[inline]
fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
backiter: &'a mut Option<T::IntoIter>,
fold: &'a mut impl FnMut(Acc, T::Item) -> R,
) -> impl FnMut(Acc, T) -> R + 'a where
T::IntoIter: DoubleEndedIterator,
{
let backiter = &mut self.backiter;
init = self.iter.try_rfold(init, |acc, x| {
move |acc, x| {
let mut mid = x.into_iter();
let r = mid.try_rfold(acc, &mut fold);
let r = mid.try_rfold(acc, &mut *fold);
*backiter = Some(mid);
r
})?;
}
}

if let Some(ref mut back) = self.backiter {
init = back.try_rfold(init, &mut fold)?;
}
self.backiter = None;

init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
self.backiter = None;

if let Some(ref mut front) = self.frontiter {
Expand All @@ -332,12 +351,19 @@ where
}

#[inline]
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc,
{
#[inline]
fn flatten<U: DoubleEndedIterator, Acc>(
fold: &mut impl FnMut(Acc, U::Item) -> Acc,
) -> impl FnMut(Acc, U) -> Acc + '_ {
move |acc, iter| iter.rfold(acc, &mut *fold)
}

self.frontiter.into_iter()
.chain(self.iter.map(IntoIterator::into_iter))
.chain(self.backiter)
.rfold(init, |acc, iter| iter.rfold(acc, &mut fold))
.rfold(init, flatten(fold))
}
}
Loading