Repository: rust
Issue: Tracking Issue for `Iterator::try_collect`
Labels: T-libs-api,C-tracking-issue

<!--
Thank you for creating a tracking issue!

Tracking issues are for tracking a feature from implementation to stabilization.

Make sure to include the relevant RFC for the feature if it has one.

If the new feature is small, it may be fine to skip the RFC process. In that
case, you can use use `issue = "none"` in your initial implementation PR. The
reviewer will ask you to open a tracking issue if they agree your feature can be
added without an RFC.
-->

Feature gate: `#![feature(iterator_try_collect)]`

This is a tracking issue for adding the `try_collect()` method to the `Iterator` trait, as originally discussed [here](https://internals.rust-lang.org/t/idea-fallible-iterator-mapping-with-try-map/15715?u=scottmcm). `Iterator::try_collect()` is a fallible variation of `Iterator::collect()` analogous to similar methods for `reduce` and `fold`, among others, that provides a simpler, generic way to collect iterators of `Try` elements into `Try`-wrapped types.

### Difference from `Iterator::collect`

In terms of functionality, the main difference between `try_collect()` and `collect()` is that `try_collect()` allows you to fallibly collect iterators yielding types that implement `Try` but not `FromIterator`, which `collect()` can't do. Concretely this means you can `try_collect()` iterators yielding `ControlFlow<_, i32>` into `ControlFlow<_, Vec<i32>>`, which you can't do with `collect()`.

It's also a `&mut self` method instead of `collect`'s `self`, so that you can resume iteration after it early exits on an error.  (Like how `try_fold` is `&mut self` while `fold` is just `self`.)

Another benefit of `try_collect()` is discoverability. Because the discoverability of the "collect-into-`Result`" appears to be lower than desired, "promoting" the technique into its own method seems like a good way to increase its discoverability and reach more users who would find it useful.  (One of many examples of people just not being able to find the `Option: FromIterator` themselves: <https://users.rust-lang.org/t/try-collect-as-iter-consuming-operation/20479?u=scottmcm>.)

Finally, `try_collect()` presents a small ergonomics benefit in terms of type hints when collecting, namely that you only have to hint at the output type you're collecting into, not the whole `Try` type. For example, that means you can collect an iterator yielding `Result<i32, SomeComplicatedError>` with `try_collect::<Vec<_>>()`, as opposed to having to specify the whole `Result` with `collect::<Result<Vec<_>, _>>()`.

### Public API

<!--
For most library features, it'd be useful to include a summarized version of the public API.
(E.g. just the public function signatures without their doc comments or implementation.)
-->

```rust
trait Iterator {
    type Item;

    fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B>
    where
        Self: Sized,
        <Self as Iterator>::Item: Try,
        <<Self as Iterator>::Item as Try>::Residual: Residual<B>,
        B: FromIterator<<Self::Item as Try>::Output>;
}
```

### Steps / History

- [x] Implementation: #94041
- [ ] Final comment period (FCP)
- [ ] Stabilization PR

<!--
Once the feature has gone through a few release cycles and there are no
unresolved questions left, the feature might be ready for stabilization.

If this feature didn't go through the RFC process, a final comment period
(FCP) is always needed before stabilization. This works as follows:

A library API team member can kick off the stabilization process, at which point
the rfcbot will ask all the team members to verify they agree with
stabilization. Once enough members agree and there are no concerns, the final
comment period begins: this issue will be marked as such and will be listed
in the next This Week in Rust newsletter. If no blocking concerns are raised in
that period of 10 days, a stabilzation PR can be opened by anyone.
-->

### Unresolved Questions

<!--
Include any open questions that need to be answered before the feature can be
stabilised. If multiple (unrelated) big questions come up, it can be a good idea
to open a separate issue for each, to make it easier to keep track of the
discussions.

It's useful to link any relevant discussions and conclusions (whether on GitHub,
Zulip, or the internals forum) here.
-->

- [ ] Should it have a more complicated signature to be able to return the partial results too? (@CAD97  https://internals.rust-lang.org/t/idea-fallible-iterator-mapping-with-try-map/15715/6?u=scottmcm )
- [ ] Should it take `self` rather than `&mut self`, to prevent users from accidentally continuing to use the iterator after a `try_collect()` failure? Note that you can still continue to use the iterator if you use `by_ref()` first, so it's not necessarily a functionality change.
- [ ] Does the name `try_collect()` conflict too much with the idea of collecting that's fallible in allocation? (i.e. collecting with `Vec::try_reserve` or similar)