Skip to content

Commit 317885e

Browse files
committed
Amend the Language Semver specification to reflect
the criteria from this RFC.
1 parent 721f2d7 commit 317885e

File tree

1 file changed

+53
-40
lines changed

1 file changed

+53
-40
lines changed

text/1122-language-semver.md

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,29 @@ 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 only contain breaking
17+
**This RFC proposes that minor releases may 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-
However, simply landing all breaking changes immediately could be very
24+
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 a good idea to make a breaking change
29+
In rare cases, it may be deemed worthwhile to make a breaking change
3030
that is not a soundness problem or compiler bug, but rather correcting
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.
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.
3436

3537
# Detailed design
3638

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.
39+
### Evaluating the impact of a change
4840

4941
The first step then is to evaluate the impact of the fix on the crates
5042
found in the `crates.io` website (using e.g. the crater tool). If
@@ -56,6 +48,8 @@ problem, which helps those people who are affected to migrate their
5648
code. A description of the problem should also appear in the relevant
5749
subteam report.
5850

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

8480
Some of the factors that should be taken into consideration when
8581
deciding whether and how to minimize the impact of a fix:
@@ -142,10 +138,19 @@ opt out will thus be removed in a later release. But in some cases,
142138
particularly those cases where the severity of the problem is
143139
relatively small, it could be an option to leave the "opt out"
144140
mechanism in place permanently. In either case, use of the "opt out"
145-
API would trigger the deprecation lint.
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.
146144

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.
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).
150+
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.
149154

150155
#### Changes that alter dynamic semantics versus typing rules
151156

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

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:
246+
247+
- All data indicates that correcting this flaw will break extremely little
248+
or no existing code (such as crates.io testing, communication with production
249+
users of Rust or other private developers, etc).
250+
- The feature was only recently stabilized, preferably in the previous
251+
cycle. This minimizes the possibility that a large body of code has
252+
crept up that relies on this feature.
253+
- If and when we establish LTS releases, we should never make
254+
changes to features marked as stable in a LTS release (except for
255+
soundness reasons).
256+
- There is no backwards compatible way to repair the problem.
257+
258+
Naturally, all of the concerns listed above in the section "Other
259+
Factors to Consider" also apply here. For example, we should consider
260+
the quality of the error messages that result from the breaking
261+
change, and evaluate whether it is possible to write code that works
262+
both before/after the change (which enables users to span compiler
263+
versions).
264+
232265
# Drawbacks
233266

234267
The primary drawback is that making breaking changes are disruptive,
@@ -269,26 +302,6 @@ observe on `crates.io` will be of the total breakage that will occur:
269302
it is certainly possible that all crates on `crates.io` work fine, but
270303
the change still breaks a large body of code we do not have access to.
271304

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-
292305
[RFC 1105]: https://github.com/rust-lang/rfcs/pull/1105
293306
[RFC 320]: https://github.com/rust-lang/rfcs/pull/320
294307
[#744]: https://github.com/rust-lang/rfcs/issues/744

0 commit comments

Comments
 (0)