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: src/rust-2021/prelude.md
+31-20Lines changed: 31 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -2,8 +2,8 @@
2
2
3
3
## Summary
4
4
5
-
-`TryInto`, `TryFrom` and `FromIterator` are now part of the prelude.
6
-
- This might change the meaning of e.g. `x.try_into()` depending on types and imports.
5
+
-The `TryInto`, `TryFrom` and `FromIterator` traits are now part of the prelude.
6
+
- This might make calls to trait methods ambiguous which could make some code fail to compile.
7
7
8
8
## Details
9
9
@@ -18,11 +18,10 @@ then `use example::*;` will make `Option` unambiguously refer to the one from `e
18
18
not the one from the standard library.
19
19
20
20
However, adding a _trait_ to the prelude can break existing code in a subtle way.
21
-
A call to `x.try_into()` using a `MyTryInto` trait might become ambiguous and
22
-
fail to compile if `std`'s `TryInto` is also imported,
23
-
since it provides a method with the same name.
24
-
This is the reason we haven't added `TryInto` to the prelude yet,
25
-
since there is a lot of code that would break this way.
21
+
For example, a call to `x.try_into()` which comes from a `MyTryInto` trait might fail
22
+
to compile if `std`'s `TryInto` is also imported, because the call to `try_into` is now
23
+
ambiguous and could come from either trait. This is the reason we haven't added `TryInto`
24
+
to the prelude yet, since there is a lot of code that would break this way.
26
25
27
26
As a solution, Rust 2021 will use a new prelude.
28
27
It's identical to the current one, except for three new additions:
@@ -43,41 +42,53 @@ In order to have rustfix migrate your code to be Rust 2021 Edition compatible, r
43
42
cargo fix --edition
44
43
```
45
44
46
-
The lint detects cases where functions or methods are called that have the same name as the methods defined in one of the new prelude traits. In some cases, it may rewrite your calls in various ways to ensure that you continue to call the same function you did before:
|[Inherent methods on `dyn Trait`](inherent-methods-on-dyn-trait-objects)|`foo.into_iter()`|`(*foo).into_iter`() |
45
+
The lint detects cases where functions or methods are called that have the same name as the methods defined in one of the new prelude traits. In some cases, it may rewrite your calls in various ways to ensure that you continue to call the same function you did before.
52
46
53
47
### Fully qualified calls to inherent methods
54
48
55
-
Many types define their own inherent methods with the name `from_iter`:
49
+
Many types define their own inherent methods with the name `from_iter` which shares the same name with `std::iter::FromIterator::from_iter`:
56
50
57
51
```rust
58
-
structFoo {
52
+
structMyStruct {
59
53
data:Vec<u32>
60
54
}
61
-
implFoo {
55
+
56
+
implMyStruct {
57
+
// This has the same name as `std::iter::FromIterator::from_iter`
62
58
fnfrom_iter(x:implIterator<Item=u32>) ->Self {
63
-
Foo {
59
+
Self {
64
60
data:x.collect()
65
61
}
66
62
}
67
63
}
68
64
```
69
65
70
-
Calls like `Foo::from_iter` cannot be confused with calls to `<Foo as FromIter>::from_iter`, because inherent methods take precedence over trait methods.
66
+
In case that already use a fully qualified inherent method syntax (e.g., calls like `MyStruct::from_iter`), there is not ambiguity with calls to trait methods (e.g., `<MyStruct as FromIter>::from_iter`), because inherent methods take precedence over trait methods. Therefore, no migration is needed.
67
+
68
+
A migration is necessary when using "dot method" syntax where the method name is the same as the trait method name for a trait which is now
69
+
in scope. For example, a call like `my_struct.into_iter()` where `into_iter()` used to refer to an inherent method on `MyStruct` but now conflicts with
70
+
the trait method from `IntoIter`. To make these calls unambiguous, fully qualified inherent method syntax must be used:
71
+
72
+
```rust
73
+
// Before:
74
+
my_struct.into_iter();
75
+
// After:
76
+
MyStruct::into_iter(my_struct);
77
+
```
78
+
79
+
Note: this only impacts methods which take `&self` and `&mut self` but not `self`.
71
80
72
81
### Inherent methods on `dyn Trait` objects
73
82
74
83
Some users invoke methods on a `dyn Trait` value where the method name overlaps with a new prelude trait:
75
84
76
85
```rust
77
-
traitFoo {
86
+
traitMyTrait {
87
+
// This has the same name as `std::iter::IntoIterator::into_iter`
0 commit comments