@@ -14,29 +14,37 @@ how to go about making such changes.
14
14
With the release of 1.0, we need to establish clear policy on what
15
15
precisely constitutes a "minor" vs "major" change to the Rust language
16
16
itself (as opposed to libraries, which are covered by [ RFC 1105] ).
17
- ** This RFC proposes that minor releases may contain breaking
17
+ ** This RFC proposes that minor releases may only contain breaking
18
18
changes that fix compiler bugs or other type-system
19
19
issues** . Primarily, this means soundness issues where "innocent" code
20
20
can cause undefined behavior (in the technical sense), but it also
21
21
covers cases like compiler bugs and tightening up the semantics of
22
22
"underspecified" parts of the language (more details below).
23
23
24
- Simply landing all breaking changes immediately could be very
24
+ However, simply landing all breaking changes immediately could be very
25
25
disruptive to the ecosystem. Therefore, ** the RFC also proposes
26
26
specific measures to mitigate the impact of breaking changes** , and
27
27
some criteria when those measures might be appropriate.
28
28
29
- In rare cases, it may be deemed worthwhile to make a breaking change
29
+ In rare cases, it may be deemed a good idea to make a breaking change
30
30
that is not a soundness problem or compiler bug, but rather correcting
31
- a defect in design. ** These changes are to be avoided, but may be
32
- permissible if the impact is judged to be negligible (and thus there
33
- is expected to be no breakage in practice).** This RFC also includes
34
- criteria for how to estimate the impact of a change and advice on the
35
- timing of such changes.
31
+ a defect in design. Such cases should be rare. But if such a change is
32
+ deemed worthwhile, then the guidelines given here can still be used to
33
+ mitigate its impact.
36
34
37
35
# Detailed design
38
36
39
- ### Evaluating the impact of a change
37
+ The detailed design is broken into two major sections: how to address
38
+ soundness changes, and how to address other, opt-in style changes. We
39
+ do not discuss non-breaking changes here, since obviously those are
40
+ safe.
41
+
42
+ ### Soundness changes
43
+
44
+ When compiler or type-system bugs are encountered in the language
45
+ itself (as opposed to in a library), clearly they ought to be
46
+ fixed. However, it is important to fix them in such a way as to
47
+ minimize the impact on the ecosystem.
40
48
41
49
The first step then is to evaluate the impact of the fix on the crates
42
50
found in the ` crates.io ` website (using e.g. the crater tool). If
@@ -48,8 +56,6 @@ problem, which helps those people who are affected to migrate their
48
56
code. A description of the problem should also appear in the relevant
49
57
subteam report.
50
58
51
- ### Techniques for easing the transition
52
-
53
59
In cases where the impact seems larger, any effort to ease the
54
60
transition is sure to be welcome. The following are suggestions for
55
61
possible steps we could take (not all of which will be applicable to
@@ -74,8 +80,6 @@ all scenarios):
74
80
However, this option may frequently not be available, because the
75
81
source of a compilation error is often hard to pin down with
76
82
precision.
77
-
78
- ### Other factors to consider
79
83
80
84
Some of the factors that should be taken into consideration when
81
85
deciding whether and how to minimize the impact of a fix:
@@ -138,19 +142,10 @@ opt out will thus be removed in a later release. But in some cases,
138
142
particularly those cases where the severity of the problem is
139
143
relatively small, it could be an option to leave the "opt out"
140
144
mechanism in place permanently. In either case, use of the "opt out"
141
- API would trigger the deprecation lint. Note that we should make every
142
- effort to ensure that crates which employ this opt out can be used
143
- compatibly with crates that do not.
144
-
145
- Opt outs should be specified using the ` #[legacy(foo)] ` attribute.
146
- This attribute intentionally ignores unrecognized opt-outs (such as
147
- ` foo ` ) to allow for forwards compatibility with opt-outs that may be
148
- added in later compiler releases (in such cases, older compilers will
149
- naturally perform the legacy behavior).
145
+ API would trigger the deprecation lint.
150
146
151
- Ideally, opt-outs should be constructed in as targeted a fashion as
152
- possible. That means it is generally better, for example, to have
153
- users opt out individual items than an entire crate at once.
147
+ Note that we should make every effort to ensure that crates which
148
+ employ this opt out can be used compatibly with crates that do not.
154
149
155
150
#### Changes that alter dynamic semantics versus typing rules
156
151
@@ -234,53 +229,15 @@ future as well. The `-Z` flags are of course explicitly unstable, but
234
229
some of the ` -C ` , rustdoc, and linker-specific flags are expected to
235
230
evolve over time (see e.g. [ #24451 ] ).
236
231
237
- #### Other kinds of breaking changes
238
-
239
- From time to time, we may find a flaw in a design that is neither a
240
- soundness concern nor a bug fix, but rather simply a suboptimal
241
- decision. In general, it is best to find ways to correct such errors
242
- without making breaking changes, such as improved error messages or
243
- deprecation. However, if the impact of making the change is judged to
244
- be negligible, we can also consider fixing the problem, presuming that
245
- the following criteria are met (in addition to the criteria listed
246
- above in the section "Other Factors to Consider"):
247
-
248
- - All data indicates that correcting this flaw will break extremely little
249
- or no existing code (such as crates.io testing, communication with production
250
- users of Rust or other private developers, etc).
251
- - The feature was only recently stabilized, preferably in the previous
252
- cycle. This minimizes the possibility that a large body of code has
253
- crept up that relies on this feature.
254
- - If and when we establish LTS releases, we should never make
255
- changes to features marked as stable in a LTS release (except for
256
- soundness reasons).
257
- - There is no backwards compatible way to repair the problem.
258
-
259
- When we do decide to make such a change, we should follow one of the
260
- following ways to ease the transition, in order of preference:
261
-
262
- 1 . When possible, issue a release that gives warnings when changes will be required.
263
- - These warnings should be as targeted as possible -- if the warning
264
- is too broad, it can easily cause more annoyance than the change
265
- itself.
266
- - To maximize the chance of these warnings being taken seriously,
267
- the warning should not be a lint. The only way to disable it is to
268
- make a change that will be forwards compatible with the new
269
- version.
270
- - After a suitable time has elapsed (at least one cycle, possibly
271
- more), make the actual change.
272
- 2 . If warnings are not possible, then include a ` #[legacy] ` attribute
273
- that allows the old behavior to be restored.
274
- - Ideally, this ` #[legacy] ` attribute will only persist for a fixed
275
- number of cycles.
276
-
277
232
# Drawbacks
278
233
279
234
The primary drawback is that making breaking changes are disruptive,
280
235
even when done with the best of intentions. The alternatives list some
281
236
ways that we could avoid breaking changes altogether, and the
282
237
downsides of each.
283
238
239
+ ## Notes on phasing
240
+
284
241
# Alternatives
285
242
286
243
** Rather than simply fixing soundness bugs, we could issue new major
@@ -312,6 +269,26 @@ observe on `crates.io` will be of the total breakage that will occur:
312
269
it is certainly possible that all crates on ` crates.io ` work fine, but
313
270
the change still breaks a large body of code we do not have access to.
314
271
272
+ ** What attribute should we use to "opt out" of soundness changes?**
273
+ The section on breaking changes indicated that it may sometimes be
274
+ appropriate to includ an "opt out" that people can use to temporarily
275
+ revert to older, unsound type rules, but did not specify precisely
276
+ what that opt-out should look like. Ideally, we would identify a
277
+ specific attribute in advance that will be used for such purposes. In
278
+ the past, we have simply created ad-hoc attributes (e.g.,
279
+ ` #[old_orphan_check] ` ), but because custom attributes are forbidden by
280
+ stable Rust, this has the unfortunate side-effect of meaning that code
281
+ which opts out of the newer rules cannot be compiled on older
282
+ compilers (even though it's using the older type system rules). If we
283
+ introduce an attribute in advance we will not have this problem.
284
+
285
+ ** Are there any other circumstances in which we might perform a
286
+ breaking change?** In particular, it may happen from time to time that
287
+ we wish to alter some detail of a stable component. If we believe that
288
+ this change will not affect anyone, such a change may be worth doing,
289
+ but we'll have to work out more precise guidelines. [ RFC 1156] is an
290
+ example.
291
+
315
292
[ RFC 1105 ] : https://github.com/rust-lang/rfcs/pull/1105
316
293
[ RFC 320 ] : https://github.com/rust-lang/rfcs/pull/320
317
294
[ #744 ] : https://github.com/rust-lang/rfcs/issues/744
0 commit comments