Skip to content

Commit 2cae289

Browse files
committed
reduce overlong physical lines
1 parent 60eb95c commit 2cae289

File tree

1 file changed

+133
-53
lines changed

1 file changed

+133
-53
lines changed

src/implementing_new_features.md

Lines changed: 133 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
# Implementing new language features
44

5-
When you want to implement a new significant feature in the compiler, you need to go through this process to make sure everything goes smoothly.
5+
When you want to implement a new significant feature in the compiler,
6+
you need to go through this process to make sure everything goes smoothly.
67

7-
**NOTE: This section is for *language* features, not *library* features, which use [a different process].**
8+
**NOTE: This section is for *language* features, not *library* features,
9+
which use [a different process].**
810

911
See also [the Rust Language Design Team's procedures][lang-propose] for proposing changes to the language.
1012

@@ -13,58 +15,95 @@ See also [the Rust Language Design Team's procedures][lang-propose] for proposin
1315

1416
## The @rfcbot FCP process
1517

16-
When the change is small, uncontroversial, non-breaking, and does not affect the stable language in any user-observable ways or add any new unstable features, then it can be done with just writing a PR and getting an r+ from someone who knows that part of the code.
18+
When the change is small, uncontroversial, non-breaking,
19+
and does not affect the stable language in any user-observable ways or add any new unstable features,
20+
then it can be done with just writing a PR and getting an r+ from someone who knows that part of the code.
1721
However, if not, more must be done.
18-
Even for compiler-internal work, it would be a bad idea to push a controversial change without consensus from the rest of the team (both in the "distributed system" sense to make sure you don't break anything you don't know about, and in the social sense to avoid PR fights).
19-
20-
For changes that need the consensus of a team, we use the process of proposing a final comment period (FCP).
21-
If you're not on the relevant team (and thus don't have @rfcbot permissions), ask someone who is to start one;
22+
Even for compiler-internal work,
23+
it would be a bad idea to push a controversial change without consensus from the rest of the team
24+
(both in the "distributed system" sense to make sure you don't break anything you don't know about,
25+
and in the social sense to avoid PR fights).
26+
27+
For changes that need the consensus of a team,
28+
we use the process of proposing a final comment period (FCP).
29+
If you're not on the relevant team (and thus don't have @rfcbot permissions),
30+
ask someone who is to start one;
2231
unless they have a concern themselves, they should.
2332

24-
The FCP process is only needed if you need consensus – if no processes require consensus for your change and you don't think anyone would have a problem with it, it's OK to rely on only an r+.
25-
For example, it is OK to add or modify unstable command-line flags or attributes in the reserved compiler-internal `rustc_` namespace without an FCP for compiler development or standard library use, as long as you don't expect them to be in wide use in the nightly ecosystem.
33+
The FCP process is only needed if you need consensus –
34+
if no processes require consensus for your change
35+
and you don't think anyone would have a problem with it, it's OK to rely on only an r+.
36+
For example,
37+
it is OK to add or modify unstable command-line flags
38+
or attributes in the reserved compiler-internal `rustc_` namespace
39+
without an FCP for compiler development or standard library use,
40+
as long as you don't expect them to be in wide use in the nightly ecosystem.
2641
Some teams have lighter weight processes that they use in scenarios like this;
27-
for example, the compiler team recommends filing a Major Change Proposal ([MCP][mcp]) as a lightweight way to garner support and feedback without requiring full consensus.
42+
for example,
43+
the compiler team recommends filing a Major Change Proposal ([MCP][mcp])
44+
as a lightweight way to garner support and feedback without requiring full consensus.
2845

2946
[mcp]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp
3047

31-
You don't need to have the implementation fully ready for r+ to propose an FCP, but it is generally a good idea to have at least a proof of concept so that people can see what you are talking about.
48+
You don't need to have the implementation fully ready for r+ to propose an FCP,
49+
but it is generally a good idea to have at least a proof of concept
50+
so that people can see what you are talking about.
3251

3352
When an FCP is proposed, it requires all members of the team to sign off on the FCP.
34-
After they all do so, there's a 10-day-long "final comment period" (hence the name) where everybody can comment, and if no concerns are raised, the PR/issue gets FCP approval.
53+
After they all do so,
54+
there's a 10-day-long "final comment period" (hence the name) where everybody can comment,
55+
and if no concerns are raised, the PR/issue gets FCP approval.
3556

3657
## The logistics of writing features
3758

38-
There are a few "logistical" hoops you might need to go through in order to implement a feature in a working way.
59+
There are a few "logistical" hoops you might need to go through
60+
in order to implement a feature in a working way.
3961

4062
### Warning Cycles
4163

4264
In some cases, a feature or bugfix might break some existing programs in some edge cases.
43-
In that case, you'll want to do a crater run to assess the impact and possibly add a future-compatibility lint, similar to those used for [edition-gated lints](diagnostics.md#edition-gated-lints).
65+
In that case,
66+
you'll want to do a crater run to assess the impact and possibly add a future-compatibility lint,
67+
similar to those used for [edition-gated lints](diagnostics.md#edition-gated-lints).
4468

4569
### Stability
4670

4771
We [value the stability of Rust].
4872
Code that works and runs on stable should (mostly) not break.
49-
Because of that, we don't want to release a feature to the world with only team consensus and code review - we want to gain real-world experience on using that feature on nightly, and we might want to change the feature based on that experience.
50-
51-
To allow for that, we must make sure users don't accidentally depend on that new feature - otherwise, especially if experimentation takes time or is delayed and the feature takes the trains to stable, it would end up de facto stable and we'll not be able to make changes in it without breaking people's code.
52-
53-
The way we do that is that we make sure all new features are feature gated - they can't be used without enabling a feature gate (`#[feature(foo)]`), which can't be done in a stable/beta compiler.
73+
Because of that,
74+
we don't want to release a feature to the world with only team consensus and code review -
75+
we want to gain real-world experience on using that feature on nightly,
76+
and we might want to change the feature based on that experience.
77+
78+
To allow for that,
79+
we must make sure users don't accidentally depend on that new feature -
80+
otherwise,
81+
especially if experimentation takes time or is delayed and the feature takes the trains to stable,
82+
it would end up de facto stable
83+
and we'll not be able to make changes in it without breaking people's code.
84+
85+
The way we do that is that we make sure all new features are feature gated -
86+
they can't be used without enabling a feature gate (`#[feature(foo)]`),
87+
which can't be done in a stable/beta compiler.
5488
See the [stability in code] section for the technical details.
5589

56-
Eventually, after we gain enough experience using the feature, make the necessary changes, and are satisfied, we expose it to the world using the stabilization process described [here].
57-
Until then, the feature is not set in stone: every part of the feature can be changed, or the feature might be completely rewritten or removed.
90+
Eventually, after we gain enough experience using the feature, make the necessary changes,
91+
and are satisfied, we expose it to the world using the stabilization process described [here].
92+
Until then, the feature is not set in stone:
93+
every part of the feature can be changed, or the feature might be completely rewritten or removed.
5894
Features do not gain tenure by being unstable and unchanged for long periods of time.
5995

6096
### Tracking Issues
6197

62-
To keep track of the status of an unstable feature, the experience we get while using it on
63-
nightly, and of the concerns that block its stabilization, every feature-gate needs a tracking
64-
issue.
65-
When creating issues and PRs related to the feature, reference this tracking issue, and when there are updates about the feature's progress, post those to the tracking issue.
98+
To keep track of the status of an unstable feature,
99+
the experience we get while using it on nightly,
100+
and of the concerns that block its stabilization,
101+
every feature-gate needs a tracking issue.
102+
When creating issues and PRs related to the feature, reference this tracking issue,
103+
and when there are updates about the feature's progress, post those to the tracking issue.
66104

67-
For features that are part of an accept RFC or approved lang experiment, use the tracking issue for that.
105+
For features that are part of an accept RFC or approved lang experiment,
106+
use the tracking issue for that.
68107

69108
For other features, create a tracking issue for that feature.
70109
The issue title should be "Tracking issue for YOUR FEATURE".
@@ -74,39 +113,50 @@ Use the ["Tracking Issue" issue template][template].
74113

75114
### Lang experiments
76115

77-
To land in the compiler, features that have user-visible effects on the language (even unstable ones) must either be part of an accepted RFC or an approved [lang experiment].
116+
To land in the compiler,
117+
features that have user-visible effects on the language (even unstable ones)
118+
must either be part of an accepted RFC or an approved [lang experiment].
78119

79-
To propose a new lang experiment, open an issue in `rust-lang/rust` that describes the motivation and the intended solution.
80-
If it's accepted, this issue will become the tracking issue for the experiment, so use the tracking issue [template] while also including these other details.
120+
To propose a new lang experiment,
121+
open an issue in `rust-lang/rust` that describes the motivation and the intended solution.
122+
If it's accepted, this issue will become the tracking issue for the experiment,
123+
so use the tracking issue [template] while also including these other details.
81124
Nominate the issue for the lang team and CC `@rust-lang/lang` and `@rust-lang/lang-advisors`.
82125
When the experiment is approved, the tracking issue will be marked as `B-experimental`.
83126

84-
Feature flags related to a lang experiment must be marked as `incomplete` until an RFC is accepted for the feature.
127+
Feature flags related to a lang experiment must be marked as `incomplete`
128+
until an RFC is accepted for the feature.
85129

86130
[lang experiment]: https://lang-team.rust-lang.org/how_to/experiment.html
87131

88132
## Stability in code
89133

90134
The below steps needs to be followed in order to implement a new unstable feature:
91135

92-
1. Open or identify the [tracking issue]. For features that are part of an accept RFC or approved lang experiment, use the tracking issue for that.
136+
1. Open or identify the [tracking issue].
137+
For features that are part of an accept RFC or approved lang experiment,
138+
use the tracking issue for that.
93139

94-
Label the tracking issue with `C-tracking-issue` and the relevant `F-feature_name` label (adding that label if needed).
140+
Label the tracking issue with `C-tracking-issue` and the relevant `F-feature_name` label
141+
(adding that label if needed).
95142

96143
1. Pick a name for the feature gate (for RFCs, use the name in the RFC).
97144

98145
1. Add the feature name to `rustc_span/src/symbol.rs` in the `Symbols {...}` block.
99146

100147
Note that this block must be in alphabetical order.
101148

102-
1. Add a feature gate declaration to `rustc_feature/src/unstable.rs` in the unstable `declare_features` block.
149+
1. Add a feature gate declaration to `rustc_feature/src/unstable.rs`
150+
in the unstable `declare_features` block.
103151

104152
```rust ignore
105153
/// description of feature
106154
(unstable, $feature_name, "CURRENT_RUSTC_VERSION", Some($tracking_issue_number))
107155
```
108156

109-
If you haven't yet opened a tracking issue (e.g. because you want initial feedback on whether the feature is likely to be accepted), you can temporarily use `None` - but make sure to update it before the PR is merged!
157+
If you haven't yet opened a tracking issue
158+
(e.g. because you want initial feedback on whether the feature is likely to be accepted),
159+
you can temporarily use `None` - but make sure to update it before the PR is merged!
110160

111161
For example:
112162

@@ -115,7 +165,9 @@ The below steps needs to be followed in order to implement a new unstable featur
115165
(unstable, non_ascii_idents, "CURRENT_RUSTC_VERSION", Some(55467), None),
116166
```
117167

118-
Features can be marked as incomplete, and trigger the warn-by-default [`incomplete_features` lint] by setting their type to `incomplete`:
168+
Features can be marked as incomplete,
169+
and trigger the warn-by-default [`incomplete_features` lint]
170+
by setting their type to `incomplete`:
119171

120172
[`incomplete_features` lint]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features
121173

@@ -124,29 +176,45 @@ The below steps needs to be followed in order to implement a new unstable featur
124176
(incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None),
125177
```
126178

127-
Feature flags related to a lang experiment must be marked as `incomplete` until an RFC is accepted for the feature.
179+
Feature flags related to a lang experiment must be marked as `incomplete`
180+
until an RFC is accepted for the feature.
128181

129-
To avoid [semantic merge conflicts], use `CURRENT_RUSTC_VERSION` instead of `1.70` or another explicit version number.
182+
To avoid [semantic merge conflicts],
183+
use `CURRENT_RUSTC_VERSION` instead of `1.70` or another explicit version number.
130184

131185
[semantic merge conflicts]: https://bors.tech/essay/2017/02/02/pitch/
132186

133-
1. Prevent usage of the new feature unless the feature gate is set. You can check it in most places in the compiler using the expression `tcx.features().$feature_name()`.
187+
1. Prevent usage of the new feature unless the feature gate is set.
188+
You can check it in most places in the compiler
189+
using the expression `tcx.features().$feature_name()`.
134190

135-
If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on what makes sense.
191+
If the feature gate is not set,
192+
you should either maintain the pre-feature behavior or raise an error,
193+
depending on what makes sense.
136194
Errors should generally use [`rustc_session::parse::feature_err`].
137195
For an example of adding an error, see [#81015].
138196

139197
For features introducing new syntax, pre-expansion gating should be used instead.
140-
During parsing, when the new syntax is parsed, the symbol must be inserted to the current crate's [`GatedSpans`] via `self.sess.gated_span.gate(sym::my_feature, span)`.
198+
During parsing, when the new syntax is parsed,
199+
the symbol must be inserted to the current crate's [`GatedSpans`]
200+
via `self.sess.gated_span.gate(sym::my_feature, span)`.
141201

142-
After being inserted to the gated spans, the span must be checked in the [`rustc_ast_passes::feature_gate::check_crate`] function, which actually denies features.
143-
Exactly how it is gated depends on the exact type of feature, but most likely will use the `gate_all!()` macro.
202+
After being inserted to the gated spans,
203+
the span must be checked in the [`rustc_ast_passes::feature_gate::check_crate`] function,
204+
which actually denies features.
205+
Exactly how it is gated depends on the exact type of feature,
206+
but most likely will use the `gate_all!()` macro.
144207

145-
1. Add a test to ensure the feature cannot be used without a feature gate, by creating `tests/ui/feature-gates/feature-gate-$feature_name.rs`. You can generate the corresponding `.stderr` file by running `./x test tests/ui/feature-gates/ --bless`.
208+
1. Add a test to ensure the feature cannot be used without a feature gate,
209+
by creating `tests/ui/feature-gates/feature-gate-$feature_name.rs`.
210+
You can generate the corresponding `.stderr` file
211+
by running `./x test tests/ui/feature-gates/ --bless`.
146212

147-
1. Add a section to the unstable book, in `src/doc/unstable-book/src/language-features/$feature_name.md`.
213+
1. Add a section to the unstable book,
214+
in `src/doc/unstable-book/src/language-features/$feature_name.md`.
148215

149-
1. Write a lot of tests for the new feature, preferably in `tests/ui/$feature_name/`. PRs without tests will not be accepted!
216+
1. Write a lot of tests for the new feature, preferably in `tests/ui/$feature_name/`.
217+
PRs without tests will not be accepted!
150218

151219
1. Get your PR reviewed and land it. You have now successfully implemented a feature in Rust!
152220

@@ -162,8 +230,10 @@ The below steps needs to be followed in order to implement a new unstable featur
162230

163231
## Call for testing
164232

165-
Once the implementation is complete, the feature will be available to nightly users but not yet part of stable Rust.
166-
This is a good time to write a blog post on [the main Rust blog][rust-blog] and issue a "call for testing".
233+
Once the implementation is complete,
234+
the feature will be available to nightly users but not yet part of stable Rust.
235+
This is a good time to write a blog post on [the main Rust blog][rust-blog]
236+
and issue a "call for testing".
167237

168238
Some earlier such blog posts include:
169239

@@ -176,7 +246,9 @@ One example of this having been used is:
176246

177247
- [Call for testing on boolean literals as cfg predicates](https://github.com/rust-lang/rust/issues/131204#issuecomment-2569314526)
178248

179-
Which option to choose might depend on how significant the language change is, though note that the [*This Week in Rust*][twir] section might be less visible than a dedicated post on the main Rust blog.
249+
Which option to choose might depend on how significant the language change is,
250+
though note that the [*This Week in Rust*][twir] section might be less visible
251+
than a dedicated post on the main Rust blog.
180252

181253
## Polishing
182254

@@ -186,14 +258,22 @@ This work includes:
186258

187259
- Documenting the language feature in the [Rust Reference][reference].
188260
- Extending [`rustfmt`] to format any new syntax (if applicable).
189-
- Extending [`rust-analyzer`] (if applicable). The extent of this work can depend on the nature of the language feature, as some features don't need to be blocked on *full* support.
190-
- When a language feature degrades the user experience simply by existing before support is implemented in [`rust-analyzer`], that may lead the lang team to raise a blocking concern.
191-
- Examples of such might include new syntax that [`rust-analyzer`] can't parse or type inference changes it doesn't understand when those lead to bogus diagnostics.
261+
- Extending [`rust-analyzer`] (if applicable).
262+
The extent of this work can depend on the nature of the language feature,
263+
as some features don't need to be blocked on *full* support.
264+
- When a language feature degrades the user experience
265+
simply by existing before support is implemented in [`rust-analyzer`],
266+
that may lead the lang team to raise a blocking concern.
267+
- Examples of such might include new syntax that [`rust-analyzer`] can't parse
268+
or type inference changes it doesn't understand when those lead to bogus diagnostics.
192269

193270
## Stabilization
194271

195-
The final step in the feature lifecycle is [stabilization][stab], which is when the feature becomes available to all Rust users.
196-
At this point, backward incompatible changes are generally no longer permitted (see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for details).
272+
The final step in the feature lifecycle is [stabilization][stab],
273+
which is when the feature becomes available to all Rust users.
274+
At this point,
275+
backward incompatible changes are generally no longer permitted
276+
(see the lang team's [defined semver policies](https://rust-lang.github.io/rfcs/1122-language-semver.html) for details).
197277
To learn more about stabilization, see the [stabilization guide][stab].
198278

199279

0 commit comments

Comments
 (0)