<NME> stabilization_guide.md
<BEF> # Request for stabilization

**NOTE**: this page is about stabilizing language features.
For stabilizing *library* features, see [Stabilizing a library feature].

[Stabilizing a library feature]: ./stability.md#stabilizing-a-library-feature

Once an unstable feature has been well-tested with no outstanding
concern, anyone may push for its stabilization. It involves the
following steps:

<!-- toc -->

## Documentation PRs

<a name="updating-documentation"></a>

If any documentation for this feature exists, it should be
in the [`Unstable Book`], located at [`src/doc/unstable-book`].
If it exists, the page for the feature gate should be removed.

If there was documentation there, integrating it into the
existing documentation is needed.

If there wasn't documentation there, it needs to be added.

Places that may need updated documentation:

- [The Reference]: This must be updated, in full detail.
- [The Book]: This may or may not need updating, depends.
    If you're not sure, please open an issue on this repository
    and it can be discussed.
- standard library documentation: As needed. Language features
    often don't need this, but if it's a feature that changes
    how good examples are written, such as when `?` was added
    to the language, updating examples is important.
- [Rust by Example]: As needed.

Prepare PRs to update documentation involving this new feature
for repositories mentioned above. Maintainers of these repositories
will keep these PRs open until the whole stabilization process
has completed. Meanwhile, we can proceed to the next step.

## Write a stabilization report

Find the tracking issue of the feature, and create a short
stabilization report. Essentially this would be a brief summary
of the feature plus some links to test cases showing it works
as expected, along with a list of edge cases that came up
and were considered. This is a minimal "due diligence" that
we do before stabilizing.

The report should contain:

- A summary, showing examples (e.g. code snippets) what is
  enabled by this feature.
- Links to test cases in our test suite regarding this feature
  and describe the feature's behavior on encountering edge cases.
- Links to the documentations (the PRs we have made in the
  previous steps).
- Any other relevant information.
- The resolutions of any unresolved questions if the stabilization
  is for an RFC.

Examples of stabilization reports can be found in
[rust-lang/rust#44494][report1] and [rust-lang/rust#28237][report2] (these links
will bring you directly to the comment containing the stabilization report).

[report1]: https://github.com/rust-lang/rust/issues/44494#issuecomment-360191474
[report2]: https://github.com/rust-lang/rust/issues/28237#issuecomment-363374130

## FCP

If any member of the team responsible for tracking this
feature agrees with stabilizing this feature, they will
start the FCP (final-comment-period) process by commenting

```text
@rfcbot fcp merge
```

The rest of the team members will review the proposal. If the final
decision is to stabilize, we proceed to do the actual code modification.

## Stabilization PR

*This is for stabilizing language features.  If you are stabilizing a library
feature, see [the stabilization chapter of the std dev guide][std-guide-stabilization] instead.*

Once we have decided to stabilize a feature, we need to have
a PR that actually makes that stabilization happen. These kinds
of PRs are a great way to get involved in Rust, as they take
you on a little tour through the source code.

Here is a general guide to how to stabilize a feature --
every feature is different, of course, so some features may
require steps beyond what this guide talks about.

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 feature-gates in
[`compiler/rustc_feature`]. 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)
(active, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),
```

The above line should be moved down to the area for "accepted"
features, declared below in a separate call to `declare_features!`.
When it is done, it should look like:

```rust,ignore
// pub(restricted) visibilities (RFC 1422)

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 stdlib and rustc crates to be
`#![cfg_attr(stage0, 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).

### 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 `test/` 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. 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 */ }
```

[rust-lang/rust#32409]: https://github.com/rust-lang/rust/issues/32409
[std-guide-stabilization]: https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html
[src-version]: https://github.com/rust-lang/rust/blob/master/src/version
[forge-versions]: https://forge.rust-lang.org/#current-release-versions
[forge-release-process]: https://forge.rust-lang.org/release/process.html
[`compiler/rustc_feature`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_feature/index.html
[The Reference]: https://github.com/rust-lang/reference
[The Book]: https://github.com/rust-lang/book
[Rust by Example]: https://github.com/rust-lang/rust-by-example
[`Unstable Book`]: https://doc.rust-lang.org/unstable-book/index.html
[`src/doc/unstable-book`]: https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book

<MSG> Update src/stabilization_guide.md

Co-Authored-By: rajcspsg <0f979e55bdd315d07ba453cd849b326598b0589f@gmail.com>
<DFF> @@ -121,7 +121,7 @@ writing, the next stable release (i.e. what is currently beta) was
 
 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 stdlib and rustc crates to be
+`#![feature(XXX)]` from the `libstd` and any rustc crates to be
 `#![cfg_attr(stage0, 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).

{'commit': 'diff --git a/src/stabilization_guide.md b/src/stabilization_guide.md\nindex a17eff1..8940730 100644\n--- a/src/stabilization_guide.md\n+++ b/src/stabilization_guide.md\n@@ -121,7 +121,7 @@ writing, the next stable release (i.e. what is currently beta) was\n \n Next search for the feature string (in this case, `pub_restricted`)\n in the codebase to find where it appears. Change uses of\n-`#![feature(XXX)]` from the stdlib and rustc crates to be\n+`#![feature(XXX)]` from the `libstd` and any rustc crates to be\n `#![cfg_attr(stage0, feature(XXX))]`. This includes the feature-gate\n only for stage0, which is built using the current beta (this is\n needed because the feature is still unstable in the current beta).\n', 'commit_subject': 'Update src/stabilization_guide.md', 'repo_name': 'rust-lang/rustc-dev-guide', 'committer': {'name': 'Who? Me?!', 'email': 'c15a8b12f9f792dbc50834ec1cf7e22bcc3105c7@users.noreply.github.com', 'time_sec': '1547772962', 'tz_offset': '-360', 'date': {'seconds': '1547772962'}}, 'commit_tree': 'ce6f292147bdb46ce869c483c1dc39931c3d8fd1', 'commit_message': 'Update src/stabilization_guide.md\n\nCo-Authored-By: rajcspsg <0f979e55bdd315d07ba453cd849b326598b0589f@gmail.com>', 'language_name': 'Shell', 'license': 'apache-2.0', 'hunks': '@@ -121,7 +121,7 @@ writing, the next stable release (i.e. what is currently beta) was\n \n Next search for the feature string (in this case, `pub_restricted`)\n in the codebase to find where it appears. Change uses of\n-`#![feature(XXX)]` from the stdlib and rustc crates to be\n+`#![feature(XXX)]` from the `libstd` and any rustc crates to be\n `#![cfg_attr(stage0, feature(XXX))]`. This includes the feature-gate\n only for stage0, which is built using the current beta (this is\n needed because the feature is still unstable in the current beta).\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/src/stabilization_guide.md', 'tgt_file': 'b/src/stabilization_guide.md', 'file_extension': '.md', 'before_file': '# Request for stabilization\n\n**NOTE**: this page is about stabilizing language features.\nFor stabilizing *library* features, see [Stabilizing a library feature].\n\n[Stabilizing a library feature]: ./stability.md#stabilizing-a-library-feature\n\nOnce an unstable feature has been well-tested with no outstanding\nconcern, anyone may push for its stabilization. It involves the\nfollowing steps:\n\n<!-- toc -->\n\n## Documentation PRs\n\n<a name="updating-documentation"></a>\n\nIf any documentation for this feature exists, it should be\nin the [`Unstable Book`], located at [`src/doc/unstable-book`].\nIf it exists, the page for the feature gate should be removed.\n\nIf there was documentation there, integrating it into the\nexisting documentation is needed.\n\nIf there wasn\'t documentation there, it needs to be added.\n\nPlaces that may need updated documentation:\n\n- [The Reference]: This must be updated, in full detail.\n- [The Book]: This may or may not need updating, depends.\n    If you\'re not sure, please open an issue on this repository\n    and it can be discussed.\n- standard library documentation: As needed. Language features\n    often don\'t need this, but if it\'s a feature that changes\n    how good examples are written, such as when `?` was added\n    to the language, updating examples is important.\n- [Rust by Example]: As needed.\n\nPrepare PRs to update documentation involving this new feature\nfor repositories mentioned above. Maintainers of these repositories\nwill keep these PRs open until the whole stabilization process\nhas completed. Meanwhile, we can proceed to the next step.\n\n## Write a stabilization report\n\nFind the tracking issue of the feature, and create a short\nstabilization report. Essentially this would be a brief summary\nof the feature plus some links to test cases showing it works\nas expected, along with a list of edge cases that came up\nand were considered. This is a minimal "due diligence" that\nwe do before stabilizing.\n\nThe report should contain:\n\n- A summary, showing examples (e.g. code snippets) what is\n  enabled by this feature.\n- Links to test cases in our test suite regarding this feature\n  and describe the feature\'s behavior on encountering edge cases.\n- Links to the documentations (the PRs we have made in the\n  previous steps).\n- Any other relevant information.\n- The resolutions of any unresolved questions if the stabilization\n  is for an RFC.\n\nExamples of stabilization reports can be found in\n[rust-lang/rust#44494][report1] and [rust-lang/rust#28237][report2] (these links\nwill bring you directly to the comment containing the stabilization report).\n\n[report1]: https://github.com/rust-lang/rust/issues/44494#issuecomment-360191474\n[report2]: https://github.com/rust-lang/rust/issues/28237#issuecomment-363374130\n\n## FCP\n\nIf any member of the team responsible for tracking this\nfeature agrees with stabilizing this feature, they will\nstart the FCP (final-comment-period) process by commenting\n\n```text\n@rfcbot fcp merge\n```\n\nThe rest of the team members will review the proposal. If the final\ndecision is to stabilize, we proceed to do the actual code modification.\n\n## Stabilization PR\n\n*This is for stabilizing language features.  If you are stabilizing a library\nfeature, see [the stabilization chapter of the std dev guide][std-guide-stabilization] instead.*\n\nOnce we have decided to stabilize a feature, we need to have\na PR that actually makes that stabilization happen. These kinds\nof PRs are a great way to get involved in Rust, as they take\nyou on a little tour through the source code.\n\nHere is a general guide to how to stabilize a feature --\nevery feature is different, of course, so some features may\nrequire steps beyond what this guide talks about.\n\nNote: Before we stabilize any feature, it\'s the rule that it\nshould appear in the documentation.\n\n### Updating the feature-gate listing\n\nThere is a central listing of feature-gates in\n[`compiler/rustc_feature`]. Search for the `declare_features!`\nmacro. There should be an entry for the feature you are aiming\nto stabilize, something like (this example is taken from\n[rust-lang/rust#32409]:\n\n```rust,ignore\n// pub(restricted) visibilities (RFC 1422)\n(active, pub_restricted, "CURRENT_RUSTC_VERSION", Some(32409)),\n```\n\nThe above line should be moved down to the area for "accepted"\nfeatures, declared below in a separate call to `declare_features!`.\nWhen it is done, it should look like:\n\n```rust,ignore\n// pub(restricted) visibilities (RFC 1422)\n\nNext search for the feature string (in this case, `pub_restricted`)\nin the codebase to find where it appears. Change uses of\n`#![feature(XXX)]` from the stdlib and rustc crates to be\n`#![cfg_attr(stage0, feature(XXX))]`. This includes the feature-gate\nonly for stage0, which is built using the current beta (this is\nneeded because the feature is still unstable in the current beta).\n\n### Removing existing uses of the feature-gate\n\nNext search for the feature string (in this case, `pub_restricted`)\nin the codebase to find where it appears. Change uses of\n`#![feature(XXX)]` from the `std` and any rustc crates (this includes test folders\nunder `library/` and `compiler/` but not the toplevel `test/` one) to be\n`#![cfg_attr(bootstrap, feature(XXX))]`. This includes the feature-gate\nonly for stage0, which is built using the current beta (this is\nneeded because the feature is still unstable in the current beta).\n\nAlso, remove those strings from any tests. If there are tests\nspecifically targeting the feature-gate (i.e., testing that the\nfeature-gate is required to use the feature, but nothing else),\nsimply remove the test.\n\n### Do not require the feature-gate to use the feature\n\nMost importantly, remove the code which flags an error if the\nfeature-gate is not present (since the feature is now considered\nstable). If the feature can be detected because it employs some\nnew syntax, then a common place for that code to be is in the\nsame `compiler/rustc_ast_passes/src/feature_gate.rs`.\nFor example, you might see code like this:\n\n```rust,ignore\ngate_feature_post!(&self, pub_restricted, span,\n "`pub(restricted)` syntax is experimental");\n```\n\nThis `gate_feature_post!` macro prints an error if the\n`pub_restricted` feature is not enabled. It is not needed\nnow that `#[pub_restricted]` is stable.\n\nFor more subtle features, you may find code like this:\n\n```rust,ignore\nif self.tcx.sess.features.borrow().pub_restricted { /* XXX */ }\n```\n\nThis `pub_restricted` field (obviously named after the feature)\nwould ordinarily be false if the feature flag is not present\nand true if it is. So transform the code to assume that the field\nis true. In this case, that would mean removing the `if` and\nleaving just the `/* XXX */`.\n\n```rust,ignore\nif self.tcx.sess.features.borrow().pub_restricted { /* XXX */ }\nbecomes\n/* XXX */\n\nif self.tcx.sess.features.borrow().pub_restricted && something { /* XXX */ }\n becomes\nif something { /* XXX */ }\n```\n\n[rust-lang/rust#32409]: https://github.com/rust-lang/rust/issues/32409\n[std-guide-stabilization]: https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html\n[src-version]: https://github.com/rust-lang/rust/blob/master/src/version\n[forge-versions]: https://forge.rust-lang.org/#current-release-versions\n[forge-release-process]: https://forge.rust-lang.org/release/process.html\n[`compiler/rustc_feature`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_feature/index.html\n[The Reference]: https://github.com/rust-lang/reference\n[The Book]: https://github.com/rust-lang/book\n[Rust by Example]: https://github.com/rust-lang/rust-by-example\n[`Unstable Book`]: https://doc.rust-lang.org/unstable-book/index.html\n[`src/doc/unstable-book`]: https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book\n', 'message': 'Update src/stabilization_guide.md\n\nCo-Authored-By: rajcspsg <0f979e55bdd315d07ba453cd849b326598b0589f@gmail.com>', 'author_name': 'Who? Me?!', 'lang': 'md'}