# Module cargo::core::features

source ·
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:

- Error when the feature is used without the gate
  - Required if ignoring the feature violates the users intent in non-superficial ways
  - A low-effort / safe way to protect the user from being broken if the format of the feature changes in incompatible was (can be worked around)
  - Good for: CLI (gate: `-Zunstable-options` or `-Z` if combined with other changes), `Cargo.toml` (gate: `cargo-features`)
- Warn that the feature is ignored due to lack of the gate
  - For if you could opt-in to the unimplemented feature on Cargo today and Cargo would operate just fine
  - If gate is not enabled, prefer to warn if the format of the feature is incompatible (instead of error or ignore)
  - Good for: `Cargo.toml`, `.cargo/config.toml`, `config.json` index file (gate: `-Z`)
- Ignore the feature that is used without a gate
  - For when ignoring the feature has so little impact that annoying the user is not worth it (e.g. a config field that changes Cargo’s terminal output)
  - For behavior changes without an interface (e.g. the resolver)
  - Good for: `.cargo/config.toml`, `config.json` index file (gate: `-Z`)

For features that touch multiple parts of Cargo, multiple feature gating strategies (error, warn, ignore) and mechanisms (`-Z`, `cargo-features`) may be used.

When adding new tests for your feature, usually the tests should go into a new module of the testsuite named after the feature. 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. Be sure to test the feature gate itself.

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!

### §`cargo-features`

The steps for adding new Cargo.toml syntax are:

1. Add the cargo-features unstable gate. Search the code below for “look here” to find the `features!` macro invocation and add your feature to the list.

2. Update the Cargo.toml parsing code to handle your new feature.

3. 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 in `cargo-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:

1. 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.
2. 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:

1. Add the option to the `CliUnstable` struct in the macro invocation of `unstable_cli_options!`. Flags can take an optional value if you want.
2. Update the `CliUnstable::add` function to parse the flag.
3. Wherever the new functionality is implemented, call `GlobalContext::cli_unstable` to get an instance of `CliUnstable` and check if the option has been enabled on the `CliUnstable` instance. Nightly gating is already handled, so no need to worry about that. If warning when feature is used without the gate, be sure to gracefully degrade (with a warning) when the `Cargo.toml` / `.cargo/config.toml` field usage doesn’t match the schema.
4. For any `Cargo.toml` fields, strip them in `prepare_for_publish` if the gate isn’t set

### §Stabilization

For the stabilization process, see https://doc.crates.io/contrib/process/unstable.html#stabilization.

The steps for stabilizing are roughly:

1. Update the feature to be stable, based on the kind of feature:
2. `cargo-features`: Change the feature to `stable` in the `features!` macro invocation below, and include the version and a URL for the documentation.
3. `-Z unstable-options`: Find the call to `fail_if_stable_opt` and remove it. Be sure to update the man pages if necessary.
4. `-Z` flag: Change the parsing code in `CliUnstable::add` to call `stabilized_warn` or `stabilized_err` and remove the field from `CliUnstable`. Remove the `(unstable)` note in the clap help text if necessary.
5. Remove `masquerade_as_nightly_cargo` from any tests, and remove `cargo-features` from `Cargo.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`
6. 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§

- features 🔒
  A listing of stable and unstable new syntax in Cargo.toml.
- stab 🔒
- unstable_cli_options 🔒
  Generates `-Z` flags as fields of `CliUnstable`.

## Structs§

- CliUnstable
  A parsed representation of all unstable flags that Cargo accepts.
- Feature
  Status and metadata for a single unstable feature.
- Features
  Unstable feature context for querying if a new Cargo.toml syntax is allowed to use.
- GitFeatures
- GitoxideFeatures

## Enums§

- Edition
  The edition of the compiler (RFC 2052)
- Status 🔒

## Constants§

- SEE_CHANNELS
- STABILISED_MULTITARGET 🔒
- STABILISED_NAMESPACED_FEATURES 🔒
- STABILISED_SPARSE_REGISTRY 🔒
- STABILIZED_CACHE_MESSAGES 🔒
- STABILIZED_CHECK_CFG 🔒
- STABILIZED_COMPILE_PROGRESS 🔒
- STABILIZED_CONFIGURABLE_ENV 🔒
- STABILIZED_CONFIG_PROFILE 🔒
- STABILIZED_CRATE_VERSIONS 🔒
- STABILIZED_CREDENTIAL_PROCESS 🔒
- STABILIZED_DOCTEST_IN_WORKSPACE 🔒
- STABILIZED_EXTRA_LINK_ARG 🔒
- STABILIZED_FEATURES 🔒
- STABILIZED_FUTURE_INCOMPAT_REPORT 🔒
- STABILIZED_INSTALL_UPGRADE 🔒
- STABILIZED_LINTS 🔒
- STABILIZED_NAMED_PROFILES 🔒
- STABILIZED_OFFLINE 🔒
- STABILIZED_PACKAGE_FEATURES 🔒
- STABILIZED_PATCH_IN_CONFIG 🔒
- STABILIZED_REGISTRY_AUTH 🔒
- STABILIZED_TERMINAL_WIDTH 🔒
- STABILIZED_TIMINGS 🔒
- STABILIZED_WEAK_DEP_FEATURES 🔒

## Functions§

- cargo_docs_link
  Generate a link to Cargo documentation for the current release channel `path` is the URL component after `https://doc.rust-lang.org/{channel}/cargo/`
- cargo_use_gitoxide_instead_of_git2 🔒
  Only for testing and developing. See “Running with gitoxide as default git backend in tests”.
- channel
  Returns the current release channel (“stable”, “beta”, “nightly”, “dev”).
- deserialize_build_std 🔒
- deserialize_git_features 🔒
- deserialize_gitoxide_features 🔒
- parse_git 🔒
- parse_gitoxide 🔒

## Type Aliases§

- AllowFeatures
  Value of [`allow-features`](CliUnstable::allow_features]