]> git.proxmox.com Git - rustc.git/blob - src/doc/rustc-guide/src/implementing_new_features.md
New upstream version 1.41.1+dfsg1
[rustc.git] / src / doc / rustc-guide / src / implementing_new_features.md
1 # Implement New Feature
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
7 ## The @rfcbot (p)FCP process
8
9 When the change is small and uncontroversial, then it can be done
10 with just writing a PR and getting r+ from someone who knows that
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
17 If such a change seems to be too small to require a full formal RFC
18 process (e.g. a big refactoring of the code, or a
19 "technically-breaking" change, or a "big bugfix" that basically
20 amounts to a small feature) but is still too controversial or
21 big to get by with a single r+, you can start a pFCP (or, if you
22 don't have r+ rights, ask someone who has them to start one - and
23 unless they have a concern themselves, they should).
24
25 Again, the pFCP 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
27 get by with only an r+. For example, it is OK to add or modify
28 unstable command-line flags or attributes without an pFCP for
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
32 You don't need to have the implementation fully ready for r+ to ask
33 for a pFCP, but it is generally a good idea to have at least a proof
34 of concept so that people can see what you are talking about.
35
36 That starts a "proposed final comment period" (pFCP), which requires
37 all members of the team to sign off the FCP. After they all do so,
38 there's a 10 day long "final comment period" where everybody can comment,
39 and if no new concerns are raised, the PR/issue gets FCP approval.
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
52 [edition-gated lints](diagnostics.md#edition-gated-lints).
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
69 gated - they can't be used without a enabling a feature gate
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
81 <a name = "tracking-issue"></a>
82 ### Tracking Issues
83
84 To keep track of the status of an unstable feature, the
85 experience we get while using it on nightly, and of the
86 concerns that block its stabilization, every feature-gate
87 needs a tracking issue.
88
89 General discussions about the feature should be done on
90 the tracking issue.
91
92 For features that have an RFC, you should use the RFC's
93 tracking issue for the feature.
94
95 For other features, you'll have to make a tracking issue
96 for that feature. The issue title should be "Tracking issue
97 for YOUR FEATURE".
98
99 For tracking issues for features (as opposed to future-compat
100 warnings), I don't think the description has to contain
101 anything specific. Generally we put the list of items required
102 for stabilization in a checklist, e.g.,
103
104 ```txt
105 **Steps:**
106
107 - [ ] Implement the RFC. (CC @rust-lang/compiler -- can anyone write
108 up mentoring instructions?)
109 - [ ] Adjust the documentation. ([See instructions on rustc-guide.](https://rust-lang.github.io/rustc-guide/stabilization_guide.html#documentation-prs))
110 - [ ] Stabilize the feature. ([See instructions on rustc-guide.](https://rust-lang.github.io/rustc-guide/stabilization_guide.html#stabilization-pr))
111 ```
112
113 <a name="stability-in-code"></a>
114 ## Stability in code
115
116 The below steps needs to be followed in order to implement
117 a new unstable feature:
118
119 1. Open a [tracking issue] -
120 if you have an RFC, you can use the tracking issue for the RFC.
121
122 The tracking issue should be labeled with at least `C-tracking-issue`.
123 For a language feature, a label `F-feature_name` should be added as well.
124
125 2. Pick a name for the feature gate (for RFCs, use the name
126 in the RFC).
127
128 3. Add a feature gate declaration to `libsyntax/feature_gate/active.rs`
129 in the active `declare_features` block:
130
131 ```rust,ignore
132 // description of feature
133 (active, $feature_name, "$current_nightly_version", Some($tracking_issue_number), $edition)
134 ```
135
136 where `$edition` has the type `Option<Edition>`, and is typically
137 just `None`.
138
139 For example:
140
141 ```rust,ignore
142 /// Allows defining identifiers beyond ASCII.
143 (active, non_ascii_idents, "1.0.0", Some(55467), None),
144 ```
145
146 When added, the current version should be the one for the current nightly.
147 Once the feature is moved to `accepted.rs`, the version is changed to that nightly version.
148
149 4. Prevent usage of the new feature unless the feature gate is set.
150 You can check it in most places in the compiler using the
151 expression `tcx.features().$feature_name` (or
152 `sess.features_untracked().$feature_name` if the
153 tcx is unavailable)
154
155 If the feature gate is not set, you should either maintain
156 the pre-feature behavior or raise an error, depending on
157 what makes sense.
158
159 For features introducing new syntax, pre-expansion gating should be used instead.
160 To do so, extend the [`GatedSpans`] struct, add spans to it during parsing,
161 and then finally feature-gate all the spans in [`feature_gate::check::check_crate`].
162
163 5. Add a test to ensure the feature cannot be used without
164 a feature gate, by creating `feature-gate-$feature_name.rs`
165 and `feature-gate-$feature_name.stderr` files under the
166 directory where the other tests for your feature reside.
167
168 6. Add a section to the unstable book, in
169 `src/doc/unstable-book/src/language-features/$feature_name.md`.
170
171 7. Write a lots of tests for the new feature.
172 PRs without tests will not be accepted!
173
174 8. Get your PR reviewed and land it. You have now successfully
175 implemented a feature in Rust!
176
177 [`GatedSpans`]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/sess/struct.GatedSpans.html
178 [`feature_gate::check::check_crate`]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/feature_gate/check/fn.check_crate.html
179 [value the stability of Rust]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
180 [stability in code]: #stability-in-code
181 [here]: ./stabilization_guide.md
182 [tracking issue]: #tracking-issue