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

Implement advance_by, advance_back_by for iter::Chain #77594

Merged
merged 3 commits into from
Oct 6, 2020

Conversation

timvermeulen
Copy link
Contributor

@timvermeulen timvermeulen commented Oct 5, 2020

Part of #77404.

This PR does two things:

  • implement Chain::advance[_back]_by in terms of advance[_back]_by on self.a and advance[_back]_by on self.b
  • change Chain::nth[_back] to use advance[_back]_by on self.a and nth[_back] on self.b

This ensures that Chain::nth can take advantage of an efficient nth implementation on the second iterator, in case it doesn't implement advance_by.

cc @scottmcm in case you want to review this

@rust-highfive
Copy link
Collaborator

r? @joshtriplett

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 5, 2020
@scottmcm
Copy link
Member

scottmcm commented Oct 5, 2020

Sure, I'll take this one.
r? @scottmcm

Copy link
Member

@scottmcm scottmcm left a comment

Choose a reason for hiding this comment

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

The code here all looks right to me, but I've become paranoid about early-exits and fusing in &mut self iterator methods.

Could you please add some tests for the edge cases of non-fused iterators? You're self.a = None;ing in the right places, AFAICT, but I don't think the tests right now would catch it if you weren't (since slice::Iter is always fused anyway).

If you need a non-fused iterator, you could use something like

pub fn make_silly_iterator(mut x: u8) -> impl Iterator<Item = u8> {
    std::iter::from_fn(move || {
        let i = x;
        x = x.wrapping_sub(1);
        if i == 0 { None } else { Some(i) }
    })
}

@timvermeulen
Copy link
Contributor Author

Good call, I've been meaning to add more tests with non-fused iterators across the board because the current tests are barely using any. It wouldn't surprise me if some of the iterators currently contain bugs related to that.

I'm adding a NonFuse iterator wrapper to the test file that simply panics when next/next_back is called after the iterator has been exhausted, that should catch everything. And libcore iterators probably shouldn't be calling next on an exhausted iterator anyway, even when the value isn't used.

@timvermeulen
Copy link
Contributor Author

The tests now indeed do fail if I leave out self.a = None;. Mutation tests would be nice to have here 🙂

@scottmcm
Copy link
Member

scottmcm commented Oct 6, 2020

Thanks! Looks like a plausible helper to use in more tests (try_fold jumps to mind, obviously).

@bors r+

@bors
Copy link
Contributor

bors commented Oct 6, 2020

📌 Commit 1d27a50 has been approved by scottmcm

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 6, 2020
@ecstatic-morse
Copy link
Contributor

@bors rollup=never

@bors
Copy link
Contributor

bors commented Oct 6, 2020

⌛ Testing commit 1d27a50 with merge 5849a7e...

@bors
Copy link
Contributor

bors commented Oct 6, 2020

☀️ Test successful - checks-actions, checks-azure
Approved by: scottmcm
Pushing 5849a7e to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 6, 2020
@bors bors merged commit 5849a7e into rust-lang:master Oct 6, 2020
@rustbot rustbot added this to the 1.49.0 milestone Oct 6, 2020
@Mark-Simulacrum
Copy link
Member

As mentioned in #76909 (comment), this was a pretty bad regression on the deeply-nested stress test. https://perf.rust-lang.org/compare.html?start=5ded394553296d56bb66e925d7001ab3271979ce&end=5849a7eca90582ee59b67eb09548a2aa424d7f52&stat=instructions:u

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants