Skip to content

Add PeekableIterator trait#144935

Open
wmstack wants to merge 23 commits intorust-lang:mainfrom
wmstack:PeekableIterator
Open

Add PeekableIterator trait#144935
wmstack wants to merge 23 commits intorust-lang:mainfrom
wmstack:PeekableIterator

Conversation

@wmstack
Copy link
Copy Markdown
Contributor

@wmstack wmstack commented Aug 5, 2025

Tracking issue: #132973

Implementation

pub trait PeekableIterator: Iterator {
  // required method
  fn peek_with<T>(&mut self, func: impl for<'a> FnOnce(Option<&'a Self::Item>) -> T) -> T

  // provided methods
  fn peek_map<T>(&mut self, func: impl for<'a> FnOnce(&'a Self::Item) -> T) -> Option<T>
  fn next_if(&mut self, func: impl FnOnce(&Self::Item) -> bool) -> Option<Self::Item>
  fn next_if_eq<T>(&mut self, expected: &T) -> Option<Self::Item>
  where
    Self::Item: PartialEq<T>,
    T: ?Sized,
}

Todo: Determine which structures need to implement PeekableIterator:

  • slice::iter
  • str::Chars
  • vec::IntoIter
  • Peekable<T>

Unresolved Issues:

  • Add another trait for iterators that can peek() without mutating?

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Aug 5, 2025

r? @tgross35

rustbot has assigned @tgross35.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 5, 2025
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@theemathas
Copy link
Copy Markdown
Contributor

Maybe the correct function signature is this?

fn peek<T>(&mut self, callback: impl for<'a> FnOnce(Option<&'a Self::Item>) -> T) -> T

This would mean, for example, that str::Chars would be able to implement this without having a field inside the iterator that contains a char. Instead, it would be able to create a local variable in the peek method that stores the char.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Comment on lines +485 to +488
// SAFETY: by type invariant, the `end_or_len` field is always
// non-null for a non-ZST pointee. (This transmute ensures we
// get `!nonnull` metadata on the load of the field.)
if ptr == crate::intrinsics::transmute::<$ptr, NonNull<T>>(end_or_len) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
// SAFETY: by type invariant, the `end_or_len` field is always
// non-null for a non-ZST pointee. (This transmute ensures we
// get `!nonnull` metadata on the load of the field.)
if ptr == crate::intrinsics::transmute::<$ptr, NonNull<T>>(end_or_len) {
if ptr.as_ptr() == end_or_len {

Copy link
Copy Markdown
Contributor Author

@wmstack wmstack Aug 9, 2025

Choose a reason for hiding this comment

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

Hmm, I was not able to write it this way as Rust determines the types differ in their mutability. In general, this code was based on the next() method generic over both Iter and IterMut

Copy link
Copy Markdown
Contributor

@tgross35 tgross35 Sep 3, 2025

Choose a reason for hiding this comment

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

What exactly was the error? Seems possible to resolve by adding a $as_ptr metavar that is either as_ptr or as_mut_ptr depending on which one is being implemented (like into_ref).

next is a bit magical, others should try to be simpler if possible. cloning and advancing should be fine, it's cheap.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cloning actually wouldn't work for IterMut since it doesn't implement it. But that actually brings up a good point; the safety comments need to say why it is sound to hand out a&mut T.

@rust-log-analyzer

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

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

This doesn't seem to be tested at all. Please make sure that even unstable API gets helpful examples, aside from checking the implementation they serve as a very useful smoke test for whether or not the API makes sense in the first place.

Additionally, the type-specific impls need tests in library/coretests

View changes since this review

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 3, 2025
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bluebear94
Copy link
Copy Markdown
Contributor

@wmstack Are you still open to working on this PR? If not, then I’m willing to take over the work on this.

@wmstack
Copy link
Copy Markdown
Contributor Author

wmstack commented Oct 9, 2025

@bluebear94 Feel free to pick this up as I’m tied up with coursework at the moment.

@bors
Copy link
Copy Markdown
Collaborator

bors commented Oct 14, 2025

☔ The latest upstream changes (presumably #147353) made this pull request unmergeable. Please resolve the merge conflicts.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Feb 15, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot

This comment has been minimized.

@rustbot rustbot added the has-merge-commits PR has merge commits, merge with caution. label Feb 15, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. has-merge-commits PR has merge commits, merge with caution. labels Feb 15, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

=> Removing the following docker images:
WARNING: This output is designed for human readability. For machine-readable output, please use --format.
IMAGE                                               ID             DISK USAGE   CONTENT SIZE   EXTRA
ghcr.io/dependabot/dependabot-updater-core:latest   9a6a20114926       1.18GB          310MB        
=> Removing docker images...
Deleted Images:
untagged: ghcr.io/dependabot/dependabot-updater-core:latest
deleted: sha256:9a6a20114926442eeadab0732ddd7264ecafc907389c47974b1825d779571319

Total reclaimed space: 309.7MB

********************************************************************************
---
test num::bignum::test_mul_small_overflow ... ok
test num::bignum::test_sub ... ok
test num::bignum::test_sub_underflow_1 ... ok
test num::bignum::test_sub_underflow_2 ... ok
test num::carryless_mul::carrying_carryless_mul ... ok
test num::carryless_mul::carryless_mul_u128 ... ok
test num::carryless_mul::carryless_mul_u16 ... ok
test num::carryless_mul::carryless_mul_u32 ... ok
test num::carryless_mul::carryless_mul_u64 ... ok
test num::carryless_mul::carryless_mul_u8 ... ok
test num::carryless_mul::widening_carryless_mul ... ok
test num::const_from::from ... ok
test num::dec2flt::decimal::check_fast_path_f16 ... ok
test num::dec2flt::decimal::check_fast_path_f32 ... ok
test num::dec2flt::decimal::check_fast_path_f64 ... ok
test num::dec2flt::decimal_seq::test_parse ... ok
---
stack backtrace:
   0: __rustc::rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed::<bool, bool>
   4: rust_out::main::_doctest_main_library_core_src_iter_traits_peekable_rs_9_0
   5: rust_out::main
   6: <fn() as core::ops::function::FnOnce<()>>::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

---- library/core/src/iter/traits/peekable.rs - iter::traits::peekable::PeekableIterator::peek_with (line 9) stdout end ----

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants