]> git.proxmox.com Git - rustc.git/blame - src/doc/edition-guide/src/rust-2021/IntoIterator-for-arrays.md
New upstream version 1.55.0+dfsg1
[rustc.git] / src / doc / edition-guide / src / rust-2021 / IntoIterator-for-arrays.md
CommitLineData
17df50a5
XL
1# IntoIterator for arrays
2
3## Summary
4
136023e0
XL
5- Arrays implement `IntoIterator` in *all* editions.
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.
10
17df50a5
XL
11## Details
12
13Until Rust 1.53, only *references* to arrays implement `IntoIterator`.
14This means you can iterate over `&[1, 2, 3]` and `&mut [1, 2, 3]`,
15but not over `[1, 2, 3]` directly.
16
17```rust,ignore
18for &e in &[1, 2, 3] {} // Ok :)
19
20for e in [1, 2, 3] {} // Error :(
21```
22
23This has been [a long-standing issue][25], but the solution is not as simple as it seems.
24Just [adding the trait implementation][20] would break existing code.
25`array.into_iter()` already compiles today because that implicitly calls
26`(&array).into_iter()` due to [how method call syntax works][22].
27Adding the trait implementation would change the meaning.
28
136023e0 29Usually this type of breakage (adding a trait implementation) is categorized as 'minor' and acceptable.
17df50a5
XL
30But in this case there is too much code that would be broken by it.
31
32It has been suggested many times to "only implement `IntoIterator` for arrays in Rust 2021".
33However, this is simply not possible.
34You can't have a trait implementation exist in one edition and not in another,
35since editions can be mixed.
36
136023e0
XL
37Instead, the trait implementation was added in *all* editions (starting in Rust 1.53.0)
38but with a small hack to avoid breakage until Rust 2021.
17df50a5
XL
39In Rust 2015 and 2018 code, the compiler will still resolve `array.into_iter()`
40to `(&array).into_iter()` like before, as if the trait implementation does not exist.
41This *only* applies to the `.into_iter()` method call syntax.
42It does not affect any other syntax such as `for e in [1, 2, 3]`, `iter.zip([1, 2, 3])` or
43`IntoIterator::into_iter([1, 2, 3])`.
44Those will start to work in *all* editions.
45
46While it's a shame that this required a small hack to avoid breakage,
136023e0 47this solution keeps the difference between the editions to an absolute minimum.
17df50a5
XL
48
49[25]: https://github.com/rust-lang/rust/issues/25725
50[20]: https://github.com/rust-lang/rust/pull/65819
136023e0
XL
51[22]: https://doc.rust-lang.org/book/ch05-03-method-syntax.html#wheres-the---operator
52
53## Migration
54
55A lint, `array_into_iter`, gets triggered whenever there is some call to `into_iter()` that will change
56meaning in Rust 2021. The `array_into_iter` lint has already been a warning by default on all editions
57since the 1.41 release (with several enhancements made in 1.55). If your code is already warning free,
58then it should already be ready to go for Rust 2021!
59
60You can automatically migrate your code to be Rust 2021 Edition compatible or ensure it is already compatible by
61running:
62
63```sh
64cargo fix --edition
65```
66
67Because the difference between editions is small, the migration to Rust 2021 is fairly straight-forward.
68
69For method calls of `into_iter` on arrays, the elements being implemented will change from references to owned values.
70
71For example:
72
73```rust
74fn main() {
75 let array = [1u8, 2, 3];
76 for x in array.into_iter() {
77 // x is a `&u8` in Rust 2015 and Rust 2018
78 // x is a `u8` in Rust 2021
79 }
80}
81```
82
83The most straightforward way to migrate in Rust 2021, is by keeping the exact behavior from previous editions
84by calling `iter()` which also iterates over owned arrays by reference:
85
86```rust
87fn main() {
88 let array = [1u8, 2, 3];
89 for x in array.iter() { // <- This line changed
90 // x is a `&u8` in all editions
91 }
92}
93```
94
95### Optional migration
96
97If you are using fully qualified method syntax (i.e., `IntoIterator::into_iter(array)`) in a previous edition,
98this can be upgraded to method call syntax (i.e., `array.into_iter()`).