Skip to content

Commit e25ddad

Browse files
committed
minor changes of wording, layout, and clarification
1 parent 88a97dc commit e25ddad

File tree

1 file changed

+26
-25
lines changed

1 file changed

+26
-25
lines changed

text/3550-new-range.md

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ for n in (0..5).rev() { ... } // No changes necessary
109109
for n in (0..5).map(|x| x * 2) { ... } // No changes necessary
110110
```
111111

112-
In other cases, `cargo fix --edition 2024` will insert `.into_iter()` as necessary:
112+
In other cases, `cargo fix --edition` will insert `.into_iter()` as necessary:
113113

114114
```rust
115115
pub fn takes_iter(range: impl Iterator<usize>) { ... }
@@ -119,6 +119,19 @@ takes_iter((0..5).into_iter()); // Add `.into_iter()`
119119
(0..5).for_each(...);
120120
// After
121121
(0..5).into_iter().for_each(...); // Add `.into_iter()`
122+
123+
// Before
124+
let mut range = 0..5;
125+
assert_eq!(range.next(), Some(0));
126+
range.for_each(|n| {
127+
// n = 1, 2, 3, 4
128+
});
129+
// After
130+
let mut range = (0..5).into_iter();
131+
assert_eq!(range.next(), Some(0));
132+
range.for_each(|n| {
133+
// n = 1, 2, 3, 4
134+
});
122135
```
123136

124137
Or fall back to converting to the legacy types:
@@ -132,9 +145,11 @@ pub fn takes_range(range: std::range::legacy::Range<usize>) { ... }
132145
takes_range((0..5).into());
133146
```
134147

135-
#### Libraries
148+
## Migrating Libraries
149+
150+
Some libraries have range types in their public interface. To use the new range types with such a library, users will need to add explicit conversions.
136151

137-
To reduce the need for the above conversions, we recommend making the following changes to libraries:
152+
To reduce the burden of explicit conversions, libraries should make the following backwards-compatible changes:
138153

139154
- Change any function parameters from legacy `Range*` types to `impl Into<Range*>`
140155
Or if applicable, `impl RangeBounds<_>`
@@ -181,25 +196,7 @@ where Range<T>: IntoIterator
181196
}
182197
```
183198

184-
- When the range is treated as mutable iterator, call `.into_iter()` before using it
185-
186-
```rust
187-
// Before
188-
let mut range = 0..5;
189-
assert_eq!(range.next(), Some(0));
190-
range.for_each(|n| {
191-
// n = 1, 2, 3, 4
192-
});
193-
194-
// After
195-
let mut range = (0..5).into_iter();
196-
assert_eq!(range.next(), Some(0));
197-
range.for_each(|n| {
198-
// n = 1, 2, 3, 4
199-
});
200-
```
201-
202-
- When ranges are used with `std::ops::Index`, add impls for the new range types
199+
- When your library implements a trait involving ranges, such as `std::ops::Index`, add impls for the new range types
203200

204201
```rust
205202
// Before
@@ -212,6 +209,10 @@ impl Index<Range<usize>> for Bar { ... }
212209
impl Index<std::range::Range<usize>> for Bar { ... }
213210
```
214211

212+
**Note**
213+
- These changes to libraries should happen when _users_ of a given library transition to the new edition
214+
- These changes do not require the library itself to transition to the new edition
215+
215216
## Diagnostics
216217

217218
There is a substantial amount of educational material in the wild which assumes the the range types implement `Iterator`. If a user references this outdated material, it is important that compiler errors guide them to the new solution.
@@ -415,7 +416,7 @@ impl<Idx> Range<Idx> {
415416

416417
This change has the potential to cause a significant amount of churn in the ecosystem. There are two main sources of churn:
417418
- where ranges are assumed to be `Iterator`
418-
- when `Index<legacy::Range<_>>` is implemented directly
419+
- trait impls involving ranges, such as `Index<legacy::Range<_>>`
419420

420421
Changes will be required to support the new range types, even on older editions. See the [migrating section](#migrating) for specifics.
421422

@@ -535,7 +536,7 @@ We leave the following items to be decided by the **libs-api** team after this p
535536
- The set of inherent methods copied from `Iterator` present on the new range types
536537
- The exact module paths and type names
537538
+ Should the new types live at `std::ops::range::` instead?
538-
+ `IterRange`, `IterRangeInclusive` or just `Iter`, `IterInclusive`?
539+
+ `IterRange`, `IterRangeInclusive` or just `Iter`, `IterInclusive`? Or `RangeIter`, `RangeInclusiveIter`, ...?
539540
- Should other range-related items (like `RangeBounds`) also be moved under the `range` module?
540541
- 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.
541542
- Should there be a way to get an iterator that modifies the range in place, rather than taking the range by value? That would allow things like `range.by_ref().next()`.
@@ -549,7 +550,7 @@ impl<Idx> From<legacy::RangeInclusive<Idx>> for RangeInclusive<Idx> {
549550
# Future possibilities
550551
[future-possibilities]: #future-possibilities
551552

552-
- Hide or deprecate range-related items directly under `ops`, without breaking existing links or triggering deprecation warnings on previous editions.
553+
- Hide or deprecate range-related items directly under `ops` (without breaking existing links or triggering deprecation warnings on previous editions).
553554
- `RangeTo(Inclusive)::rev()` that returns an iterator?
554555
- `IterRangeInclusive` can be optimized to take advantage of the case where the bounds don't occupy the full domain of the index type:
555556

0 commit comments

Comments
 (0)