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

Clarify iterator by_ref docs #135987

Merged
merged 1 commit into from
Mar 11, 2025
Merged
Changes from all commits
Commits
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
18 changes: 15 additions & 3 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -1825,10 +1825,19 @@ pub trait Iterator {
Inspect::new(self, f)
}

/// Borrows an iterator, rather than consuming it.
/// Creates a "by reference" adapter for this instance of `Iterator`.
///
/// This is useful to allow applying iterator adapters while still
/// retaining ownership of the original iterator.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this part of the diff is necessary. The one-liner at the top and the explanation seems sufficient, maybe just adding a disclaimer that the original iterator is still mutated is enough.

Copy link
Member Author

@hkBst hkBst Feb 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Borrows an iterator, rather than consuming it." is quite poorly phrased, as it is subsequent methods applied to the borrow, that will be prevented from consuming the original iterator.
"This is useful to allow applying iterator adapters while still retaining ownership of the original iterator." is also quite opaque, as it is already possible to do just that with the original iterator, except if the method happens to take self, but that crucial detail is not mentioned.

In addition to this, it is not obvious how the mutable borrow of an iterator turns into an iterator. It wasn't until I started writing this PR that I thought to myself: "wait a minute, there is no reason a mutable borrow of an iterator should be an iterator, unless there is an impl block that says so." Before that, I think I thought something like this: "I must be missing something about how mutable references work, because I don't see how this method works..." It is just like the chars method on Strings giving a Chars struct which impls iterator, except that there is no &mut impl Iterator struct to point to, therefore I think it makes sense to link to the relevant impl directly, to show that there is no magic here.

I do agree that the original iterator being mutated is still missing from my text, so I will work on that.

Copy link
Member

@ibraheemdev ibraheemdev Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you are getting at, but I feel that this is a bit wordy. Let me try rewording it. We should keep a one sentence header for rustdoc, Read::by_ref does a better job of this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, there should be a short one sentence summary at the top, can do.

/// Consuming method calls (direct or indirect calls to `next`)
/// on the "by reference" adapter will consume the original iterator,
/// but ownership-taking methods (those with a `self` parameter)
/// only take ownership of the "by reference" iterator.
///
/// This is useful for applying ownership-taking methods
/// (such as `take` in the example below)
/// without giving up ownership of the original iterator,
/// so you can use the original iterator afterwards.
///
/// Uses [impl<I: Iterator + ?Sized> Iterator for &mut I { type Item = I::Item; ...}](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#impl-Iterator-for-%26mut+I).
///
/// # Examples
///
@@ -4019,6 +4028,9 @@ where
}
}

/// Implements `Iterator` for mutable references to iterators, such as those produced by [`Iterator::by_ref`].
///
/// This implementation passes all method calls on to the original iterator.
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator + ?Sized> Iterator for &mut I {
type Item = I::Item;
Loading