Expand description
Support for nightly features in Cargo itself.
This file is the version of feature_gate.rs
in upstream Rust for Cargo
itself and is intended to be the avenue for which new features in Cargo are
gated by default and then eventually stabilized. All known stable and
unstable features are tracked in this file.
If you’re reading this then you’re likely interested in adding a feature to Cargo, and the good news is that it shouldn’t be too hard! First determine how the feature should be gated:
- New syntax in Cargo.toml should use
cargo-features
. - New CLI options should use
-Z unstable-options
. - New functionality that may not have an interface, or the interface has
not yet been designed, or for more complex features that affect multiple
parts of Cargo should use a new
-Z
flag.
See below for more details.
When adding new tests for your feature, usually the tests should go into a new module of the testsuite. See https://doc.crates.io/contrib/tests/writing.html for more information on writing tests. Particularly, check out the “Testing Nightly Features” section for testing unstable features.
After you have added your feature, be sure to update the unstable
documentation at src/doc/src/reference/unstable.md
to include a short
description of how to use your new feature.
And hopefully that’s it!
New Cargo.toml syntax
The steps for adding new Cargo.toml syntax are:
-
Add the cargo-features unstable gate. Search below for “look here” to find the
features!
macro invocation and add your feature to the list. -
Update the Cargo.toml parsing code to handle your new feature.
-
Wherever you added the new parsing code, call
features.require(Feature::my_feature_name())?
if the new syntax is used. This will return an error if the user hasn’t listed the feature incargo-features
or this is not the nightly channel.
-Z unstable-options
-Z unstable-options
is intended to force the user to opt-in to new CLI
flags, options, and new subcommands.
The steps to add a new command-line option are:
- Add the option to the CLI parsing code. In the help text, be sure to
include
(unstable)
to note that this is an unstable option. - Where the CLI option is loaded, be sure to call
CliUnstable::fail_if_stable_opt
. This will return an error if-Z unstable options
was not passed.
-Z
options
New -Z
options cover all other functionality that isn’t covered with
cargo-features
or -Z unstable-options
.
The steps to add a new -Z
option are:
- Add the option to the
CliUnstable
struct below. Flags can take an optional value if you want. - Update the
CliUnstable::add
function to parse the flag. - Wherever the new functionality is implemented, call
Config::cli_unstable
to get an instance ofCliUnstable
and check if the option has been enabled on theCliUnstable
instance. Nightly gating is already handled, so no need to worry about that.
-Z
vs cargo-features
In some cases there might be some changes that cargo-features
is unable
to sufficiently encompass. An example would be a syntax change in
Cargo.toml
that also impacts the index or resolver. The resolver doesn’t
know about cargo-features
, so it needs a -Z
flag to enable the
experimental functionality.
In those cases, you usually should introduce both a -Z
flag (to enable
the changes outside of the manifest) and a cargo-features
entry (to
enable the new syntax in Cargo.toml
). The cargo-features
entry ensures
that any experimental syntax that gets uploaded to crates.io is clearly
intended for nightly-only builds. Otherwise, users accessing those crates
may get confusing errors, particularly if the syntax changes during the
development cycle, and the user tries to access it with a stable release.
-Z
with external files
Some files, such as config.toml
config files, or the config.json
index
file, are used in a global location which can make interaction with stable
releases problematic. In general, before the feature is stabilized, stable
Cargo should behave roughly similar to how it behaved before the
unstable feature was introduced. If Cargo would normally have ignored or
warned about the introduction of something, then it probably should
continue to do so.
For example, Cargo generally ignores (or warns) about config.toml
entries it doesn’t know about. This allows a limited degree of
forwards-compatibility with future versions of Cargo that add new entries.
Whether or not to warn on stable may need to be decided on a case-by-case basis. For example, you may want to avoid generating a warning for options that are not critical to Cargo’s operation in order to reduce the annoyance of constant warnings. However, ignoring some options may prevent proper operation, so a warning may be valuable for a user trying to diagnose why it isn’t working correctly.
Stabilization
For the stabilization process, see https://doc.crates.io/contrib/process/unstable.html#stabilization.
The steps for stabilizing are roughly:
- Update the feature to be stable, based on the kind of feature:
cargo-features
: Change the feature tostable
in thefeatures!
macro invocation below, and include the version and a URL for the documentation.-Z unstable-options
: Find the call tofail_if_stable_opt
and remove it. Be sure to update the man pages if necessary.-Z
flag: Change the parsing code inCliUnstable::add
to callstabilized_warn
orstabilized_err
and remove the field fromCliUnstable
. Remove the(unstable)
note in the clap help text if necessary.- Remove
masquerade_as_nightly_cargo
from any tests, and removecargo-features
fromCargo.toml
test files if any. You can quickly find what needs to be removed by searching for the name of the feature, e.g.print_im_a_teapot
- Update the docs in unstable.md to move the section to the bottom and summarize it similar to the other entries. Update the rest of the documentation to add the new feature.
Macros
Structs
- A parsed representation of all unstable flags that Cargo accepts.
Enums
Constants
Functions
- Generate a link to Cargo documentation for the current release channel
path
is the URL component afterhttps://doc.rust-lang.org/{channel}/cargo/
- Only for testing and developing. See “Running with gitoxide as default git backend in tests”.
- Returns the current release channel (“stable”, “beta”, “nightly”, “dev”).