Skip to content

Commit 09fd06d

Browse files
committed
Add migration section to into-iterator
1 parent 288f611 commit 09fd06d

File tree

1 file changed

+51
-11
lines changed

1 file changed

+51
-11
lines changed

src/rust-2021/IntoIterator-for-arrays.md

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
## Summary
44

55
- Arrays implement `IntoIterator` in *all* editions.
6-
- The new `.into_iter()` is *hidden* in Rust 2015 and Rust 2018 in method call syntax.
7-
So, `array.into_iter()` still resolves to `(&array).into_iter()` as before.
8-
- `array.into_iter()` changes meaning when switching to Rust 2021.
6+
- Calls to `IntoIterator::into_iter` are *hidden* in Rust 2015 and Rust 2018 when using method call syntax
7+
(i.e., `array.into_iter()`). So, `array.into_iter()` still resolves to `(&array).into_iter()` as it
8+
has before.
9+
- `array.into_iter()` changes meaning to be the call to `IntoIterator::into_inter` in Rust 2021.
910

1011
## Details
1112

@@ -25,17 +26,16 @@ Just [adding the trait implementation][20] would break existing code.
2526
`(&array).into_iter()` due to [how method call syntax works][22].
2627
Adding the trait implementation would change the meaning.
2728

28-
Usually we categorize this type of breakage
29-
(adding a trait implementation) 'minor' and acceptable.
29+
Usually this type of breakage (adding a trait implementation) is categorized as 'minor' and acceptable.
3030
But in this case there is too much code that would be broken by it.
3131

3232
It has been suggested many times to "only implement `IntoIterator` for arrays in Rust 2021".
3333
However, this is simply not possible.
3434
You can't have a trait implementation exist in one edition and not in another,
3535
since editions can be mixed.
3636

37-
Instead, we decided to add the trait implementation in *all* editions (starting in Rust 1.53.0),
38-
but add a small hack to avoid breakage until Rust 2021.
37+
Instead, the trait implementation was added in *all* editions (starting in Rust 1.53.0)
38+
but with a small hack to avoid breakage until Rust 2021.
3939
In Rust 2015 and 2018 code, the compiler will still resolve `array.into_iter()`
4040
to `(&array).into_iter()` like before, as if the trait implementation does not exist.
4141
This *only* applies to the `.into_iter()` method call syntax.
@@ -44,11 +44,51 @@ It does not affect any other syntax such as `for e in [1, 2, 3]`, `iter.zip([1,
4444
Those will start to work in *all* editions.
4545

4646
While it's a shame that this required a small hack to avoid breakage,
47-
we're very happy with how this solution keeps the difference between
48-
the editions to an absolute minimum.
49-
Since the hack is only present in the older editions,
50-
there is no added complexity in the new edition.
47+
this solution keeps the difference between the editions to an absolute minimum.
5148

5249
[25]: https://github.com/rust-lang/rust/issues/25725
5350
[20]: https://github.com/rust-lang/rust/pull/65819
5451
[22]: https://doc.rust-lang.org/book/ch05-03-method-syntax.html#wheres-the---operator
52+
53+
## Migration
54+
55+
A migration lint, `array_into_iter`, has been added in order to aid in automatic migration of Rust 2018 codebases to Rust 2021.
56+
57+
In order to have `rustfix` migrate your code to be Rust 2021 Edition compatible, run:
58+
59+
```sh
60+
cargo fix --edition
61+
```
62+
63+
Because the difference between editions is small, the migration to Rust 2021 is fairly straight-forward.
64+
65+
For method calls of `into_iter` on arrays, the elements being implemented will change from references to owned values.
66+
67+
For example:
68+
69+
```rust
70+
fn main() {
71+
let array = [1u8, 2, 3];
72+
for x in array.into_iter() {
73+
// x is a `&u8` in Rust 2015 and Rust 2018
74+
// x is a `u8` in Rust 2021
75+
}
76+
}
77+
```
78+
79+
The most straightforward way to migrate in Rust 2021, is by keeping the exact behavior from previous editions
80+
by calling `iter()` which also iterates over owned arrays by reference:
81+
82+
```rust
83+
fn main() {
84+
let array = [1u8, 2, 3];
85+
for x in array.iter() { // <- This line changed
86+
// x is a `&u8` in all editions
87+
}
88+
}
89+
```
90+
91+
### Optional migration
92+
93+
If you are using fully qualified method syntax (i.e., `IntoIterator::into_iter(array)`) in a previous edition,
94+
this can be upgraded to method call syntax (i.e., `array.into_iter()`).

0 commit comments

Comments
 (0)