Commit graph

385 commits

Author SHA1 Message Date
bors
6c943bad02 Auto merge of #99541 - timvermeulen:flatten_cleanup, r=the8472
Refactor iteration logic in the `Flatten` and `FlatMap` iterators

The `Flatten` and `FlatMap` iterators both delegate to `FlattenCompat`:
```rust
struct FlattenCompat<I, U> {
    iter: Fuse<I>,
    frontiter: Option<U>,
    backiter: Option<U>,
}
```
Every individual iterator method that `FlattenCompat` implements needs to carefully manage this state, checking whether the `frontiter` and `backiter` are present, and storing the current iterator appropriately if iteration is aborted. This has led to methods such as `next`, `advance_by`, and `try_fold` all having similar code for managing the iterator's state.

I have extracted this common logic of iterating the inner iterators with the option to exit early into a `iter_try_fold` method:
```rust
impl<I, U> FlattenCompat<I, U>
where
    I: Iterator<Item: IntoIterator<IntoIter = U>>,
{
    fn iter_try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
    where
        Fold: FnMut(Acc, &mut U) -> R,
        R: Try<Output = Acc>,
    { ... }
}
```
It passes each of the inner iterators to the given function as long as it keep succeeding. It takes care of managing `FlattenCompat`'s state, so that the actual `Iterator` methods don't need to. The resulting code that makes use of this abstraction is much more straightforward:
```rust
fn next(&mut self) -> Option<U::Item> {
    #[inline]
    fn next<U: Iterator>((): (), iter: &mut U) -> ControlFlow<U::Item> {
        match iter.next() {
            None => ControlFlow::CONTINUE,
            Some(x) => ControlFlow::Break(x),
        }
    }

    self.iter_try_fold((), next).break_value()
}
```
Note that despite being implemented in terms of `iter_try_fold`, `next` is still able to benefit from `U`'s `next` method. It therefore does not take the performance hit that implementing `next` directly in terms of `Self::try_fold` causes (in some benchmarks).

This PR also adds `iter_try_rfold` which captures the shared logic of `try_rfold` and `advance_back_by`, as well as `iter_fold` and `iter_rfold` for folding without early exits (used by `fold`, `rfold`, `count`, and `last`).

Benchmark results:
```
                                             before                after
bench_flat_map_sum                       423,255 ns/iter      414,338 ns/iter
bench_flat_map_ref_sum                 1,942,139 ns/iter    2,216,643 ns/iter
bench_flat_map_chain_sum               1,616,840 ns/iter    1,246,445 ns/iter
bench_flat_map_chain_ref_sum           4,348,110 ns/iter    3,574,775 ns/iter
bench_flat_map_chain_option_sum          780,037 ns/iter      780,679 ns/iter
bench_flat_map_chain_option_ref_sum    2,056,458 ns/iter      834,932 ns/iter
```

I added the last two benchmarks specifically to demonstrate an extreme case where `FlatMap::next` can benefit from custom internal iteration of the outer iterator, so take it with a grain of salt. We should probably do a perf run to see if the changes to `next` are worth it in practice.
2022-08-19 02:34:30 +00:00
austinabell
00bc9e8ac4
fix(iter::skip): Optimize next and nth implementations of Skip 2022-08-14 13:25:13 -04:00
Maybe Waffle
5fbcde1b55 fill-in tracking issue for feature(iter_array_chunks) 2022-08-12 15:04:29 +04:00
Maybe Waffle
eb6b729545 address review comments 2022-08-12 14:57:15 +04:00
Tim Vermeulen
38bb0b173e Move rfold logic into iter_rfold 2022-08-05 03:43:39 +02:00
Tim Vermeulen
3f7004920c Move fold logic to iter_fold method and reuse it in count and last 2022-08-05 03:43:39 +02:00
Tim Vermeulen
cbc5f62782 Move shared logic of try_rfold and advance_back_by into iter_try_rfold 2022-08-05 03:43:39 +02:00
Tim Vermeulen
8ff8d05279 Move shared logic of try_fold and advance_by into iter_try_fold 2022-08-05 03:43:39 +02:00
Maybe Waffle
756bd6e3a3 Use next_chunk in ArrayChunks impl 2022-08-02 10:46:43 +04:00
Maybe Waffle
475e4ba747 Simplify ArrayChunks::{,r}fold impls 2022-08-01 19:17:01 +04:00
Maybe Waffle
4c0292cff5 Simplify ArrayChunks::is_empty 2022-08-01 19:17:01 +04:00
Maybe Waffle
37dfb04317 Remove Fuse from ArrayChunks implementation
It doesn't seem to be used at all.
2022-08-01 19:16:56 +04:00
Maybe Waffle
3102b39daa Use #[track_caller] to make panic in Iterator::array_chunks nicer 2022-08-01 19:16:36 +04:00
Maybe Waffle
4db628a801 Remove incorrect impl TrustedLen for ArrayChunks
As explained in the review of the previous attempt to add `ArrayChunks`,
adapters that shrink the length can't implement `TrustedLen`.
2022-08-01 19:16:24 +04:00
Maybe Waffle
b8b14864c0 Forward ArrayChunks::next{,_back} to try_{for_each,rfold}
(suggested in the review of the previous attempt to add `ArrayChunks`)
2022-08-01 18:26:18 +04:00
Maybe Waffle
ef72349e38 Remove array::IntoIter::with_partial -- an artifact of the past, once used to create an IntoIter from its parts 2022-08-01 17:00:51 +04:00
Ross MacArthur
f5485181ca Use array::IntoIter for the ArrayChunks remainder 2022-08-01 16:39:30 +04:00
Ross MacArthur
ca3d1010bb Add Iterator::array_chunks() 2022-08-01 16:39:27 +04:00
Tim Vermeulen
50c612faef Fix Skip::next for non-fused inner iterators 2022-07-18 21:10:47 +02:00
The 8472
3fcf84a68e clarify that ExactSizeIterator::len returns the remaining length 2022-06-30 19:45:36 +02:00
Dylan DPC
ff223ff297
Rollup merge of #98430 - camsteffen:flatten-refactor, r=joshtriplett
Refactor iter adapters with less macros

Just some code cleanup. Introduced a util `and_then_or_clear` for each of chain, flatten and fuse iter adapter impls. This reduces code nicely for flatten, but admittedly the other modules are more of a lateral move replacing macros with a function. But I think consistency across the modules and avoiding macros when possible is good.
2022-06-28 15:30:05 +05:30
Cameron Steffen
6587dda39e Refactor iter adapters with less macros 2022-06-22 17:44:39 -05:00
Ross MacArthur
bbdff1fff4
Add Iterator::next_chunk 2022-06-21 08:57:02 +02:00
Paolo Barbolini
ce3b6f505e Expose iter::ByRefSized as unstable feature and use it 2022-06-18 00:03:54 +02:00
Chayim Refael Friedman
456f1ffe12 Suggest using iter() or into_iter() for Vec
We cannot do that for `&Vec` because `#[rustc_on_unimplemented]` is limited (it does not clean generic instantiation for references, only for ADTs).
2022-06-08 11:09:08 +00:00
Vadim Petrochenkov
5bf23f64cc libcore: Add iter::from_generator which is like iter::from_fn, but for coroutines instead of functions 2022-05-27 01:51:31 +03:00
bors
9fbbe75fd7 Auto merge of #95602 - scottmcm:faster-array-intoiter-fold, r=the8472
Fix `array::IntoIter::fold` to use the optimized `Range::fold`

It was using `Iterator::by_ref` in the implementation, which ended up pessimizing it enough that, for example, it didn't vectorize when we tried it in the <https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd/topic/Reducing.20sum.20into.20wider.20types> conversation.

Demonstration that the codegen test doesn't pass on the current nightly: <https://rust.godbolt.org/z/Taxev5eMn>
2022-05-14 03:12:53 +00:00
Scott McMurray
e8fc7ba6a7 Slap #[inline] on all the ByRefSized methods, per the8472's suggestion 2022-05-13 00:43:15 -07:00
León Orell Valerian Liehr
9d157ada35 Warn on unused doc(hidden) on trait impl items 2022-05-08 22:53:14 +02:00
The 8472
a68a5d219d This aligns the inline attributes of existing __iterator_get_unchecked with those of next() on adapters that have both.
It improves the performance of iterators using unchecked access when building in incremental mode
(due to the larger CGU count?). It might negatively affect incremental compile times for better runtime results,
but considering that the equivalent `next()` implementations also are `#[inline]` and usually are more complex this
should be ok.

```
./x.py bench library/core -i --stage 0 --test-args bench_trusted_random_access

OLD: 119,172 ns/iter
NEW:  17,714 ns/iter
```
2022-05-02 20:54:46 +02:00
Dylan DPC
2c1d58b8cc
Rollup merge of #96480 - user-simon:patch-1, r=Dylan-DPC
Fixed grammatical error in example comment

Added missing "we" in sentence.
2022-04-28 20:13:03 +02:00
Simon
332f326334
Fixed grammatical error in example comment 2022-04-27 17:27:02 +02:00
Michael Goulet
83d701e569 Better error messages when collecting into [T; n] 2022-04-26 21:37:10 -07:00
bors
6b4563bf93 Auto merge of #90602 - mbartlett21:const-intoiterator, r=oli-obk
Unstably constify `impl<I: Iterator> IntoIterator for I`

This constifies the default `IntoIterator` implementation under the `const_intoiterator_identity` feature.

Tracking Issue: #90603
2022-04-23 15:41:45 +00:00
Boyd Kane
d73e32867f
Remove trailing whitespace
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2022-04-14 11:19:49 +02:00
Boyd Kane
f6d957701f
docs: add link from zip to unzip
The docs for `Iterator::unzip` explain that it is kind of an inverse operation to `Iterator::zip` and guide the reader to the `zip` docs, but the `zip` docs don't let the user know that they can undo the `zip` operation with `unzip`. This change modifies the docs to help the user find `unzip`.
2022-04-14 09:51:47 +02:00
Scott McMurray
83595f9242 Fix array::IntoIter::fold to use the optimized Range::fold
It was using `Iterator::by_ref` in the implementation, which ended up pessimizing it enough that, for example, it didn't vectorize when we tried it in the <https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd/topic/Reducing.20sum.20into.20wider.20types> conversation.

Demonstration that the codegen test doesn't pass on the current nightly: <https://rust.godbolt.org/z/Taxev5eMn>
2022-04-02 14:29:41 -07:00
dlup
15134249f4 Remove mention of HashMap<K, V> not offering iter_mut 2022-03-26 02:05:34 -04:00
bors
6970f88db3 Auto merge of #87667 - the8472:document-in-place-iter, r=yaahc
add module-level documentation for vec's in-place iteration

As requested in the last libs team meeting and during previous reviews.

Feel free to point out any gaps you encounter, after all non-obvious things may with hindsight seem obvious to me.

r? `@yaahc`

CC `@steffahn`
2022-03-24 01:43:21 +00:00
Andre Bogus
1fb43f6662 add perf side effect docs to Iterator::cloned() 2022-03-22 19:07:23 +01:00
The8472
a1a602adde add module-level documentation for vec's in-place iteration 2022-03-21 22:29:38 +01:00
Matthias Krüger
c183d4a510
Rollup merge of #94115 - scottmcm:iter-process-by-ref, r=yaahc
Let `try_collect` take advantage of `try_fold` overrides

No public API changes.

With this change, `try_collect` (#94047) is no longer going through the `impl Iterator for &mut impl Iterator`, and thus will be able to use `try_fold` overrides instead of being forced through `next` for every element.

Here's the test added, to see that it fails before this PR (once a new enough nightly is out): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=462f2896f2fed2c238ee63ca1a7e7c56

This might as well go to the same person as my last `try_process` PR  (#93572), so
r? ``@yaahc``
2022-03-18 21:50:44 +01:00
mbartlett21
91eda96e38 Unstably constify impl IntoIterator for I: ~const Iterator 2022-03-15 06:07:18 +00:00
Dylan DPC
5a7f09d9a3
Rollup merge of #93950 - T-O-R-U-S:use-modern-formatting-for-format!-macros, r=Mark-Simulacrum
Use modern formatting for format! macros

This updates the standard library's documentation to use the new format_args syntax.
The documentation is worthwhile to update as it should be more idiomatic
(particularly for features like this, which are nice for users to get acquainted
with). The general codebase is likely more hassle than benefit to update: it'll
hurt git blame, and generally updates can be done by folks updating the code if
(and when) that makes things more readable with the new format.

A few places in the compiler and library code are updated (mostly just due to
already having been done when this commit was first authored).

`eprintln!("{}", e)` becomes `eprintln!("{e}")`, but `eprintln!("{}", e.kind())` remains untouched.
2022-03-10 23:12:57 +01:00
Matthias Krüger
b5127202b2
Rollup merge of #94587 - JKAnderson409:issue-90107-fix, r=scottmcm
Document new recommended use of `FromIterator::from_iter`

#90107
Most of the added prose was paraphrased from the links provided in the issue. The suggested `VecDeque` example seemed to make the point well enough so I just used that.
2022-03-10 19:00:06 +01:00
T-O-R-U-S
72a25d05bf Use implicit capture syntax in format_args
This updates the standard library's documentation to use the new syntax. The
documentation is worthwhile to update as it should be more idiomatic
(particularly for features like this, which are nice for users to get acquainted
with). The general codebase is likely more hassle than benefit to update: it'll
hurt git blame, and generally updates can be done by folks updating the code if
(and when) that makes things more readable with the new format.

A few places in the compiler and library code are updated (mostly just due to
already having been done when this commit was first authored).
2022-03-10 10:23:40 -05:00
Matthias Krüger
e7281d08de
Rollup merge of #94746 - notriddle:notriddle/method-rustc-on-unimplemented, r=davidtwco
diagnostics: use rustc_on_unimplemented to recommend `[].iter()`

To make this work, the `#[rustc_on_unimplemented]` data needs to be used to
report method resolution errors, which is most of what this commit does.

Fixes #94581
2022-03-10 12:20:53 +01:00
Scott McMurray
7ef74bc8b9 Let try_collect take advantage of try_fold overrides
Without this change it's going through `&mut impl Iterator`, which handles `?Sized` and thus currently can't forward generics.

Here's the test added, to see that it fails before this PR (once a new enough nightly is out): https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=462f2896f2fed2c238ee63ca1a7e7c56
2022-03-10 00:16:06 -08:00
Matthias Krüger
d5c05fcc8a
Rollup merge of #93057 - frengor:iter_collect_into, r=m-ou-se
Add Iterator::collect_into

This PR adds `Iterator::collect_into` as proposed by ``@cormacrelf`` in #48597 (see https://github.com/rust-lang/rust/pull/48597#issuecomment-842083688).
Followup of #92982.

This adds the following method to the Iterator trait:

```rust
fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E
```
2022-03-09 23:14:11 +01:00
fren_gor
63eddb3e68
Add tracking issue 2022-03-09 21:12:07 +01:00