Skip to content

Commit 0b056f7

Browse files
committed
Reverse changes to #1122, which I will extract into a distinct RFC for more visibility
1 parent e17464c commit 0b056f7

File tree

1 file changed

+42
-65
lines changed

1 file changed

+42
-65
lines changed

text/1122-language-semver.md

+42-65
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,37 @@ how to go about making such changes.
1414
With the release of 1.0, we need to establish clear policy on what
1515
precisely constitutes a "minor" vs "major" change to the Rust language
1616
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
1818
changes that fix compiler bugs or other type-system
1919
issues**. Primarily, this means soundness issues where "innocent" code
2020
can cause undefined behavior (in the technical sense), but it also
2121
covers cases like compiler bugs and tightening up the semantics of
2222
"underspecified" parts of the language (more details below).
2323

24-
Simply landing all breaking changes immediately could be very
24+
However, simply landing all breaking changes immediately could be very
2525
disruptive to the ecosystem. Therefore, **the RFC also proposes
2626
specific measures to mitigate the impact of breaking changes**, and
2727
some criteria when those measures might be appropriate.
2828

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
3030
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.
3634

3735
# Detailed design
3836

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

4149
The first step then is to evaluate the impact of the fix on the crates
4250
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
4856
code. A description of the problem should also appear in the relevant
4957
subteam report.
5058

51-
### Techniques for easing the transition
52-
5359
In cases where the impact seems larger, any effort to ease the
5460
transition is sure to be welcome. The following are suggestions for
5561
possible steps we could take (not all of which will be applicable to
@@ -74,8 +80,6 @@ all scenarios):
7480
However, this option may frequently not be available, because the
7581
source of a compilation error is often hard to pin down with
7682
precision.
77-
78-
### Other factors to consider
7983

8084
Some of the factors that should be taken into consideration when
8185
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,
138142
particularly those cases where the severity of the problem is
139143
relatively small, it could be an option to leave the "opt out"
140144
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.
150146

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

155150
#### Changes that alter dynamic semantics versus typing rules
156151

@@ -234,53 +229,15 @@ future as well. The `-Z` flags are of course explicitly unstable, but
234229
some of the `-C`, rustdoc, and linker-specific flags are expected to
235230
evolve over time (see e.g. [#24451]).
236231

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-
277232
# Drawbacks
278233

279234
The primary drawback is that making breaking changes are disruptive,
280235
even when done with the best of intentions. The alternatives list some
281236
ways that we could avoid breaking changes altogether, and the
282237
downsides of each.
283238

239+
## Notes on phasing
240+
284241
# Alternatives
285242

286243
**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:
312269
it is certainly possible that all crates on `crates.io` work fine, but
313270
the change still breaks a large body of code we do not have access to.
314271

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+
315292
[RFC 1105]: https://github.com/rust-lang/rfcs/pull/1105
316293
[RFC 320]: https://github.com/rust-lang/rfcs/pull/320
317294
[#744]: https://github.com/rust-lang/rfcs/issues/744

0 commit comments

Comments
 (0)