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

Add Range[Inclusive]::is_empty #48087

Merged
merged 5 commits into from
Feb 15, 2018
Merged

Conversation

scottmcm
Copy link
Member

@scottmcm scottmcm commented Feb 9, 2018

During rust-lang/rfcs#1980, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it. It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- such as Range<i64> and RangeInclusive<usize>.

Things to ponder:

  • Unless this is stabilized first, this makes stabilizing ExactSizeIterator::is_empty more icky, since this hides that.
  • This is only on Range and RangeInclusive, as those are the only ones where it's interesting. But one could argue that it should be on more for consistency, or on RangeArgument instead.
  • The bound on this is PartialOrd, since that works ok (see tests for float examples) and is consistent with contains. But ranges like NAN..=NANare kinda weird.
  • There's not a real issue number on this yet

During the RFC, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it.  It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- not even Range<i32> or RangeInclusive<usize>.
@rust-highfive
Copy link
Collaborator

r? @shepmaster

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

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 9, 2018
@@ -706,7 +706,7 @@ pub trait ExactSizeIterator: Iterator {
/// ```
/// #![feature(exact_size_is_empty)]
///
/// let mut one_element = 0..1;
/// let mut one_element = std::iter::once(0);
Copy link
Member

Choose a reason for hiding this comment

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

Why is this related to this PR?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because using 0..1 means the code wasn't actually using ExactSizeIterator; the inherent method was getting picked up instead. For normal code that's not a problem--they do exactly the same thing--but I figured the doctest should actually use the method it's documenting.

assert_eq!(r.nth(10), None);
assert_eq!(r.is_empty(), true);
assert_eq!(ExactSizeIterator::is_empty(&r), true);
Copy link
Member

Choose a reason for hiding this comment

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

Is this going to be a concern for end users?

Copy link
Member

Choose a reason for hiding this comment

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

ExactSizeIterator::is_empty (also unstable)

ah, nvm

Copy link
Member Author

Choose a reason for hiding this comment

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

Range::is_empty is strictly more general, so it's not a problem in a world where everything is stable. It may be a slight hiccup in nightly, but I would expect it to be solved in the wild by adding the new feature gate, rather than the annoying UFCS. Here I just changed it to the other method because I didn't want to change what the test was testing. (It would be a problem if we wanted to stabilize ExactSizeIterator::is_empty first, as mentioned in the OP, but I feel like this should be less controversial than the new trait method, especially since there are a bunch of iterators that aren't ExactSize that could provide an efficient is_empty.)

@shepmaster
Copy link
Member

The code seems reasonable to me, but since @kennytm has been thinking about ranges lately...

r? @kennytm

@rust-highfive rust-highfive assigned kennytm and unassigned shepmaster Feb 9, 2018
assert!( (EPSILON ..= NAN).is_empty());
assert!( (NAN ..= EPSILON).is_empty());
assert!( (NAN ..= NAN).is_empty());
}
Copy link
Member

Choose a reason for hiding this comment

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

WDYT about a test that calls next on a Range{Inclusive} and makes sure it transitions from not empty to empty?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good thought; I'll change all of these to look for is_empty instead of 1..=0: https://github.com/rust-lang/rust/blob/master/src/libcore/tests/iter.rs#L1433

assert_eq!(r.nth(10), None);
assert_eq!(r.is_empty(), true);
assert_eq!(r, 1..=0); // We may not want to document/promise this detail
assert_eq!(ExactSizeIterator::is_empty(&r), true);
Copy link
Member Author

@scottmcm scottmcm Feb 10, 2018

Choose a reason for hiding this comment

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

Changed RangeInclusive exhaustion tests to check is_empty, updated the docs to unspecify the post-iteration value of a RangeInclusive, and added some more Range tests using its is_empty.

@kennytm
Copy link
Member

kennytm commented Feb 10, 2018

Since you're defining is_empty() to floating point types as well, perhaps spell out in the documentation that a..b is not empty when a < b (similar for a..=b).

LGTM other than this documentation bit, but I'd also like someone from @rust-lang/libs to sign-off.

@kennytm kennytm added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Feb 10, 2018
@alexcrichton
Copy link
Member

Looks good to me! Especially as unstable I think this can land when it's good to go

@kennytm kennytm 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 Feb 10, 2018
@scottmcm
Copy link
Member Author

Added the start < end and start <= end to the doc comments next to the description of what the range contains, and added a doctest for each showing the behaviour with NAN.

@kennytm
Copy link
Member

kennytm commented Feb 11, 2018

@bors r=kennytm,alexcrichton

@bors
Copy link
Contributor

bors commented Feb 11, 2018

📌 Commit 22b0489 has been approved by kennytm,alexcrichton

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 11, 2018
kennytm added a commit to kennytm/rust that referenced this pull request Feb 12, 2018
…alexcrichton Add Range[Inclusive]::is_empty During rust-lang/rfcs#1980, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it. It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- such as `Range<i64>` and `RangeInclusive<usize>`. Things to ponder: - Unless this is stabilized first, this makes stabilizing ExactSizeIterator::is_empty more icky, since this hides that. - This is only on `Range` and `RangeInclusive`, as those are the only ones where it's interesting. But one could argue that it should be on more for consistency, or on RangeArgument instead. - The bound on this is PartialOrd, since that works ok (see tests for float examples) and is consistent with `contains`. But ranges like `NAN..=NAN`_are_ kinda weird. - [x] ~~There's not a real issue number on this yet~~
bors added a commit that referenced this pull request Feb 12, 2018
Rollup of 8 pull requests

- Successful merges: #47846, #48033, #48087, #48114, #48126, #48130, #48133, #48151
- Failed merges:
kennytm added a commit to kennytm/rust that referenced this pull request Feb 13, 2018
…alexcrichton

Add Range[Inclusive]::is_empty

During rust-lang/rfcs#1980, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it.  It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- such as `Range<i64>` and `RangeInclusive<usize>`.

Things to ponder:
- Unless this is stabilized first, this makes stabilizing ExactSizeIterator::is_empty more icky, since this hides that.
- This is only on `Range` and `RangeInclusive`, as those are the only ones where it's interesting.  But one could argue that it should be on more for consistency, or on RangeArgument instead.
- The bound on this is PartialOrd, since that works ok (see tests for float examples) and is consistent with `contains`.  But ranges like `NAN..=NAN`_are_ kinda weird.
- [x] ~~There's not a real issue number on this yet~~
bors added a commit that referenced this pull request Feb 13, 2018
Rollup of 14 pull requests

- Successful merges: #47784, #47846, #48033, #48083, #48087, #48114, #48126, #48130, #48133, #48151, #48154, #48163, #48165, #48167
- Failed merges:
kennytm added a commit to kennytm/rust that referenced this pull request Feb 14, 2018
…alexcrichton

Add Range[Inclusive]::is_empty

During rust-lang/rfcs#1980, it was discussed that figuring out whether a range is empty was subtle, and thus there should be a clear and obvious way to do it.  It can't just be ExactSizeIterator::is_empty (also unstable) because not all ranges are ExactSize -- such as `Range<i64>` and `RangeInclusive<usize>`.

Things to ponder:
- Unless this is stabilized first, this makes stabilizing ExactSizeIterator::is_empty more icky, since this hides that.
- This is only on `Range` and `RangeInclusive`, as those are the only ones where it's interesting.  But one could argue that it should be on more for consistency, or on RangeArgument instead.
- The bound on this is PartialOrd, since that works ok (see tests for float examples) and is consistent with `contains`.  But ranges like `NAN..=NAN`_are_ kinda weird.
- [x] ~~There's not a real issue number on this yet~~
bors added a commit that referenced this pull request Feb 14, 2018
bors added a commit that referenced this pull request Feb 15, 2018
bors added a commit that referenced this pull request Feb 15, 2018
@kennytm kennytm merged commit 22b0489 into rust-lang:master Feb 15, 2018
@scottmcm scottmcm deleted the range_is_empty branch February 20, 2018 01:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants