Proposing a change to the language

Do you have an idea for a new language feature? The following page describes the lang team policy around changes to the language.

TL;DR

The highlights are these:

  • An RFC is required for most changes.
  • Small changes that fit in a PR, have narrow impact, and are uncontroversial can skip the RFC process (read more).
  • If you have a lang-team liaison and an experienced implementor, you can start experimenting by just adding a feature gate and a tracking issue, but you'll still need an RFC later.

Complete flowchart

The following lays out the complete flow chart for language features. Note that you can click on most of the nodes to read about that step in more detail.

flowchart TD

subgraph LangTeamChangeProcess [Lang Team Change Process]
TweakToExistingFeature["How large is your proposed change?"]
LangTeamLiaison["Are you an experienced contributor\nwith a lang team liaison?"]
NeedToExperiment["Do you need to experiment\nbefore you can write RFC?"]

subgraph Stages
    ExperimentalFeatureGateProposed["Create a tracking issue and\nopen a rust-lang/rust PR proposing\nan experimental feature gate"]
    ExperimentalFeatureGateAccepted["Experiment is approved. Write code!"]
    RFCOpen["Open a rust-lang/rfcs PR\nwith the completed RFC"]
    RFCAccepted["RFC is merged.\nIf needed, create a tracking issue,\n and finalize the implementation"]
    FeatureComplete["Implementation is complete.\nGain experience with the new feature."]
    StabilizationProposed["Author a stabilization report and\nopen a PR stabilizing the feature"]
    Documented["Author a rust-lang/reference PR\nextending the reference\nto describe the new feature."]
    StabilizationAccepted["Stabilization is approved!\nFeature rides the trains into stable."]
    ChangeProposed["Open a rust-lang/rust PR and\nnominate for lang team."]
    ChangeAccepted["PR is merged."]
    TypesTeamApproval["Types team approves the\ninteraction with type system."]
    StyleTeamNotified["Style team notified about the new feature."]
    
    ExperimentalFeatureGateProposed --Seconded--> ExperimentalFeatureGateAccepted
    ExperimentalFeatureGateAccepted --> RFCOpen
    RFCOpen --FCP--> RFCAccepted
    RFCAccepted --> FeatureComplete
    FeatureComplete --> StabilizationProposed
    %% StabilizationProposed --> StabilizationAccepted
    StabilizationProposed --do this--> Documented
    Documented --> StabilizationAccepted
    StabilizationProposed --and this--> TypesTeamApproval
    TypesTeamApproval --> StabilizationAccepted
    StabilizationProposed --and this--> StyleTeamNotified
    StyleTeamNotified --> StabilizationAccepted
    ChangeProposed --FCP proposed and accepted--> ChangeAccepted
    ChangeProposed -- If team feels change\nmerits a second RFC --> RFCOpen
end

TweakToExistingFeature -- Tweak to an existing aspect of Rust --> ChangeProposed
TweakToExistingFeature -- New feature or a complex change --> LangTeamLiaison
LangTeamLiaison -- Yes --> NeedToExperiment
LangTeamLiaison -- No --> RFCOpen
NeedToExperiment -- Yes --> ExperimentalFeatureGateProposed
NeedToExperiment -- No --> RFCOpen
end

%% Drawn from https://coolors.co/25283d-8f3985-a675a1-cea2ac-efd9ce
classDef pink fill:#EFD9CE
classDef tuscany fill:#CEA2AC
class LangTeamChangeProcess pink
class Stages tuscany

click RFCOpen href "https://github.com/rust-lang/rfcs/#when-you-need-to-follow-this-process" "Read about RFCs"
click RFCAccepted href "https://forge.rust-lang.org/lang/rfc-merge-procedure.html" "RFC merge procedure"
click ExperimentalFeatureGateProposed href "./experiment.html" "Read about experimental feature gates"
click ExperimentalFeatureGateAccepted href "./experiment.html" "Read about experimental feature gates"
click StabilizationProposed href "./stabilize.html" "Read about stabilization procedure"
click StabilizationAccepted href "./stabilize.html" "Read about stabilization procedure"
click Documented href "./stabilize.html" "Read about stabilization procedure"
click TypesTeamApproval href "./stabilize.html" "Read about stabilization procedure"
click StyleTeamNotified href "./stabilize.html" "Read about stabilization procedure"
click TweakToExistingFeature href "./propose.html#what-constitutes-a-small-addition-or-tweak-to-an-existing-feature"
click LangTeamLiaison "./experiment.html" "Read about experimental feature gates"
click NeedToExperiment "./experiment.html" "Read about experimental feature gates"

Frequently asked questions

What do the labels "lang-team second" and "lang-team consensus" mean?

These refer to our decision process:

  • A second means that some lang team member must liaison the idea, but it doesn't require full checkboxes. Instead, the idea goes immediately into "final comment period" (which lasts for 10 days), giving other lang team members a chance to comment on it and raise concerns. We use seconding for reversible decisions that don't commit the language to anything in particular.
  • A consensus means that every lang team member must check their box and actively approve.

In both cases, we currently handle consensus with rfcbot (@rfcbot fcp). For a second, however, the lang team member who initiatives FCP can go ahead and check the boxes of other lang-team members, they can raise concerns if needed. This is a temporary measure until we have first-class support for seconding.

Are RFCs required for every language change?

No! For small additions or tweaks to existing features, you can simply implement the change, open a PR, and nominate it for lang-team attention. If the change turns out to be complex or controversial, though, we may close the PR and request an RFC instead.

What constitutes a "small addition or tweak to an existing feature"?

We do not require an RFC for everything. Small changes that fit in a single PR, have narrow impact, and are uncontroversial can skip the RFC process. Simply make the change, open the PR, and nominate it for lang-team feedback. But be aware that we may still ask you to write an RFC! The rule of thumb is that we use RFCs for ideas that impact a lot of users or are potentially controversial. They're a great way to get broad feedback from the community about an idea.

If you choose to open a PR without an RFC, please document the motivation and details of your change! Very often people will open a PR that changes some code in the compiler without clearly explaining what they are trying to achieve. Also, please make the explanation "self sufficient" -- avoid linking to internals threads or other places where we have to read a bunch of context to understand what is going on (it's encouraged, however, to provide a summary and link to threads for more details).

Some examples where RFCs are typically NOT required...

  • Narrow changes like adding support for a new ABI (this may even just be a compiler concern).
  • Soundness fixes to existing features, unless they have large impact or change the way people have to write Rust, in which case we may opt for an RFC.
  • Small changes to complex rules, such as name resolution, intended to address a particular problem and which don't impact most users; often in cases like these RFCs do not provide valuable feedback, and so we'll instead focus on getting the relevant experts to weigh in. This category in particular still needs to have a detailed write-up.
  • Extending a lint to cover more instances of the same general pattern, or to be more precise.
  • Proposing a new lint that is narrow in scope.

What is the policy for adding a new lint?

We have a streamlined process for most lint proposals. See the How do I add a new lint? for details.

Do experiments always require an RFC?

In the diagram above, we show experiments as always leading to an RFC. This is typically the case because experiments tend to be for larger, more ambitious features. However, if the experiment turns out to be a relatively small change to the language -- i.e., some change that would not require an RFC anyway -- then you can skip the RFC and move straight to stabilization.

What about adding special traits and things to the standard library?

We consider intrinsics and "lang item" (things that need special treatment from the language) to be under the lang team purview. Specifically, the lang team governs the semantics and capabilities exposed by this new feature. The details of the API are governed by the libs-api team.

Whenever possible, though, we prefer to issue a quick approval for the "general feature" being discussed, and leave it to the libs-api team to decide where to apply it. For example, we approved the ability to add inherent methods to standard library types like u32 long ago, but the libs-api team governs what APIs are available.

My RFC has been waiting for a comment from the lang-team for a long time!

First off, I'm sorry, that sucks. We are aware that we need to do a better job keeping up with RFCs :/ (as long as it's tagged with T-lang, we'll know it exists). That said, what you can do is to nominate the RFC and we will discuss it during the meeting.