Note: Before we stabilize any feature, it's the rule that it
should appear in the documentation.
### Updating the feature-gate listing
There is a central listing of unstable feature-gates in
[`compiler/rustc_feature/src/unstable.rs`]. Search for the `declare_features!`
macro. There should be an entry for the feature you are aiming
to stabilize, something like (this example is taken from
[rust-lang/rust#32409]:
```rust,ignore
// pub(restricted) visibilities (RFC 1422)
(unstable, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
```
The above line should be moved to [`compiler/rustc_feature/src/accepted.rs`].
Entries in the `declare_features!` call are sorted, so find the correct place.
When it is done, it should look like:
```rust,ignore
// pub(restricted) visibilities (RFC 1422)
(accepted, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
// note that we changed this
```
(Even though you will encounter version numbers in the file of past changes,
you should not put the rustc version you expect your stabilization to happen in,
but instead `CURRENT_RUSTC_VERSION`)
### Removing existing uses of the feature-gate
Next search for the feature string (in this case, `pub_restricted`)
in the codebase to find where it appears. Change uses of
`#![feature(XXX)]` from the `std` and any rustc crates (this includes test folders
under `library/` and `compiler/` but not the toplevel `tests/` one) to be
`#![cfg_attr(bootstrap, feature(XXX))]`. This includes the feature-gate
only for stage0, which is built using the current beta (this is
needed because the feature is still unstable in the current beta).
Also, remove those strings from any tests (e.g. under `tests/`). If there are tests
specifically targeting the feature-gate (i.e., testing that the
feature-gate is required to use the feature, but nothing else),
simply remove the test.
### Do not require the feature-gate to use the feature
Most importantly, remove the code which flags an error if the
feature-gate is not present (since the feature is now considered
stable). If the feature can be detected because it employs some
new syntax, then a common place for that code to be is in the
same `compiler/rustc_ast_passes/src/feature_gate.rs`.
For example, you might see code like this:
```rust,ignore
gate_feature_post!(&self, pub_restricted, span,
"`pub(restricted)` syntax is experimental");
```
This `gate_feature_post!` macro prints an error if the
`pub_restricted` feature is not enabled. It is not needed
now that `#[pub_restricted]` is stable.
For more subtle features, you may find code like this:
```rust,ignore
if self.tcx.sess.features.borrow().pub_restricted { /* XXX */ }
```
This `pub_restricted` field (obviously named after the feature)
would ordinarily be false if the feature flag is not present
and true if it is. So transform the code to assume that the field
is true. In this case, that would mean removing the `if` and
leaving just the `/* XXX */`.
```rust,ignore
if self.tcx.sess.features.borrow().pub_restricted { /* XXX */ }
becomes
/* XXX */
if self.tcx.sess.features.borrow().pub_restricted && something { /* XXX */ }
becomes
if something { /* XXX */ }
```