]>
Commit | Line | Data |
---|---|---|
5099ac24 | 1 | # Implementing new features |
532ac7d7 XL |
2 | |
3 | When you want to implement a new significant feature in the compiler, | |
4 | you need to go through this process to make sure everything goes | |
5 | smoothly. | |
6 | ||
5099ac24 | 7 | ## The @rfcbot FCP process |
532ac7d7 XL |
8 | |
9 | When the change is small and uncontroversial, then it can be done | |
5099ac24 | 10 | with just writing a PR and getting an r+ from someone who knows that |
532ac7d7 XL |
11 | part of the code. However, if the change is potentially controversial, |
12 | it would be a bad idea to push it without consensus from the rest | |
13 | of the team (both in the "distributed system" sense to make sure | |
14 | you don't break anything you don't know about, and in the social | |
15 | sense to avoid PR fights). | |
16 | ||
5099ac24 FG |
17 | If such a change seems to be too small to require a full formal RFC process |
18 | (e.g., a small standard library addition, a big refactoring of the code, a | |
19 | "technically-breaking" change, or a "big bugfix" that basically amounts to a | |
20 | small feature) but is still too controversial or big to get by with a single r+, | |
21 | you can propose a final comment period (FCP). Or, if you're not on the relevant | |
22 | team (and thus don't have @rfcbot permissions), ask someone who is to start one; | |
23 | unless they have a concern themselves, they should. | |
24 | ||
25 | Again, the FCP process is only needed if you need consensus – if you | |
26 | don't think anyone would have a problem with your change, it's OK to | |
532ac7d7 | 27 | get by with only an r+. For example, it is OK to add or modify |
5099ac24 | 28 | unstable command-line flags or attributes without an FCP for |
532ac7d7 XL |
29 | compiler development or standard library use, as long as you don't |
30 | expect them to be in wide use in the nightly ecosystem. | |
31 | ||
5099ac24 FG |
32 | You don't need to have the implementation fully ready for r+ to propose an FCP, |
33 | but it is generally a good idea to have at least a proof | |
532ac7d7 XL |
34 | of concept so that people can see what you are talking about. |
35 | ||
5099ac24 FG |
36 | When an FCP is proposed, it requires all members of the team to sign off the |
37 | FCP. After they all do so, there's a 10-day-long "final comment period" (hence | |
38 | the name) where everybody can comment, and if no concerns are raised, the | |
39 | PR/issue gets FCP approval. | |
532ac7d7 XL |
40 | |
41 | ## The logistics of writing features | |
42 | ||
43 | There are a few "logistic" hoops you might need to go through in | |
44 | order to implement a feature in a working way. | |
45 | ||
46 | ### Warning Cycles | |
47 | ||
48 | In some cases, a feature or bugfix might break some existing programs | |
49 | in some edge cases. In that case, you might want to do a crater run | |
50 | to assess the impact and possibly add a future-compatibility lint, | |
51 | similar to those used for | |
dc9dc135 | 52 | [edition-gated lints](diagnostics.md#edition-gated-lints). |
532ac7d7 XL |
53 | |
54 | ### Stability | |
55 | ||
56 | We [value the stability of Rust]. Code that works and runs on stable | |
57 | should (mostly) not break. Because of that, we don't want to release | |
58 | a feature to the world with only team consensus and code review - | |
59 | we want to gain real-world experience on using that feature on nightly, | |
60 | and we might want to change the feature based on that experience. | |
61 | ||
62 | To allow for that, we must make sure users don't accidentally depend | |
63 | on that new feature - otherwise, especially if experimentation takes | |
64 | time or is delayed and the feature takes the trains to stable, | |
65 | it would end up de facto stable and we'll not be able to make changes | |
66 | in it without breaking people's code. | |
67 | ||
68 | The way we do that is that we make sure all new features are feature | |
ba9703b0 | 69 | gated - they can't be used without enabling a feature gate |
532ac7d7 XL |
70 | (`#[feature(foo)]`), which can't be done in a stable/beta compiler. |
71 | See the [stability in code] section for the technical details. | |
72 | ||
73 | Eventually, after we gain enough experience using the feature, | |
74 | make the necessary changes, and are satisfied, we expose it to | |
75 | the world using the stabilization process described [here]. | |
76 | Until then, the feature is not set in stone: every part of the | |
77 | feature can be changed, or the feature might be completely | |
78 | rewritten or removed. Features are not supposed to gain tenure | |
79 | by being unstable and unchanged for a year. | |
80 | ||
532ac7d7 XL |
81 | ### Tracking Issues |
82 | ||
83 | To keep track of the status of an unstable feature, the | |
84 | experience we get while using it on nightly, and of the | |
85 | concerns that block its stabilization, every feature-gate | |
86 | needs a tracking issue. | |
87 | ||
88 | General discussions about the feature should be done on | |
89 | the tracking issue. | |
90 | ||
91 | For features that have an RFC, you should use the RFC's | |
92 | tracking issue for the feature. | |
93 | ||
94 | For other features, you'll have to make a tracking issue | |
95 | for that feature. The issue title should be "Tracking issue | |
96 | for YOUR FEATURE". | |
97 | ||
98 | For tracking issues for features (as opposed to future-compat | |
99 | warnings), I don't think the description has to contain | |
100 | anything specific. Generally we put the list of items required | |
60c5eb7d | 101 | for stabilization in a checklist, e.g., |
532ac7d7 XL |
102 | |
103 | ```txt | |
60c5eb7d | 104 | **Steps:** |
532ac7d7 | 105 | |
60c5eb7d XL |
106 | - [ ] Implement the RFC. (CC @rust-lang/compiler -- can anyone write |
107 | up mentoring instructions?) | |
064997fb FG |
108 | - [ ] Adjust the documentation. ([See instructions on rustc-dev-guide.](stabilization_guide.md#documentation-prs)) |
109 | - [ ] Stabilize the feature. ([See instructions on rustc-dev-guide.](stabilization_guide.md#stabilization-pr)) | |
532ac7d7 XL |
110 | ``` |
111 | ||
532ac7d7 XL |
112 | ## Stability in code |
113 | ||
114 | The below steps needs to be followed in order to implement | |
115 | a new unstable feature: | |
116 | ||
117 | 1. Open a [tracking issue] - | |
118 | if you have an RFC, you can use the tracking issue for the RFC. | |
119 | ||
60c5eb7d XL |
120 | The tracking issue should be labeled with at least `C-tracking-issue`. |
121 | For a language feature, a label `F-feature_name` should be added as well. | |
122 | ||
532ac7d7 XL |
123 | 2. Pick a name for the feature gate (for RFCs, use the name |
124 | in the RFC). | |
125 | ||
6a06907d XL |
126 | 3. Add a feature gate declaration to `rustc_feature/src/active.rs` |
127 | in the active `declare_features` block. See [here][add-feature-gate] for | |
128 | detailed instructions. | |
532ac7d7 XL |
129 | |
130 | 4. Prevent usage of the new feature unless the feature gate is set. | |
131 | You can check it in most places in the compiler using the | |
132 | expression `tcx.features().$feature_name` (or | |
133 | `sess.features_untracked().$feature_name` if the | |
134 | tcx is unavailable) | |
135 | ||
136 | If the feature gate is not set, you should either maintain | |
137 | the pre-feature behavior or raise an error, depending on | |
6a06907d XL |
138 | what makes sense. Errors should generally use [`rustc_session::parse::feature_err`]. |
139 | For an example of adding an error, see [#81015]. | |
532ac7d7 | 140 | |
60c5eb7d XL |
141 | For features introducing new syntax, pre-expansion gating should be used instead. |
142 | To do so, extend the [`GatedSpans`] struct, add spans to it during parsing, | |
dfeec247 XL |
143 | and then finally feature-gate all the spans in |
144 | [`rustc_ast_passes::feature_gate::check_crate`]. | |
60c5eb7d | 145 | |
532ac7d7 XL |
146 | 5. Add a test to ensure the feature cannot be used without |
147 | a feature gate, by creating `feature-gate-$feature_name.rs` | |
148 | and `feature-gate-$feature_name.stderr` files under the | |
60c5eb7d | 149 | directory where the other tests for your feature reside. |
532ac7d7 XL |
150 | |
151 | 6. Add a section to the unstable book, in | |
152 | `src/doc/unstable-book/src/language-features/$feature_name.md`. | |
153 | ||
6a06907d | 154 | 7. Write a lot of tests for the new feature. |
532ac7d7 XL |
155 | PRs without tests will not be accepted! |
156 | ||
157 | 8. Get your PR reviewed and land it. You have now successfully | |
158 | implemented a feature in Rust! | |
159 | ||
74b04a01 | 160 | [`GatedSpans`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.GatedSpans.html |
6a06907d XL |
161 | [#81015]: https://github.com/rust-lang/rust/pull/81015 |
162 | [`rustc_session::parse::feature_err`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/fn.feature_err.html | |
dfeec247 | 163 | [`rustc_ast_passes::feature_gate::check_crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_passes/feature_gate/fn.check_crate.html |
532ac7d7 XL |
164 | [value the stability of Rust]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md |
165 | [stability in code]: #stability-in-code | |
60c5eb7d | 166 | [here]: ./stabilization_guide.md |
532ac7d7 | 167 | [tracking issue]: #tracking-issue |
6a06907d | 168 | [add-feature-gate]: ./feature-gates.md#adding-a-feature-gate |