Skip to content

Commit 8dd83cc

Browse files
authored
Merge pull request #1 from nikomatsakis/pr-248
2 parents 466f68e + 67ec8b8 commit 8dd83cc

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

src/rust-2021/prelude.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ For example, if you have a crate or module called `example` containing a `pub st
1717
then `use example::*;` will make `Option` unambiguously refer to the one from `example`;
1818
not the one from the standard library.
1919

20-
However, adding a *trait* to the prelude can break existing code in a subtle way.
20+
However, adding a _trait_ to the prelude can break existing code in a subtle way.
2121
A call to `x.try_into()` using a `MyTryInto` trait might become ambiguous and
2222
fail to compile if `std`'s `TryInto` is also imported,
2323
since it provides a method with the same name.
@@ -33,7 +33,7 @@ It's identical to the current one, except for three new additions:
3333

3434
The tracking issue [can be found here](https://github.com/rust-lang/rust/issues/85684).
3535

36-
## Migration
36+
## Migration to Rust 2021
3737

3838
As a part of the 2021 edition a migration lint, `rust_2021_prelude_collisions`, has been added in order to aid in automatic migration of Rust 2018 codebases to Rust 2021.
3939

@@ -43,6 +43,47 @@ In order to have rustfix migrate your code to be Rust 2021 Edition compatible, r
4343
cargo fix --edition
4444
```
4545

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`() |
52+
53+
### Fully qualified calls to inherent methods
54+
55+
Many types define their own inherent methods with the name `from_iter`:
56+
57+
```rust
58+
struct Foo {
59+
data: Vec<u32>
60+
}
61+
impl Foo {
62+
fn from_iter(x: impl Iterator<Item = u32>) -> Self {
63+
Foo {
64+
data: x.collect()
65+
}
66+
}
67+
}
68+
```
69+
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.
71+
72+
### Inherent methods on `dyn Trait` objects
73+
74+
Some users invoke methods on a `dyn Trait` value where the method name overlaps with a new prelude trait:
75+
76+
```rust
77+
trait Foo {
78+
fn into_iter(&self);
79+
}
80+
fn bar(f: &dyn Foo) {
81+
f.into_iter();
82+
}
83+
```
84+
85+
In these cases, the lint will sometimes rewrite to introduce additional dereferences or otherwise clarify the type of the method receiver. This ensures that the `dyn Trait` method is chosen, versus the methods from the prelude trait. For example, `f.into_iter()` above would become `(*f).into_iter()`.
86+
4687
### Implementation Reference
4788

4889
The lint needs to take a couple of factors into account when determining whether or not introducing 2021 Edition to a codebase will cause a name resolution collision (thus breaking the code after changing edition). These factors include:

0 commit comments

Comments
 (0)