You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/3550-new-range.md
+61-60Lines changed: 61 additions & 60 deletions
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@
6
6
# Summary
7
7
[summary]: #summary
8
8
9
-
Change the range operators `a..b`, `a..`, and `a..=b` to resolve to new types `ops::range::Range`, `ops::range::RangeFrom`, and `ops::range::RangeInclusive` in Edition 2024. These new types will not implement `Iterator`, instead implementing `Copy` and `IntoIterator`.
9
+
Change the range operators `a..b`, `a..`, and `a..=b` to resolve to new types `std::range::Range`, `std::range::RangeFrom`, and `std::range::RangeInclusive` in Edition 2024. These new types will not implement `Iterator`, instead implementing `Copy` and `IntoIterator`.
10
10
11
11
# Motivation
12
12
[motivation]: #motivation
@@ -38,13 +38,13 @@ Another primary motivation is the extra size of `RangeInclusive`. It uses an ext
38
38
39
39
Rust has several different types of "range" syntax, including the following:
40
40
41
-
-`a..b` denotes a range from `a` (inclusive) to `b` (exclusive). It resolves to the type `std::ops::range::Range`.
41
+
-`a..b` denotes a range from `a` (inclusive) to `b` (exclusive). It resolves to the type `std::range::Range`.
42
42
The iterator for `Range` will yield values from `a` (inclusive) to `b` (exclusive) in steps of one.
43
43
44
-
-`a..=b` denotes a range from `a` (inclusive) to `b` (inclusive). It resolve to the type `std::ops::range::RangeInclusive`.
44
+
-`a..=b` denotes a range from `a` (inclusive) to `b` (inclusive). It resolve to the type `std::range::RangeInclusive`.
45
45
The iterator for `RangeInclusive` will yield values from `a` (inclusive) to `b` (inclusive) in steps of one.
46
46
47
-
-`a..` denotes a range from `a` (inclusive) with no upper bound. It resolves to the type `std::ops::range::RangeFrom`.
47
+
-`a..` denotes a range from `a` (inclusive) with no upper bound. It resolves to the type `std::range::RangeFrom`.
48
48
The iterator for `RangeFrom` will yield values starting with `a` and increasing in steps of one.
49
49
50
50
These types implement the `IntoIterator` trait, enabling their use directly in a `for` loop:
@@ -78,7 +78,7 @@ for n in (0..5).rev() {
78
78
79
79
## Legacy Range Types
80
80
81
-
In Rust editions prior to 2024, `a..b`, `a..=b`, and `a..` resolved to a different set of types (now found in `std::ops::range::legacy`). These legacy range types did not implement `Copy`, and implemented `Iterator` directly (rather than `IntoIterator`).
81
+
In Rust editions prior to 2024, `a..b`, `a..=b`, and `a..` resolved to a different set of types (now found in `std::range::legacy`). These legacy range types did not implement `Copy`, and implemented `Iterator` directly (rather than `IntoIterator`).
82
82
83
83
This meant that any `Iterator` method could be called on those range types:
84
84
```rust
@@ -128,7 +128,7 @@ Or fall back to converting to the legacy types:
@@ -240,108 +240,109 @@ The [**Range Expressions** page in the Reference](https://doc.rust-lang.org/refe
240
240
241
241
> ## Edition 2024 and later
242
242
>
243
-
> The `..` and `..=` operators will construct an object of one of the `std::ops::range::Range` (or `core::ops::range::Range`) variants, according to the following table:
243
+
> The `..` and `..=` operators will construct an object of one of the `std::range::Range` (or `core::range::Range`) variants, according to the following table:
> |_RangeInclusiveExpr_| start`..=`end | std::range::RangeInclusive | start ≤ x ≤ end |
252
+
> |_RangeToInclusiveExpr_|`..=`end | std::range::RangeToInclusive | x ≤ end |
253
253
>
254
-
> **Note:** While `std::ops::RangeTo`, `std::ops::RangeFull`, and `std::ops::RangeToInclusive` are re-exports of `std::ops::range::RangeTo`, `std::ops::range::RangeFull`, and `std::ops::Range::RangeToInclusive` respectively, `std::ops::Range`, `std::ops::RangeFrom`, and `std::ops::RangeInclusive` are re-exports of the types under `std::ops::range::legacy::` (NOT those directly under `std::ops::range::`) for backwards-compatibility reasons.
254
+
> **Note:** While `std::ops::RangeTo`, `std::ops::RangeFull`, and `std::ops::RangeToInclusive` are re-exports of `std::range::RangeTo`, `std::range::RangeFull`, and `std::ops::Range::RangeToInclusive` respectively, `std::ops::Range`, `std::ops::RangeFrom`, and `std::ops::RangeInclusive` are re-exports of the types under `std::range::legacy::` (NOT those directly under `std::range::`) for backwards-compatibility reasons.
255
255
>
256
256
> Examples:
257
257
>
258
258
> ```rust
259
-
> 1..2; // std::ops::range::Range
260
-
> 3..; // std::ops::range::RangeFrom
261
-
> ..4; // std::ops::range::RangeTo
262
-
> ..; // std::ops::range::RangeFull
263
-
> 5..=6; // std::ops::range::RangeInclusive
264
-
> ..=7; // std::ops::range::RangeToInclusive
259
+
> 1..2; // std::range::Range
260
+
> 3..; // std::range::RangeFrom
261
+
> ..4; // std::range::RangeTo
262
+
> ..; // std::range::RangeFull
263
+
> 5..=6; // std::range::RangeInclusive
264
+
> ..=7; // std::range::RangeToInclusive
265
265
> ```
266
266
>
267
267
> Thefollowingexpressionsareequivalent.
268
268
>
269
269
> ```rust
270
-
> letx=std::ops::range::Range {start:0, end:10};
270
+
> letx=std::range::Range {start:0, end:10};
271
271
> lety=0..10;
272
272
>
273
273
> assert_eq!(x, y);
274
274
> ```
275
275
>
276
276
> ## PriortoEdition2024
277
277
>
278
-
> The `..` and `..=` operatorswillconstructanobjectofoneofthe `std::ops::range::legacy::Range` (or `core::ops::range::legacy::Range`) variants, accordingtothefollowingtable:
278
+
> The `..` and `..=` operatorswillconstructanobjectofoneofthe `std::range::legacy::Range` (or `core::range::legacy::Range`) variants, accordingtothefollowingtable:
The `RangeFull`, `RangeTo`, and `RangeToInclusive` typeswillremainunchanged.Butforconsistency, theircanonicalpathswillbechangedtoliveunder `ops::range`:
329
+
The `RangeFull`, `RangeTo`, and `RangeToInclusive` typeswillremainunchanged.Butforconsistency, theircanonicalpathswillbechangedtoliveunder `range`:
- `ops::range::IterRange` willnotimplement `ExactSizeIterator` for `u32` or `i32`
344
-
- `ops::range::IterRangeInclusive` willnotimplement `ExactSizeIterator` for `u16` or `i16`
344
+
- `std::range::IterRange` willnotimplement `ExactSizeIterator` for `u32` or `i32`
345
+
- `std::range::IterRangeInclusive` willnotimplement `ExactSizeIterator` for `u16` or `i16`
345
346
346
347
Those `ExactSizeIterator` implsonthelegacyrangetypesare [knowntobeincorrect](https://github.com/rust-lang/rust/blob/495203bf61efabecc2c460be38e1eb0f9952601b/library/core/src/iter/range.rs#L903-L936).
`ops::range::Range` and `ops::range::RangeFrom` will have identical structure to the existing types, with public fields for the bounds. However, `ops::range::RangeInclusive` will be changed:
366
+
`std::range::Range` and `std::range::RangeFrom` will have identical structure to the existing types, with public fields for the bounds. However, `std::range::RangeInclusive` will be changed:
366
367
-`start` and `end` will be changed to public fields
367
368
-`exhausted` field will be removed entirely
368
369
@@ -543,7 +544,7 @@ We leave the following items to be decided by the **libs-api** team after this p
543
544
544
545
- The set of inherent methods copied from `Iterator` present on the new range types
545
546
- The exact module paths and type names
546
-
+`std::ops::range::` is long and heavily nested, perhaps `std::range::`would be better?
547
+
+Should the new types live at `std::ops::range::`instead?
547
548
+`IterRange`, `IterRangeInclusive` or just `Iter`, `IterInclusive`?
548
549
- Should other range-related items (like `RangeBounds`) also be moved under the `range` module?
549
550
- Should `RangeFrom` even implement `IntoIterator`, or should it require an explicit `.iter()` call? Using it as an iterator [can be a footgun](https://github.com/rust-lang/libs-team/issues/304), usually people want `start..=MAX` instead. Also, it is inconsistent with `RangeTo`, which doesn't implement `IntoIterator` either.
0 commit comments