Skip to content

Commit 1dd0767

Browse files
committed
Apply feedback on PR
1 parent 8dd83cc commit 1dd0767

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

src/rust-2021/prelude.md

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
## Summary
44

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.
77

88
## Details
99

@@ -18,11 +18,10 @@ then `use example::*;` will make `Option` unambiguously refer to the one from `e
1818
not the one from the standard library.
1919

2020
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.
2625

2726
As a solution, Rust 2021 will use a new prelude.
2827
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
4342
cargo fix --edition
4443
```
4544

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:
47-
48-
| Scenario | Example | Rewrite (if any) |
49-
| ------------------------------------------------------------------------ | --------------------- | -------------------- |
50-
| [Fully qualified inherent](#fully-qualified-calls-to-inherent-methods) | `Foo::from_iter(...)` | none |
51-
| [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.
5246

5347
### Fully qualified calls to inherent methods
5448

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`:
5650

5751
```rust
58-
struct Foo {
52+
struct MyStruct {
5953
data: Vec<u32>
6054
}
61-
impl Foo {
55+
56+
impl MyStruct {
57+
// This has the same name as `std::iter::FromIterator::from_iter`
6258
fn from_iter(x: impl Iterator<Item = u32>) -> Self {
63-
Foo {
59+
Self {
6460
data: x.collect()
6561
}
6662
}
6763
}
6864
```
6965

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`.
7180

7281
### Inherent methods on `dyn Trait` objects
7382

7483
Some users invoke methods on a `dyn Trait` value where the method name overlaps with a new prelude trait:
7584

7685
```rust
77-
trait Foo {
86+
trait MyTrait {
87+
// This has the same name as `std::iter::IntoIterator::into_iter`
7888
fn into_iter(&self);
7989
}
80-
fn bar(f: &dyn Foo) {
90+
91+
fn bar(f: &dyn MyTrait) {
8192
f.into_iter();
8293
}
8394
```

0 commit comments

Comments
 (0)