Recently, I was trying to implement a generic function that takes any type that can return an iterator without consuming the type. IntoIterator was insufficient for my use case, because I need to be able to re-use the Self type / iterate multiple times.
Most of the collection types in std::collections already have an iter() method that iterates over members of the collection without consuming it. I wrote a trait to generalize over all of these, only to later find that somebody else had this same problem, documented it, and solved it.
I wanted to know if there has been any consideration for including this in the standard library. It seems like an obvious and nearly universally useful thing to have. Other people have had this problem and it seems like an obvious and universally useful thing for the standard library to have.
This is really a question phrased as a short essay. Thoughts?
It would be kind of nice if this question answered itself in some way. If not by having inherent methods literally generate the trait impl via some attribute, at least the docs could be linked.
Okay I don't know how you generate all of impl<'a, T, A> IntoIterator for &'a Vec<T, A> { ... } out of an attribute on a pub fn iter(&self) -> Iter<'_, T> { ... } in any sort of ergonomic way, but the docs should definitely be linked together, ideally somewhat automatically.
Theoretically, in the function context you *could" just say impl IntoIterator for &'_ Self (where '_ is actually tied to the '_ in .iter()'s signature), but that functionality doesn't actually exist currently, it's just a theoretical possibility.
A second option for discoverability would be to introduce a trait alias
trait Iterable<'a> = where &'a Self: IntoIterator;
Most of the time though the answer is actually to take impl Copy + IntoIterator instead of &(impl Iterable + ?Sized). Taking impl Iterable directly is even worse since you're asking to receive ownership of e.g. Vec without being able to utilize the ownership; if you're only going to use the value by reference, take it by reference.
(I still hold that functions taking impl AsRef is a mis-design that we're stuck with and leads early devs passing clones unnecessarily where just using a reference would be sufficient.)
The awful thing about this one IMO is that pre-1.0 std use to have the correct pattern[1] for not taking ownership with a &self-methods-only trait bound: