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

Make the specialized Fuse still deal with None #86765

Merged
merged 1 commit into from
Jul 14, 2021

Conversation

cuviper
Copy link
Member

@cuviper cuviper commented Jun 30, 2021

Fixes #85863 by removing the assumption that we'll never see a cleared iterator in the I: FusedIterator specialization. Now all Fuse methods check for the possibility that self.iter is None, and the specialization only avoids setting that to None in &mut self methods.

@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 Jun 30, 2021
@cuviper
Copy link
Member Author

cuviper commented Jun 30, 2021

Queuing for a performance run, especially relative to #86766.

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jun 30, 2021
@bors
Copy link
Contributor

bors commented Jun 30, 2021

⌛ Trying commit 6f5e933 with merge 014fd74e3bfafd8c10f931b6fbc233a19f81413b...

@bors
Copy link
Contributor

bors commented Jul 1, 2021

☀️ Try build successful - checks-actions
Build commit: 014fd74e3bfafd8c10f931b6fbc233a19f81413b (014fd74e3bfafd8c10f931b6fbc233a19f81413b)

@rust-timer
Copy link
Collaborator

Queued 014fd74e3bfafd8c10f931b6fbc233a19f81413b with parent 868c702, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (014fd74e3bfafd8c10f931b6fbc233a19f81413b): comparison url.

Summary: This benchmark run did not return any significant changes.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying rollup- to bors.

Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 1, 2021
@cuviper cuviper marked this pull request as ready for review July 7, 2021 18:09
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
// SAFETY: the specialized iterator never sets `None`
None => unsafe { intrinsics::unreachable() },
Copy link
Member

Choose a reason for hiding this comment

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

The trait impl is being removed due to the unreachable here, right? I think it might be possible to replace this with a panic instead.

If someone pulled the HRTB shenaningans then it would only lead to a panic, not to unsafety. If that's not good enough then maybe SourceIter could be changed to return an Option<&mut>.

Copy link
Member Author

Choose a reason for hiding this comment

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

I personally don't think we should use a panic for code that is otherwise allowable, however weird it may be.

Changing SourceIter to return an Option sounds promising, assuming there actually is a reasonable fallback at the caller -- I suppose going back to normal not-in-place collection. Then you wouldn't even need the seemingly-unrelated I: FusedIterator constraint here.

Copy link
Member

@the8472 the8472 Jul 14, 2021

Choose a reason for hiding this comment

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

I suppose going back to normal not-in-place collection.

That would probably be bad for compile times since it would need two different code paths in that case.

If we can assume that None implies an exhausted iterator then it could work and simply return an empty Vec. But I'll have to look through all the implementations to see if that's a valid assumption.

Copy link
Member

@the8472 the8472 Jul 14, 2021

Choose a reason for hiding this comment

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

Then you wouldn't even need the seemingly-unrelated I: FusedIterator constraint here.

In place iteration works roughly like this

  1. retrieve source iter to get a write pointer
  2. perform loop that gets elements from the iterator and writes to the pointer
  3. retrieve source iter again to drop the remainder and then steal the allocation

Which means that once we have started iterating the source must stay retrievable. Which means the iterator cannot be fused through the option because that would drop the source. So it can only work for FusedIterator which doesn't switch the option variant.

Under those circumstances it should be safe since user code doesn't have access to the iterator during that time and can't do the variance coercion.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, yeah, you need it to not drop. I agree the user doesn't have access during your steps, but they could have played the variance game before it got there at all, so it might be None to start with. Then an empty collection is fine.

@joshtriplett
Copy link
Member

Reviewing on the basis of the code here looking reasonable, relying on other statements that this fixes the underlying problem it intends to fix.

@bors r+

@bors
Copy link
Contributor

bors commented Jul 14, 2021

📌 Commit 6f5e933 has been approved by joshtriplett

@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 Jul 14, 2021
@bors
Copy link
Contributor

bors commented Jul 14, 2021

⌛ Testing commit 6f5e933 with merge 2f391da...

@bors
Copy link
Contributor

bors commented Jul 14, 2021

☀️ Test successful - checks-actions
Approved by: joshtriplett
Pushing 2f391da to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jul 14, 2021
@bors bors merged commit 2f391da into rust-lang:master Jul 14, 2021
@rustbot rustbot added this to the 1.55.0 milestone Jul 14, 2021
@cuviper cuviper deleted the fuse-less-specialized branch September 21, 2021 16:43
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.

iter::Fuse is unsound with how specialization currently behaves around HRTB fn pointers
7 participants