Skip to content

Work-around optimiser deficiencies in Range iterator. #26390

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

Closed
wants to merge 2 commits into from

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Jun 18, 2015

closes #24705

the issue in the other PR was that the inclusive range iterator depended on internals of the normal range iterator

range_inclusive (https://github.com/rust-lang/rust/blob/master/src/libcore/iter.rs#L2799-2808) won't work anymore due to the self.range.start == self.range.end check. This will cause https://github.com/rust-lang/rust/blob/master/src/librustc/middle/check_match.rs#L605 to produce 0 elements for range_inclusive(0, 0)

which then causes the match arm reachability to fail

This was not detected by the test-suite, because the failure happens during stage1 compilation of the standard libraries.

r? @aturon
cc @huonw @pythonesque @pnkfelix

huonw and others added 2 commits June 16, 2015 14:06
The conditional mutation of the previous implementation resulted in poor
code, making it unconditional makes `Range` less well behaved as an
Iterator (but still legal) but also makes it fast.

The intention is that this change will be reverted when rustc/LLVM
handle the best-behaved implementation better.

cc rust-lang#24660
// mishandles the version that places the mutation inside the
// `if`: it seems to optimise the `Option<i32>` in a way that
// confuses it.
let mut n = &self.start + &A::one();
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately I think doing this addition outside the guard causes the panic semantics of this iterator to change, which I believe will be a regression. For example this code does not panic today, but I suspect it will panic with this implementation:

fn main() {
    for i in 255u8..255 {
        println!("{}", i);
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, didn't notice that corner case...
Anyway, closing is perfectly alright with me, I just wanted to move the PR forward :)

Copy link
Member

Choose a reason for hiding this comment

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

Hm ok, I think for now we may want to not merge this due to that, but perhaps we can think of a new idea in the future!

@alexcrichton
Copy link
Member

Closing because I think this may be backwards incompatible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants