7
7
[ summary ] : #summary
8
8
9
9
This RFC proposes a way to introduce new trait methods that conflict with
10
- existing trait methods in downstream crates in a backwards compatible fashion.
10
+ pre-edition [ ^ 1 ] trait methods in downstream crates in a backwards compatible fashion.
11
11
We do so by annotating new methods with the edition they're introduced in. Then
12
12
when ambigutity is detected between a new method in the standard library and an
13
- existing downstream method the compiler will check if the crate edition matches
13
+ pre-edition downstream method the compiler will check if the crate edition matches
14
14
the edition that the method was introduced in. If it does we pick the
15
- presumably pre-existing downstream method and output a warning that there was
15
+ pre-edition method and output a warning that there was
16
16
an ambigutity with a newly introduced std method and that this warning will be
17
17
promoted to a hard error in the next edition.
18
18
19
19
# Motivation
20
20
[ motivation ] : #motivation
21
21
22
22
Rust has had a long standing issue with breaking changes caused by introducing
23
- new methods that conflict with existing downstream methods. This issue is best
23
+ new methods that conflict with pre-edition downstream methods. This issue is best
24
24
exemplified with the recent attempt to move ` Itertools::intersperse ` into the
25
25
` Iterator ` trait which [ broke a large number of
26
26
crates] ( https://github.com/rust-lang/rust/issues/88967 ) . Continuing as we have
@@ -34,9 +34,9 @@ introduce methods like these without causing any breakage.
34
34
* written as though this feature is already implemented and stable*
35
35
36
36
The rust standard library recently added support for adding new methods to
37
- traits that conflict with existing methods with the same name on other traits
38
- without causing breakage due to ambiguity. Since adding this feature you may
39
- start running into errors that look like this
37
+ traits that conflict with pre-edition [ ^ 1 ] methods with the same name on other
38
+ traits without causing breakage due to ambiguity. Since adding this feature you
39
+ may start running into errors that look like this
40
40
41
41
```
42
42
warning[E0034]: multiple applicable items in scope
@@ -73,7 +73,7 @@ lifecycle, where methods are experimented within 3rd party crates and then
73
73
moved into the standard library once they've been thorougly tested. A classic
74
74
example of this is the ` Itertools ` crate for experimenting with extentions to
75
75
the ` Iterator ` trait. However this problem isn't restricted to extension traits
76
- of existing standard library traits, and can indeed become a problem whenever
76
+ of pre-edition standard library traits, and can indeed become a problem whenever
77
77
any two methods have the same name.
78
78
79
79
You can fix issues like this by manually editing the code to select the
@@ -82,10 +82,10 @@ can use cargo fix. cargo fix will make assumptions about how the methods relate
82
82
depending on if you're using cargo fix for an edition upgrade or not.
83
83
84
84
* ** Within same edition** cargo fix will assume that the new method is a drop
85
- in replacement of the existing downstream one and will disambiguate by
85
+ in replacement of the pre-edition downstream one and will disambiguate by
86
86
selecting the upstream method defined in ` std ` .
87
87
* ** As part of an edition upgrade** cargo fix will prioritize maintaining the
88
- same behavior, and will disambiguate by selecting the existing method that
88
+ same behavior, and will disambiguate by selecting the pre-edition method that
89
89
was being used previously.
90
90
91
91
To run cargo fix within the same edition run:
@@ -104,7 +104,7 @@ cargo fix --edition
104
104
```
105
105
106
106
In the example above this would replace the ambiguous code with
107
- ` Itertools::intersperse(it, sep) ` , maintaining the existing behavior.
107
+ ` Itertools::intersperse(it, sep) ` , maintaining the pre-edition behavior.
108
108
109
109
# Reference-level explanation
110
110
[ reference-level-explanation ] : #reference-level-explanation
@@ -122,11 +122,11 @@ normal and emit an error for the ambiguity.
122
122
123
123
This flag should be usable to resolve the following forms of breakage:
124
124
125
- * A new method on an existing trait ([ e.g.
125
+ * A new method on an pre-edition trait ([ e.g.
126
126
itertools::intersperse] ( https://github.com/rust-lang/rust/issues/88967 ) )
127
- * A new trait implementation of an existing trait on an existing types ([ e.g.
127
+ * A new trait implementation of an pre-edition trait on an pre-edition type ([ e.g.
128
128
ErrorKind Display] ( https://github.com/rust-lang/rust/issues/94507 ) )
129
- * A new inherent method on an existing type (no recent examples)
129
+ * A new inherent method on an pre-edition type (no recent examples)
130
130
131
131
# Drawbacks
132
132
[ drawbacks ] : #drawbacks
@@ -149,7 +149,11 @@ disambiguating the trait a method call should come from.
149
149
# Rationale and alternatives
150
150
[ rationale-and-alternatives ] : #rationale-and-alternatives
151
151
152
- [ This comment] ( https://github.com/rust-lang/rust/issues/88967#issuecomment-938024847 ) on the ` Iterator::intersperse ` issue details a few alternatives that were discussed by the libs team when we encountered that specific issue. These include both short term and long term suggestions.
152
+ [ This
153
+ comment] ( https://github.com/rust-lang/rust/issues/88967#issuecomment-938024847 )
154
+ on the ` Iterator::intersperse ` issue details a few alternatives that were
155
+ discussed by the libs team when we encountered that specific issue. These
156
+ include both short term and long term suggestions.
153
157
154
158
** Short Term**
155
159
@@ -188,15 +192,19 @@ supertrait.
188
192
## Interaction with autoderef
189
193
190
194
We already have logic for preferring stable methods to unstable methods but it
191
- breaks[ ^ 1 ] if the auto deref for one requires one more level of indirection
195
+ breaks[ ^ 2 ] if the auto deref for one requires one more level of indirection
192
196
than the other. We should be careful to consider how autoderef behavior can
193
197
affect edition based method disambiguation.
194
198
195
- [ ^ 1 ] : https://github.com/rust-lang/rust/issues/86682
196
199
197
200
# Future possibilities
198
201
[ future-possibilities ] : #future-possibilities
199
202
200
203
As this RFC previously pointed out in the drawbacks section, introducing a new
201
204
syntax for unambiguous method calls for a specific trait would significantly
202
205
improve the experience of resolving these warnings.
206
+
207
+ [ ^ 1 ] : Definition: Pre-edition methods are methods that could legally have been
208
+ introduced during the current edition which do not conflict with any methods
209
+ that existed during the initial release of the current edition.
210
+ [ ^ 2 ] : https://github.com/rust-lang/rust/issues/86682
0 commit comments