From eed47f3242a77308d6a07c30cd9411345f0e6c49 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 13 Oct 2015 15:02:16 -0400 Subject: [PATCH 1/3] Amend 1192 (RangeInclusive) to use an enum. 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. --- text/1192-inclusive-ranges.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/text/1192-inclusive-ranges.md b/text/1192-inclusive-ranges.md index 78051be6b5a..243702745a0 100644 --- a/text/1192-inclusive-ranges.md +++ b/text/1192-inclusive-ranges.md @@ -26,10 +26,12 @@ more dots means more elements. `std::ops` defines ```rust -pub struct RangeInclusive { - pub start: T, - pub end: T, - pub finished: bool, +pub enum RangeInclusive { + Empty, + NonEmpty { + start: T, + end: T, + } } pub struct RangeToInclusive { @@ -37,12 +39,11 @@ pub struct RangeToInclusive { } ``` -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 }`. `RangeInclusive` implements the standard traits (`Clone`, `Debug` -etc.), and implements `Iterator`. The `finished` field is to allow the +etc.), and implements `Iterator`. The `Empty` variant is to allow the `Iterator` implementation to work without hacks (see Alternatives). The use of `...` in a pattern remains as testing for inclusion @@ -79,8 +80,9 @@ winner. This RFC doesn't propose non-double-ended syntax, like `a...`, `...b` or `...` since it isn't clear that this is so useful. Maybe it is. -The `finished` field could be omitted, leaving two options: +The `Empty` variant could be omitted, leaving two options: +- `RangeInclusive` could be a struct including a `finished` field. - `a...b` only implements `IntoIterator`, not `Iterator`, by converting to a different type that does have the field. However, this means that `a...b` behaves differently to `a..b`, so From 66417584b3ce91e44f92858d5ca50658ab75e677 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 13 Nov 2015 17:08:36 -0500 Subject: [PATCH 2/3] Don't throw away endpoint after exhausting range --- text/1192-inclusive-ranges.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/text/1192-inclusive-ranges.md b/text/1192-inclusive-ranges.md index 243702745a0..de512694888 100644 --- a/text/1192-inclusive-ranges.md +++ b/text/1192-inclusive-ranges.md @@ -27,7 +27,9 @@ more dots means more elements. ```rust pub enum RangeInclusive { - Empty, + Empty { + at: T, + }, NonEmpty { start: T, end: T, @@ -85,7 +87,7 @@ The `Empty` variant could be omitted, leaving two options: - `RangeInclusive` could be a struct including a `finished` field. - `a...b` only implements `IntoIterator`, not `Iterator`, by converting to a different type that does have the field. However, - this means that `a...b` behaves differently to `a..b`, so + this means that `a.. .b` behaves differently to `a..b`, so `(a...b).map(|x| ...)` doesn't work (the `..` version of that is used reasonably often, in the author's experience) - `a...b` can implement `Iterator` for types that can be stepped From 2025389e1084a7c74772b33d27aa93e53ecf2cc8 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 15 Jan 2016 21:50:12 -0500 Subject: [PATCH 3/3] Add amendments section to note change. At @nikomatsakis request. --- text/1192-inclusive-ranges.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/text/1192-inclusive-ranges.md b/text/1192-inclusive-ranges.md index de512694888..7bef8c643c1 100644 --- a/text/1192-inclusive-ranges.md +++ b/text/1192-inclusive-ranges.md @@ -108,3 +108,8 @@ The `Empty` variant could be omitted, leaving two options: # Unresolved questions None so far. + +# Amendments + +* In rust-lang/rfcs#1320, this RFC was amended to change the `RangeInclusive` + type from a struct with a `finished` field to an enum.