-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Amend 1192 (RangeInclusive) to use an enum. #1320
Conversation
Rational: 1. The word "finished" is very iterator specific. Really, this field is trying to indicate that the range is actually empty. 2. `start`/`end` don't make sense if the range is empty. Using an enum prevents coders from using the `start`/`end` of spent ranges. Basically, this makes it impossible for the coder to do something like `foo(my_range.take(10)); bar(my_range)` and forget to check `finished` in `bar`. 3. If we ever get better enum optimizations (specifically, utf8 code point ones) `'a'...'z'` should be the same size as `'a'..'z'`; the Empty variant can be encoded as an invalid code point.
Hm, I wonder if there's any use for storing the end point, i.e. |
To expand a little/respond to your rational:
|
I agree that keeping the end is useful but I don't really get the ownership argument for keeping both. |
I think we should back out of RangeInclusive. We need fully general ranges instead which are open/closed/unbounded of both ends. |
@Stebalien it can be expensive to create/copy/destroy values in Rust (this is in contrast to managed languages, where copying is often just copying a single pointer, or at most manipulating some reference counts), so minimising how often this happens implicitly/without programmer control is good. E.g. if you have a @bluss I agree that having fully general ranges would be nice, but there has been a lot of discussion/thinking about it and AFAIK there has been no nice (and backwards compatible) syntax raised. |
Syntax is a second-order issue for me, which types we want to introduce into the core of rust is much more important. |
@huonw
I (obviously) agree. However, it may be a bit late for that given that we're stuck with |
I think |
Scratch that, I thought Step was used for iterating in general. Not storing start actually saves an allocation because you don't have to allocate a new one when transitioning from |
|
@huonw, I've updated the proposal to avoid throwing away the endpoint. I do only need to keep one because, on the last iteration, I can just return the start as-is without advancing it leaving me with the end only. |
Oh, that's a good point. |
Hear ye, hear ye! This RFC is now entering final comment period. |
I am 👍 on this RFC but I would request that the author add a "# History" or "# Amendments" section and simply note the change that is occurring. It's nice when reading the text of an RFC if you don't have to consult the git history to know when it was updated. For example:
|
Where did the discussion of more complete range syntax go? Mentioned in #1254 |
That topic seems more relevant for stabilisation of the actual (Maybe you're thinking of https://internals.rust-lang.org/t/vs-for-inclusive-ranges/1539 ?) |
I'm not thinking of that, that's an old discussion. #1254 was much more recent, indicating aturon and lang team wanted to look at this. |
@bluss Yes, I am on the same page: I want to back out However, as @huonw said, this RFC is just an amendment to the previous one, so it's somewhat orthogonal to the larger question. |
Libs team consensus: this is a clear improvement over the original RFC. |
@@ -37,12 +41,11 @@ pub struct RangeToInclusive<T> { | |||
} | |||
``` | |||
|
|||
Writing `a...b` in an expression desugars to `std::ops::RangeInclusive | |||
{ start: a, end: b, finished: false }`. Writing `...b` in an | |||
Writing `a...b` in an expression desugars to `std::ops::RangeInclusive::NonEmpty { start: a, end: b }`. Writing `...b` in an | |||
expression desugars to `std::ops::RangeToInclusive { end: b }`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops. soorry!
Huzzah! The lang team has decided to accept this RFC. |
I kept the same tracking issue, but added a "to do" item to implement the changes suggested here. |
Implemented in (in progress) rust-lang/rust#30884. |
I wonder whether, from a performance perspective, how does the I can't tell if this was suggested at some point, but even if it wasn't, I doubt the implementation will change. |
This PR proposes that
RangeInclusive
be an enum withEmpty
/NonEmpty
variants instead of a struct with afinished
field:Rational:
finished
is very iterator specific. Regardless of what happens, I think this field should be calledempty
.start
/end
don't make sense if the range is empty. Using an enum prevents users from using thestart
/end
of spent ranges. Basically, this makes it impossible for users to do something likefoo(my_range.take(10)); bar(my_range)
and forget to checkfinished
inbar
.'a'...'z'
should be the same size as'a'..'z'
.