blob: 36dd56addb8fb10f9c0ee4381757fb7f7bf42ac2 [file] [edit]
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Implementing new language features - Rust Compiler Development Guide</title>
<!-- Custom HTML head -->
<meta name="description" content="A guide to developing the Rust compiler (rustc)">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon-de23e50b.svg">
<link rel="shortcut icon" href="favicon-8114d1fc.png">
<link rel="stylesheet" href="css/variables-8adf115d.css">
<link rel="stylesheet" href="css/general-2459343d.css">
<link rel="stylesheet" href="css/chrome-ae938929.css">
<link rel="stylesheet" href="css/print-9e4910d8.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="fonts/fonts-9644e21d.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="mdbook-highlight-css" href="highlight-493f70e1.css">
<link rel="stylesheet" id="mdbook-tomorrow-night-css" href="tomorrow-night-4c0ae647.css">
<link rel="stylesheet" id="mdbook-ayu-highlight-css" href="ayu-highlight-3fdfc3ac.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "";
const default_light_theme = "light";
const default_dark_theme = "navy";
window.path_to_searchindex_js = "searchindex-a3ca3873.js";
</script>
<!-- Start loading toc.js asap -->
<script src="toc-8a9b1d8d.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="mdbook-body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="mdbook-sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("mdbook-sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
sidebar_toggle.checked = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="mdbook-sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="toc.html"></iframe>
</noscript>
<div id="mdbook-sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="mdbook-page-wrapper" class="page-wrapper">
<div class="page">
<div id="mdbook-menu-bar-hover-placeholder"></div>
<div id="mdbook-menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></span>
</label>
<button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M371.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L600.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S549.7-4.4 531.1 9.6L294.4 187.2c-24 18-38.2 46.1-38.4 76.1L371.3 367.1zm-19.6 25.4l-116-104.4C175.9 290.3 128 339.6 128 400c0 3.9 .2 7.8 .6 11.6c1.8 17.5-10.2 36.4-27.8 36.4H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H240c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z"/></svg></span>
</button>
<ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li>
</ul>
<button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg></span>
</button>
</div>
<h1 class="menu-title">Rust Compiler Development Guide</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg></span>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide" title="Git repository" aria-label="Git repository">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg></span>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide/edit/main/src/implementing-new-features.md" title="Suggest an edit" aria-label="Suggest an edit" rel="edit">
<span class=fa-svg id="git-edit-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M421.7 220.3l-11.3 11.3-22.6 22.6-205 205c-6.6 6.6-14.8 11.5-23.8 14.1L30.8 511c-8.4 2.5-17.5 .2-23.7-6.1S-1.5 489.7 1 481.2L38.7 353.1c2.6-9 7.5-17.2 14.1-23.8l205-205 22.6-22.6 11.3-11.3 33.9 33.9 62.1 62.1 33.9 33.9zM96 353.9l-9.3 9.3c-.9 .9-1.6 2.1-2 3.4l-25.3 86 86-25.3c1.3-.4 2.5-1.1 3.4-2l9.3-9.3H112c-8.8 0-16-7.2-16-16V353.9zM453.3 19.3l39.4 39.4c25 25 25 65.5 0 90.5l-14.5 14.5-22.6 22.6-11.3 11.3-33.9-33.9-62.1-62.1L314.3 67.7l11.3-11.3 22.6-22.6 14.5-14.5c25-25 65.5-25 90.5 0z"/></svg></span>
</a>
</div>
</div>
<div id="mdbook-search-wrapper" class="hidden">
<form id="mdbook-searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<span class=fa-svg id="fa-spin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg></span>
</div>
</div>
</form>
<div id="mdbook-searchresults-outer" class="searchresults-outer hidden">
<div id="mdbook-searchresults-header" class="searchresults-header"></div>
<ul id="mdbook-searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="mdbook-content" class="content">
<main>
<h1 id="implementing-new-language-features"><a class="header" href="#implementing-new-language-features">Implementing new language features</a></h1>
<p>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.</p>
<p><strong>NOTE: This section is for <em>language</em> features, not <em>library</em> features,
which use <a href="./stability.html">a different process</a>.</strong></p>
<p>See also <a href="https://lang-team.rust-lang.org/how_to/propose.html">the Rust Language Design Team’s procedures</a> for proposing changes to the language.</p>
<h2 id="the-rfcbot-fcp-process"><a class="header" href="#the-rfcbot-fcp-process">The @rfcbot FCP process</a></h2>
<p>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.
However, if not, more must be done.
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).</p>
<p>For changes that need the consensus of a team,
we use the process of proposing a final comment period (FCP).
If you’re not on the relevant team (and thus don’t have @rfcbot permissions),
ask someone who is to start one;
unless they have a concern themselves, they should.</p>
<p>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+.
For example,
it is OK to add or modify unstable command-line flags
or attributes in the reserved compiler-internal <code>rustc_</code> 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.
Some teams have lighter weight processes that they use in scenarios like this;
for example,
the compiler team recommends filing a Major Change Proposal (<a href="https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp">MCP</a>)
as a lightweight way to garner support and feedback without requiring full consensus.</p>
<p>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.</p>
<p>When an FCP is proposed, it requires all members of the team to sign off on the FCP.
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.</p>
<h2 id="the-logistics-of-writing-features"><a class="header" href="#the-logistics-of-writing-features">The logistics of writing features</a></h2>
<p>There are a few “logistical” hoops you might need to go through
in order to implement a feature in a working way.</p>
<h3 id="warning-cycles"><a class="header" href="#warning-cycles">Warning Cycles</a></h3>
<p>In some cases, a feature or bugfix might break some existing programs in some edge cases.
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 <a href="diagnostics.html#edition-gated-lints">edition-gated lints</a>.</p>
<h3 id="stability"><a class="header" href="#stability">Stability</a></h3>
<p>We <a href="https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md">value the stability of Rust</a>.
Code that works and runs on stable should (mostly) not break.
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.</p>
<p>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.</p>
<p>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 (<code>#[feature(foo)]</code>),
which can’t be done in a stable/beta compiler.
See the <a href="#stability-in-code">stability in code</a> section for the technical details.</p>
<p>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 <a href="./stabilization-guide.html">here</a>.
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.
Features do not gain tenure by being unstable and unchanged for long periods of time.</p>
<h3 id="tracking-issues"><a class="header" href="#tracking-issues">Tracking Issues</a></h3>
<p>To keep track of the status of an unstable feature,
the experience we get while using it on nightly,
and of the concerns that block its stabilization,
every feature-gate needs a tracking issue.
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.</p>
<p>For features that are part of an accept RFC or approved lang experiment,
use the tracking issue for that.</p>
<p>For other features, create a tracking issue for that feature.
The issue title should be “Tracking issue for YOUR FEATURE”.
Use the <a href="https://github.com/rust-lang/rust/issues/new?template=tracking_issue.md">“Tracking Issue” issue template</a>.</p>
<h3 id="lang-experiments"><a class="header" href="#lang-experiments">Lang experiments</a></h3>
<p>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 <a href="https://lang-team.rust-lang.org/how_to/experiment.html">lang experiment</a>.</p>
<p>To propose a new lang experiment,
open an issue in <code>rust-lang/rust</code> that describes the motivation and the intended solution.
If it’s accepted, this issue will become the tracking issue for the experiment,
so use the tracking issue <a href="https://github.com/rust-lang/rust/issues/new?template=tracking_issue.md">template</a> while also including these other details.
Nominate the issue for the lang team and CC <code>@rust-lang/lang</code> and <code>@rust-lang/lang-advisors</code>.
When the experiment is approved, the tracking issue will be marked as <code>B-experimental</code>.</p>
<p>Feature flags related to a lang experiment must be marked as <code>incomplete</code>
until an RFC is accepted for the feature.</p>
<h2 id="stability-in-code"><a class="header" href="#stability-in-code">Stability in code</a></h2>
<p>The below steps needs to be followed in order to implement a new unstable feature:</p>
<ol>
<li>
<p>Open or identify the <a href="#tracking-issues">tracking issue</a>.
For features that are part of an accept RFC or approved lang experiment,
use the tracking issue for that.</p>
<p>Label the tracking issue with <code>C-tracking-issue</code> and the relevant <code>F-feature_name</code> label
(adding that label if needed).</p>
</li>
<li>
<p>Pick a name for the feature gate (for RFCs, use the name in the RFC).</p>
</li>
<li>
<p>Add the feature name to <code>rustc_span/src/symbol.rs</code> in the <code>Symbols {...}</code> block.</p>
<p>Note that this block must be in alphabetical order.</p>
</li>
<li>
<p>Add a feature gate declaration to <code>rustc_feature/src/unstable.rs</code>
in the unstable <code>declare_features</code> block.</p>
<pre><code class="language-rust ignore">/// description of feature
(unstable, $feature_name, "CURRENT_RUSTC_VERSION", Some($tracking_issue_number))</code></pre>
<p>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 <code>None</code> - but make sure to update it before the PR is merged!</p>
<p>For example:</p>
<pre><code class="language-rust ignore">/// Allows defining identifiers beyond ASCII.
(unstable, non_ascii_idents, "CURRENT_RUSTC_VERSION", Some(55467)),</code></pre>
<p>Features can be marked as incomplete,
and trigger the warn-by-default <a href="https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#incomplete-features"><code>incomplete_features</code> lint</a>
by setting their type to <code>incomplete</code>:</p>
<pre><code class="language-rust ignore">/// Allows deref patterns.
(incomplete, deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121)),</code></pre>
<p>Feature flags related to a lang experiment must be marked as <code>incomplete</code>
until an RFC is accepted for the feature.</p>
<p>To avoid <a href="https://bors.tech/essay/2017/02/02/pitch/">semantic merge conflicts</a>,
use <code>CURRENT_RUSTC_VERSION</code> instead of <code>1.70</code> or another explicit version number.</p>
</li>
<li>
<p>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 <code>tcx.features().$feature_name()</code>.</p>
<p>If the feature gate is not set,
you should either maintain the pre-feature behavior or raise an error,
depending on what makes sense.
Errors should generally use <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/errors/fn.feature_err.html"><code>rustc_session::errors::feature_err</code></a>.
For an example of adding an error, see <a href="https://github.com/rust-lang/rust/pull/81015">#81015</a>.</p>
<p>For features introducing new syntax, pre-expansion gating should be used instead.
During parsing, when the new syntax is parsed,
the symbol must be inserted to the current crate’s <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.GatedSpans.html"><code>GatedSpans</code></a>
via <code>self.psess.gated_spans.gate(sym::my_feature, span)</code>.</p>
<p>After being inserted to the gated spans,
the span must be checked in the <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_passes/feature_gate/fn.check_crate.html"><code>rustc_ast_passes::feature_gate::check_crate</code></a> function,
which actually denies features.
Exactly how it is gated depends on the exact type of feature,
but most likely will use the <code>gate_all!()</code> macro.</p>
</li>
<li>
<p>Add a test to ensure the feature cannot be used without a feature gate,
by creating <code>tests/ui/feature-gates/feature-gate-$feature_name.rs</code>.
You can generate the corresponding <code>.stderr</code> file
by running <code>./x test tests/ui/feature-gates/ --bless</code>.</p>
</li>
<li>
<p>Add a section to the unstable book,
in <code>src/doc/unstable-book/src/language-features/$feature_name.md</code>.</p>
</li>
<li>
<p>Write a lot of tests for the new feature, preferably in <code>tests/ui/$feature_name/</code>.
PRs without tests will not be accepted!</p>
</li>
<li>
<p>Get your PR reviewed and land it.
You have now successfully implemented a feature in Rust!</p>
</li>
</ol>
<h2 id="adding-unstable-compiler-flags"><a class="header" href="#adding-unstable-compiler-flags">Adding unstable compiler flags</a></h2>
<p>For compiler-internal experiments, diagnostics, debugging aids, and temporary implementation
controls, a <code>-Z</code> flag can be more appropriate than a language feature gate.
Feature gates should still be preferred for user-facing language features,
especially when crates need to opt in from source code.</p>
<p>Before adding a new flag, check the compiler team’s <a href="https://forge.rust-lang.org/compiler/proposals-and-stabilization.html?highlight=unstable%20flag#compiler-flags">guidance for compiler flags</a>.
Some flags, especially those intended for direct nightly user workflows or broader
ecosystem use, may need additional sign-off beyond an r+ on the implementation PR.</p>
<p>When adding a new <code>-Z</code> flag:</p>
<ol>
<li>
<p>Add the option to <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/options/struct.UnstableOptions.html"><code>UnstableOptions</code></a> in
<code>compiler/rustc_session/src/options.rs</code>.
The option name is written as snake_case in the struct and is exposed as
kebab-case on the command line.
Choose the parser, default value, and dependency tracking marker carefully.
Use <code>[UNTRACKED]</code> for flags that only affect diagnostics or debugging output,
and use <code>[TRACKED]</code> when changing the flag can change compilation results.</p>
</li>
<li>
<p>Update the option tests in <code>compiler/rustc_interface/src/tests.rs</code>.
<code>options.rs</code> also has a short checklist near the <code>UnstableOptions</code> list for
files that need to stay in sync.</p>
</li>
<li>
<p>Use the option through <code>sess.opts.unstable_opts.$flag_name</code> or
<code>tcx.sess.opts.unstable_opts.$flag_name</code>.
If bootstrap or rustdoc needs to pass the flag internally,
thread it through the relevant command construction code as part of the same
change.</p>
</li>
<li>
<p>Add focused tests for the behavior controlled by the flag.
For example, UI tests can use <code>//@ compile-flags: -Zyour-flag</code>,
while rustdoc behavior usually belongs in <code>tests/rustdoc</code>.</p>
</li>
<li>
<p>If the flag is meant for users of nightly rustc or rustdoc,
document it in the unstable book under <code>src/doc/unstable-book/src/compiler-flags</code>.</p>
</li>
</ol>
<p>Before opening the PR, run <code>./x test tidy</code> and the narrow test suite that exercises the new flag.</p>
<h2 id="call-for-testing"><a class="header" href="#call-for-testing">Call for testing</a></h2>
<p>Once the implementation is complete,
the feature will be available to nightly users but not yet part of stable Rust.
This is a good time to write a blog post on <a href="https://github.com/rust-lang/blog.rust-lang.org/">the main Rust blog</a>
and issue a “call for testing”.</p>
<p>Some earlier such blog posts include:</p>
<ol>
<li><a href="https://blog.rust-lang.org/2021/08/03/GATs-stabilization-push/">The push for GATs stabilization</a></li>
<li><a href="https://blog.rust-lang.org/2024/09/05/impl-trait-capture-rules.html">Changes to <code>impl Trait</code> in Rust 2024</a></li>
<li><a href="https://blog.rust-lang.org/inside-rust/2024/08/09/async-closures-call-for-testing/">Async Closures MVP: Call for Testing!</a></li>
</ol>
<p>Alternatively, <a href="https://github.com/rust-lang/this-week-in-rust"><em>This Week in Rust</em></a> has a <a href="https://this-week-in-rust.org/blog/2025/01/22/this-week-in-rust-583/#calls-for-testing">section</a> for this.
One example of this having been used is:</p>
<ul>
<li><a href="https://github.com/rust-lang/rust/issues/131204#issuecomment-2569314526">Call for testing on boolean literals as cfg predicates</a></li>
</ul>
<p>Which option to choose might depend on how significant the language change is,
though note that the <a href="https://github.com/rust-lang/this-week-in-rust"><em>This Week in Rust</em></a> section might be less visible
than a dedicated post on the main Rust blog.</p>
<h2 id="polishing"><a class="header" href="#polishing">Polishing</a></h2>
<p>Giving users a polished experience means more than just implementing the feature in rustc.
We need to think about all of the tools and resources that we ship.
This work includes:</p>
<ul>
<li>Documenting the language feature in the <a href="https://github.com/rust-lang/reference">Rust Reference</a>.</li>
<li>Extending <a href="https://github.com/rust-lang/rustfmt"><code>rustfmt</code></a> to format any new syntax (if applicable).</li>
<li>Extending <a href="https://github.com/rust-lang/rust-analyzer"><code>rust-analyzer</code></a> (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 <em>full</em> support.
<ul>
<li>When a language feature degrades the user experience
simply by existing before support is implemented in <a href="https://github.com/rust-lang/rust-analyzer"><code>rust-analyzer</code></a>,
that may lead the lang team to raise a blocking concern.</li>
<li>Examples of such might include new syntax that <a href="https://github.com/rust-lang/rust-analyzer"><code>rust-analyzer</code></a> can’t parse
or type inference changes it doesn’t understand when those lead to bogus diagnostics.</li>
</ul>
</li>
</ul>
<h2 id="stabilization"><a class="header" href="#stabilization">Stabilization</a></h2>
<p>The final step in the feature lifecycle is <a href="./stabilization-guide.html">stabilization</a>,
which is when the feature becomes available to all Rust users.
At this point,
backward incompatible changes are generally no longer permitted
(see the lang team’s <a href="https://rust-lang.github.io/rfcs/1122-language-semver.html">defined semver policies</a> for details).
To learn more about stabilization, see the <a href="./stabilization-guide.html">stabilization guide</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="walkthrough.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span>
</a>
<a rel="next prefetch" href="stability-guarantees.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="walkthrough.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span>
</a>
<a rel="next prefetch" href="stability-guarantees.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span>
</a>
</nav>
</div>
<template id=fa-eye><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></template>
<template id=fa-eye-slash><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg></span></template>
<template id=fa-copy><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg></span></template>
<template id=fa-play><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg></span></template>
<template id=fa-clock-rotate-left><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg></span></template>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr-ef4e11c1.min.js"></script>
<script src="mark-09e88c2c.min.js"></script>
<script src="searcher-c2a407aa.js"></script>
<script src="clipboard-1626706a.min.js"></script>
<script src="highlight-abc7f01d.js"></script>
<script src="book-a0b12cfe.js"></script>
<!-- Custom JS scripts -->
<script src="mermaid-cc85ecea.min.js"></script>
<script src="mermaid-init-4533fb11.js"></script>
</div>
</body>
</html>