The Rust Unstable Book

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# The Unstable Book

Welcome to the Unstable Book! This book consists of a number of chapters, each one organized by a “feature flag.” That is, when using an unstable feature of Rust, you must use a flag, like this:

    #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]

    use std::ops::{Coroutine, CoroutineState};
    use std::pin::Pin;

    fn main() {
        let mut coroutine = #[coroutine] || {
            yield 1;
            return "foo"
        };

        match Pin::new(&mut coroutine).resume(()) {
            CoroutineState::Yielded(1) => {}
            _ => panic!("unexpected value from resume"),
        }
        match Pin::new(&mut coroutine).resume(()) {
            CoroutineState::Complete("foo") => {}
            _ => panic!("unexpected value from resume"),
        }
    }

The `coroutines` feature has a chapter describing how to use it.

Because this documentation relates to unstable features, we make no guarantees that what is contained here is accurate or up to date. It’s developed on a best-effort basis. Each page will have a link to its tracking issue with the latest developments; you might want to check those as well.

# Compiler environment variables

# `COLORTERM`

This environment variable is used by `-Zterminal-urls` to detect if URLs are supported by the terminal emulator.

# `QNX_TARGET`

This environment variable is mandatory when linking on `nto-qnx*_iosock` platforms. It is used to determine an `-L` path to pass to the QNX linker.

You should set this variable by running `source qnxsdp-env.sh`. See the QNX docs for more background information.

# `RUSTC_BLESS`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_BOOTSTRAP`

This feature is perma-unstable and has no tracking issue.

The `RUSTC_BOOTSTRAP` environment variable tells rustc to act as if it is a nightly compiler; in particular, it allows `#![feature(...)]` attributes and `-Z` flags even on the stable release channel.

Setting `RUSTC_BOOTSTRAP=1` instructs rustc to enable this for all crates. Setting `RUSTC_BOOTSTRAP=crate_name` instructs rustc to only apply this to crates named `crate_name`. Setting `RUSTC_BOOTSTRAP=-1` instructs rustc to act as if it is a stable compiler, even on the nightly release channel. Cargo disallows setting `cargo::rustc-env=RUSTC_BOOTSTRAP` in build scripts. Build systems can limit the features they enable with `-Z allow-features=feature1,feature2`. Crates can fully opt out of unstable features by using `#![forbid(unstable_features)]` at the crate root (or any other way of enabling lints, such as `-F unstable-features`).

## Why does this environment variable exist?

`RUSTC_BOOTSTRAP`, as the name suggests, is used for bootstrapping the compiler from an earlier version. In particular, nightly is built with beta, and beta is built with stable. Since the standard library and compiler both use unstable features, `RUSTC_BOOTSTRAP` is required so that we can use the previous version to build them.

## Why is this environment variable so easy to use for people not in the Rust project?

Originally, `RUSTC_BOOTSTRAP` required passing in a hash of the previous compiler version, to discourage using it for any purpose other than bootstrapping. That constraint was later relaxed; see https://github.com/rust-lang/rust/issues/36548 for the discussion that happened at that time.

People have at various times proposed re-adding the technical constraints. However, doing so is extremely disruptive for several major projects that we very much want to keep using the latest stable toolchain version, such as Firefox, Rust for Linux, and Chromium. We continue to allow `RUSTC_BOOTSTRAP` until we can come up with an alternative that does not disrupt our largest constituents.

## Stability policy

Despite being usable on stable, this is an unstable feature. Like any other unstable feature, we reserve the right to change or remove this feature in the future, as well as any other unstable feature that it enables. Using this feature opts you out of the normal stability/backwards compatibility guarantee of stable.

Although we do not take technical measures to prevent it from being used, we strongly discourage using this feature. If at all possible, please contribute to stabilizing the features you care about instead of bypassing the Rust project’s stability policy.

For library crates, we especially discourage the use of this feature. The crates depending on you do not know that you use this feature, have little recourse if it breaks, and can be used in contexts that are hard to predict.

For libraries that do use this feature, please document the versions you support (including a maximum as well as minimum version), and a mechanism to disable it. If you do not have a mechanism to disable the use of `RUSTC_BOOTSTRAP`, consider removing its use altogether, such that people can only use your library if they are already using a nightly toolchain. This leaves the choice of whether to opt-out of Rust’s stability guarantees up to the end user building their code.

## History

- Allowed without a hash (discussion)
- Extended to crate names (discussion)
- Disallowed for build scripts (discussion)
- Extended to emulate stable (discussion)

# `RUSTC_BREAK_ON_ICE`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_CTFE_BACKTRACE`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_FORCE_RUSTC_VERSION`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_GRAPHVIZ_FONT`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_ICE`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_LOG`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_OVERRIDE_VERSION_STRING`

This feature is perma-unstable and has no tracking issue.

The `RUSTC_OVERRIDE_VERSION_STRING` environment variable overrides the version reported by `rustc --version`. For example:

    $ rustc --version
    rustc 1.87.0-nightly (43f0014ef 2025-03-25)
    $ env RUSTC_OVERRIDE_VERSION_STRING=1.81.0-nightly rustc --version
    rustc 1.81.0-nightly

Note that the version string is completely overwritten; i.e. rustc discards commit hash and commit date information unless it is explicitly included in the environment variable. The string only applies to the “release” part of the version; for example:

    $ RUSTC_OVERRIDE_VERSION_STRING="1.81.0-nightly (aaaaaaaaa 2025-03-22)" rustc -vV
    rustc 1.81.0-nightly (aaaaaaaaa 2025-03-22)
    binary: rustc
    commit-hash: 43f0014ef0f242418674f49052ed39b70f73bc1c
    commit-date: 2025-03-25
    host: x86_64-unknown-linux-gnu
    release: 1.81.0-nightly (aaaaaaaaa 2025-03-22)
    LLVM version: 20.1.1

Note here that `commit-hash` and `commit-date` do not match the values in the string, and `release` includes the fake hash and date.

This variable has no effect on whether or not unstable features are allowed to be used. It only affects the output of `--version`.

## Why does this environment variable exist?

Various library crates have incomplete or incorrect feature detection. This environment variable allows bisecting crates that do incorrect detection with `version_check::supports_feature`.

This is not intended to be used for any other case (and, except for bisection, is not particularly useful).

See https://github.com/rust-lang/rust/pull/124339 for further discussion.

# `RUSTC_TRANSLATION_NO_DEBUG_ASSERT`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUSTC_WINDOWS_RC`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUST_BACKTRACE`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUST_DEP_GRAPH`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUST_DEP_GRAPH_FILTER`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUST_FORBID_DEP_GRAPH_EDGE`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUST_MIN_STACK`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `RUST_TARGET_PATH`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `SDKROOT`

This environment variable is used on Apple targets. It is passed through to the linker (currently either directly or via the `-syslibroot` flag).

Note that this variable is not always respected. When the SDKROOT is clearly wrong (e.g. when the platform of the SDK does not match the `--target` used by rustc), this is ignored and rustc does its own detection.

# `TERM`

This environment variable is used by `-Zterminal-urls` to detect if URLs are supported by the terminal emulator.

# `UNSTABLE_RUSTDOC_TEST_LINE`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# `UNSTABLE_RUSTDOC_TEST_PATH`

Environment variables have no tracking issue. This environment variable has no documentation, and therefore is likely internal to the compiler and not meant for general use.

See the code for more information.

# Compiler flags

# `allow-features`

This feature is perma-unstable and has no tracking issue.

This flag allows limiting the features which can be enabled with `#![feature(...)]` attributes. By default, all features are allowed on nightly and no features are allowed on stable or beta (but see `RUSTC_BOOTSTRAP`).

Features are comma-separated, for example `-Z allow-features=ffi_pure,f16`. If the flag is present, any feature listed will be allowed and any feature not listed will be disallowed. Any unrecognized feature is ignored.

# `annotate-moves`

The tracking issue for this feature is: #148197.

The `-Z annotate-moves` flag enables annotation of compiler-generated move and copy operations, making them visible in profilers and stack traces for performance debugging.

When enabled, the compiler manipulates debug info to make large move and copy operations appear as if they were inlined calls to `core::profiling::compiler_move` and `core::profiling::compiler_copy`. No actual function calls are generated - this is purely a debug info transformation that makes expensive memory operations visible in profilers and stack traces.

## Syntax

    rustc -Z annotate-moves[=<value>]

Where `<value>` can be:

- A boolean: `true`, `false`, `yes`, `no`, `on`, `off`
- A number: size threshold in bytes (e.g., `128`)
- Omitted: enables with default threshold (65 bytes)

## Options

- `-Z annotate-moves` or `-Z annotate-moves=true`: Enable with default size limit
- `-Z annotate-moves=false`: Disable annotation
- `-Z annotate-moves=N`: Enable with custom size limit of N bytes

## Examples

    # Enable annotation with default threshold (65 bytes)
    rustc -Z annotate-moves main.rs

    # Enable with custom 128-byte threshold
    rustc -Z annotate-moves=128 main.rs

    # Only annotate very large moves (1KB+)
    rustc -Z annotate-moves=1024 main.rs

    # Explicitly disable
    rustc -Z annotate-moves=false main.rs

## Behavior

The annotation only applies to:

- Types equal or larger than the specified size threshold
- Non-immediate types (those that would generate `memcpy`)
- Operations that actually move/copy data (not ZST types)

Stack traces will show the operations:

    0: memcpy
    1: core::profiling::compiler_move::<MyLargeStruct, 148>
    2: my_function

The `compiler_move` and `compiler_copy` functions have two generic parameters: the type being moved/copied and its size in bytes. The size is identical to `size_of::<T>()`, and is present just so that it’s easy to immediately tell how large the copy is.

Note that this requires v0 mangling to be properly encoded; legacy mangling does not substitute these with a specific type and size.

## Example

    #![allow(unused)]
    fn main() {
    #[derive(Clone)]
    struct LargeData {
        buffer: [u8; 1000],
    }

    fn example() {
        let data = LargeData { buffer: [0; 1000] };
        let copy = data.clone(); // Shows as compiler_copy in profiler
        let moved = data;        // Shows as compiler_move in profiler
    }
    }

## Overhead

This has no effect on generated code; it only adds debuginfo. The overhead is typically very small; on rustc itself, the default limit of 65 bytes adds about 0.055% to the binary size.

# `autodiff`

The tracking issue for this feature is: #124509.

This feature allows you to differentiate functions using automatic differentiation. Set the `-Zautodiff=<options>` compiler flag to adjust the behaviour of the autodiff feature. Multiple options can be separated with a comma.

## Syntax

    rustc -Z autodiff=Enable[,options]

Where `options` can be:

- `Enable` - Required flag to enable autodiff
- `PrintTA` - print Type Analysis Information
- `PrintTAFn=<fn_name>` - print Type Analysis Information for a specific function (consider combining it with `no_mangle`)
- `PrintAA` - print Activity Analysis Information
- `PrintPerf` - print Performance Warnings from Enzyme
- `PrintSteps` - prints all intermediate transformations
- `PrintModBefore` - print the whole module, before running opts
- `PrintModAfter` - print the module after Enzyme differentiated everything
- `LooseTypes` - Enzyme’s loose type debug helper (can cause incorrect gradients)
- `Inline` - runs Enzyme specific Inlining
- `RuntimeActivity` - allow specifying activity at runtime

## Examples

    # Enable autodiff via cargo, assuming `enzyme` being a toolchain that supports autodiff
    "RUSTFLAGS=-Zautodiff=Enable" cargo +enzyme build

    # Enable autodiff directly via rustc
    rustc -Z autodiff=Enable

    # Print TypeAnalysis updates for the function `foo`, as well as Activity Analysis for all differentiated code.
    rustc -Z autodiff=Enable,PrintTAFn=foo,PrintAA

# `branch-protection`

The tracking issue for this feature is: #113369.

This option lets you enable branch authentication instructions on AArch64. This option is only accepted when targeting AArch64 architectures. It takes some combination of the following values, separated by a `,`.

- `pac-ret` - Enable pointer authentication for non-leaf functions.
- `pc` - Use PC as a diversifier using PAuthLR instructions
- `leaf` - Enable pointer authentication for all functions, including leaf functions.
- `b-key` - Sign return addresses with key B, instead of the default key A.
- `bti` - Enable branch target identification.
- `gcs` - Enable guarded control stack support.

`leaf`, `b-key` and `pc` are only valid if `pac-ret` was previously specified. For example, `-Z branch-protection=bti,pac-ret,leaf` is valid, but `-Z branch-protection=bti,leaf,pac-ret` is not.

Rust’s standard library does not ship with BTI or pointer authentication enabled by default. In Cargo projects the standard library can be recompiled with pointer authentication using the nightly build-std feature.

# `cf-protection`

The tracking issue for this feature is: #93754.

This option enables control-flow enforcement technology (CET) on x86; a more detailed description of CET is available here. Similar to `clang`, this flag takes one of the following values:

- `none` - Disable CET completely (this is the default).
- `branch` - Enable indirect branch tracking (`IBT`).
- `return` - Enable shadow stack (`SHSTK`).
- `full` - Enable both `branch` and `return`.

This flag only applies to the LLVM backend: it sets the `cf-protection-branch` and `cf-protection-return` flags on LLVM modules. Note, however, that all compiled modules linked together must have the flags set for the compiled output to be CET-enabled. Currently, Rust’s standard library does not ship with CET enabled by default, so you may need to rebuild all standard modules with a `cargo` command like:

    $ RUSTFLAGS="-Z cf-protection=full" cargo +nightly build -Z build-std --target x86_64-unknown-linux-gnu

### Detection

An ELF binary is CET-enabled if it has the `IBT` and `SHSTK` tags, e.g.:

    $ readelf -a target/x86_64-unknown-linux-gnu/debug/example | grep feature:
          Properties: x86 feature: IBT, SHSTK

### Troubleshooting

To display modules that are not CET enabled, examine the linker errors available when `cet-report` is enabled:

    $ RUSTC_LOG=rustc_codegen_ssa::back::link=info rustc-custom -v -Z cf-protection=full -C link-arg="-Wl,-z,cet-report=warning" -o example example.rs
    ...
    /usr/bin/ld: /.../build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-d73f7266be14cb8b.rlib(std-d73f7266be14cb8b.std.f7443020-cgu.12.rcgu.o): warning: missing IBT and SHSTK properties

# `codegen-backend`

The tracking issue for this feature is: #77933.

This feature allows you to specify a path to a dynamic library to use as rustc’s code generation backend at runtime.

Set the `-Zcodegen-backend=<path>` compiler flag to specify the location of the backend. The library must be of crate type `dylib` and must contain a function named `__rustc_codegen_backend` with a signature of `fn() -> Box<dyn rustc_codegen_ssa::traits::CodegenBackend>`.

## Example

See also the `codegen-backend/hotplug` test for a working example.

    use rustc_codegen_ssa::traits::CodegenBackend;

    struct MyBackend;

    impl CodegenBackend for MyBackend {
       // Implement codegen methods
    }

    #[no_mangle]
    pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
        Box::new(MyBackend)
    }

# Unstable codegen options

All of these options are passed to `rustc` via the `-C` flag, short for “codegen”. The flags are stable but some of their values are individually unstable, and also require using `-Z unstable-options` to be accepted.

## linker-flavor

In addition to the stable set of linker flavors, the following unstable values also exist:

- `ptx`: use `rust-ptx-linker` for Nvidia NVPTX GPGPU support.
- `bpf`: use `bpf-linker` for eBPF support.
- `llbc`: for linking in llvm bitcode. Install the preview rustup components`llvm-bitcode-linker` and `llvm-tools` to use as a self-contained linker by passing `-Zunstable-options -Clink-self-contained=+linker` together with `-Clinker-flavor=llbc`. Can currently only be used for Nvidia NVPTX targets (`nvptx64-nvidia-cuda`).

Additionally, a set of more precise linker flavors also exists, for example allowing targets to declare that they use the LLD linker by default. The following values are currently unstable, and the goal is for them to become stable, and preferred in practice over the existing stable values:

- `gnu`: unix-like linker with GNU extensions
- `gnu-lld`: `gnu` using LLD
- `gnu-cc`: `gnu` using a C/C++ compiler as the linker driver
- `gnu-lld-cc`: `gnu` using LLD and a C/C++ compiler as the linker driver
- `darwin`: unix-like linker for Apple targets
- `darwin-lld`: `darwin` using LLD
- `darwin-cc`: `darwin` using a C/C++ compiler as the linker driver
- `darwin-lld-cc`: `darwin` using LLD and a C/C++ compiler as the linker driver
- `wasm-lld`: unix-like linker for Wasm targets, with LLD
- `wasm-lld-cc`: unix-like linker for Wasm targets, with LLD and a C/C++ compiler as the linker driver
- `unix`: basic unix-like linker for “any other Unix” targets (Solaris/illumos, L4Re, MSP430, etc), not supported with LLD.
- `unix-cc`: `unix` using a C/C++ compiler as the linker driver
- `msvc-lld`: MSVC-style linker for Windows and UEFI, with LLD
- `em-cc`: emscripten compiler frontend, similar to `wasm-lld-cc` with a different interface

## link-self-contained

This flag generally controls whether the linker will use libraries and objects shipped with Rust instead of those in the system. The stable boolean values for this flag are coarse-grained (everything or nothing), but there exists a set of unstable values with finer-grained control, `-Clink-self-contained` can accept a comma-separated list of components, individually enabled (`+component`) or disabled (`-component`):

- `crto`: CRT objects (e.g. on `windows-gnu`, `musl`, `wasi` targets)
- `libc`: libc static library (e.g. on `musl`, `wasi` targets)
- `unwind`: libgcc/libunwind (e.g. on `windows-gnu`, `fuchsia`, `fortanix`, `gnullvm` targets)
- `linker`: linker, dlltool, and their necessary libraries (e.g. on `windows-gnu` and for `rust-lld`)
- `sanitizers`: sanitizer runtime libraries
- `mingw`: other MinGW libs and Windows import libs

Out of the above self-contained linking components, `linker` is the only one currently implemented (beyond parsing the CLI options) and stabilized.

It refers to the LLD linker, built from the same LLVM revision used by rustc (named `rust-lld` to avoid naming conflicts), that is distributed via `rustup` with the compiler (and is used by default for the wasm targets). One can also opt into using it by combining this flag with the appropriate linker feature: for example, `-Clinker-features=+lld -Clink-self-contained=+linker` will use the toolchain’s `rust-lld` as the linker instead of the system’s lld with `-Clinker-features=+lld` only.

# `codegen-source-order`

This feature allows you to have a predictive and deterministic order for items after codegen, which is the same as in source code.

For every `CodegenUnit`, local `MonoItem`s would be sorted by `(Span, SymbolName)`, which makes codegen tests rely on the order of items in source files work.

# `control-flow-guard`

The tracking issue for this feature is: #68793.

The rustc flag `-Z control-flow-guard` enables the Windows Control Flow Guard (CFG) platform security feature.

CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported Windows platforms (Windows 8.1 onwards). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete.

During compilation, the compiler identifies all indirect calls/jumps and adds CFG checks. It also emits metadata containing the relative addresses of all address-taken functions. At runtime, if the binary is run on a CFG-aware operating system, the loader uses the CFG metadata to generate a bitmap of the address space and marks those addresses that contain valid targets. On each indirect call, the inserted check determines whether the target address is marked in this bitmap. If the target is not valid, the process is terminated.

In terms of interoperability:

- Code compiled with CFG enabled can be linked with libraries and object files that are not compiled with CFG. In this case, a CFG-aware linker can identify address-taken functions in the non-CFG libraries.
- Libraries compiled with CFG can linked into non-CFG programs. In this case, the CFG runtime checks in the libraries are not used (i.e. the mitigation is completely disabled).

CFG functionality is completely implemented in the LLVM backend and is supported for X86 (32-bit and 64-bit), ARM, and Aarch64 targets. The rustc flag adds the relevant LLVM module flags to enable the feature. This flag will be ignored for all non-Windows targets.

## When to use Control Flow Guard

The primary motivation for enabling CFG in Rust is to enhance security when linking against non-Rust code, especially C/C++ code. To achieve full CFG protection, all indirect calls (including any from Rust code) must have the appropriate CFG checks, as added by this flag. CFG can also improve security for Rust code that uses the `unsafe` keyword.

Another motivation behind CFG is to harden programs against return-oriented programming (ROP) attacks. CFG disallows an attacker from taking advantage of the program’s own instructions while redirecting control flow in unexpected ways.

## Overhead of Control Flow Guard

The CFG checks and metadata can potentially increase binary size and runtime overhead. The magnitude of any increase depends on the number and frequency of indirect calls. For example, enabling CFG for the Rust standard library increases binary size by approximately 0.14%. Enabling CFG in the SPEC CPU 2017 Integer Speed benchmark suite (compiled with Clang/LLVM) incurs approximate runtime overheads of between 0% and 8%, with a geometric mean of 2.9%.

## Testing Control Flow Guard

The rustc flag `-Z control-flow-guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement.

## Control Flow Guard in libraries

It is strongly recommended to also enable CFG checks for all linked libraries, including the standard library.

To enable CFG in the standard library, use the cargo `-Z build-std` functionality to recompile the standard library with the same configuration options as the main program.

For example:

    rustup toolchain install --force nightly
    rustup component add rust-src
    SET RUSTFLAGS=-Z control-flow-guard
    cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc

    rustup toolchain install --force nightly
    rustup component add rust-src
    $Env:RUSTFLAGS = "-Z control-flow-guard"
    cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc

Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the bootstrap.toml file.

# `coverage-options`

This option controls details of the coverage instrumentation performed by `-C instrument-coverage`.

Multiple options can be passed, separated by commas. Valid options are:

- `block`, `branch`, `condition`: Sets the level of coverage instrumentation. Setting the level will override any previously-specified level.
  - `block` (default): Blocks in the control-flow graph will be instrumented for coverage.
  - `branch`: In addition to block coverage, also enables branch coverage instrumentation.
  - `condition`: In addition to branch coverage, also instruments some boolean expressions as branches, even if they are not directly used as branch conditions.

# `crate-attr`

The tracking issue for this feature is: #138287.

The `-Z crate-attr` flag allows you to inject attributes into the crate root. For example, `-Z crate-attr=crate_name="test"` acts as if `#![crate_name="test"]` were present before the first source line of the crate root.

To inject multiple attributes, pass `-Z crate-attr` multiple times.

Formally, the expansion behaves as follows:

1. The crate is parsed as if `-Z crate-attr` were not present.
2. The attributes in `-Z crate-attr` are parsed.
3. The attributes are injected at the top of the crate root.
4. Macro expansion is performed.

# `debug-info-for-profiling`

## Introduction

Automatic Feedback Directed Optimization (AFDO) is a method for using sampling based profiles to guide optimizations. This is contrasted with other methods of FDO or profile-guided optimization (PGO) which use instrumented profiling.

Unlike PGO (controlled by the `rustc` flags `-Cprofile-generate` and `-Cprofile-use`), a binary being profiled does not perform significantly worse, and thus it’s possible to profile binaries used in real workflows and not necessary to construct artificial workflows.

## Use

In order to use AFDO, the target platform must be Linux running on an `x86_64` architecture with the performance profiler `perf` available. In addition, the external tool `create_llvm_prof` from this repository must be used.

Given a Rust file `main.rs`, we can produce an optimized binary as follows:

    rustc -O -Zdebug-info-for-profiling main.rs -o main
    perf record -b ./main
    create_llvm_prof --binary=main --out=code.prof
    rustc -O -Zprofile-sample-use=code.prof main.rs -o main2

The `perf` command produces a profile `perf.data`, which is then used by the `create_llvm_prof` command to create `code.prof`. This final profile is then used by `rustc` to guide optimizations in producing the binary `main2`.

# `debug-info-type-line-numbers`

This option causes additional type and line information to be emitted in debug info to provide richer information to debuggers. This is currently off by default as it causes some compilation scenarios to be noticeably slower.

# `default-visibility`

The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/131090

This flag can be used to override the target’s `default_visibility` setting.

This option only affects building of shared objects and should have no effect on executables.

Visibility an be set to one of three options:

- protected
- hidden
- interposable

## Hidden visibility

Using `-Zdefault-visibility=hidden` is roughly equivalent to Clang’s `-fvisibility=hidden` cmdline flag. Hidden symbols will not be exported from the created shared object, so cannot be referenced from other shared objects or from executables.

## Protected visibility

Using `-Zdefault-visibility=protected` will cause rust-mangled symbols to be emitted with “protected” visibility. This signals the compiler, the linker and the runtime linker that these symbols cannot be overridden by the executable or by other shared objects earlier in the load order.

This will allow the compiler to emit direct references to symbols, which may improve performance. It also removes the need for these symbols to be resolved when a shared object built with this option is loaded.

Using protected visibility when linking with GNU ld prior to 2.40 will result in linker errors when building for Linux. Other linkers such as LLD are not affected.

## Interposable

Using `-Zdefault-visibility=interposable` will cause symbols to be emitted with “default” visibility. On platforms that support it, this makes it so that symbols can be interposed, which means that they can be overridden by symbols with the same name from the executable or by other shared objects earier in the load order.

# `direct_access_external_data`

The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/707

Option `-Z direct-access-external-data` controls how to access symbols of external data.

Supported values for this option are:

- `yes` - Don’t use GOT indirection to reference external data symbols.
- `no` - Use GOT indirection to reference external data symbols.

If the option is not explicitly specified, different targets have different default values.

# `dump-mono-stats`

The `-Z dump-mono-stats` compiler flag generates a file with a list of the monomorphized items in the current crate. It is useful for investigating compile times.

It accepts an optional directory where the file will be located. If no directory is specified, the file will be placed in the current directory.

See also `-Z dump-mono-stats-format` and `-Z print-mono-items`. Unlike `print-mono-items`, `dump-mono-stats` aggregates monomorphized items by definition and includes a size estimate of how large the item is when codegened.

See https://rustc-dev-guide.rust-lang.org/backend/monomorph.html for an overview of monomorphized items.

# `dump-mono-stats-format`

The `-Z dump-mono-stats-format` compiler flag controls what file format to use for `-Z dump-mono-stats`. The default is markdown; currently JSON is also supported. JSON can be useful for programmatically manipulating the results (e.g. to find the item that took the longest to compile).

# dylib_lto

## `dylib-lto`

This option enables using LTO for the `dylib` crate type. This is currently only used for compiling `rustc` itself (more specifically, the `librustc_driver` dylib).

# `eagerly-emit-delayed-bugs`

This feature is perma-unstable and has no tracking issue.

This flag converts all `span_delayed_bug()` calls to `bug!` calls, exiting the compiler immediately and allowing you to generate a backtrace of where the delayed bug occurred. For full documentation, see the rustc-dev-guide.

# embed_metadata

## `embed-metadata`

This option instructs `rustc` to include the full metadata in `rlib` and `dylib` crate types. The default value is `yes` (enabled). If disabled (`no`), only stub metadata will be stored in these files, to reduce their size on disk. When using `-Zembed-metadata=no`, you will probably want to use `--emit=metadata` to produce the full metadata into a separate `.rmeta` file.

# `embed-source`

This flag controls whether the compiler embeds the program source code text into the object debug information section. It takes one of the following values:

- `y`, `yes`, `on` or `true`: put source code in debug info.
- `n`, `no`, `off`, `false` or no value: omit source code from debug info (the default).

This flag is ignored in configurations that don’t emit DWARF debug information and is ignored on non-LLVM backends. `-Z embed-source` requires DWARFv5. Use `-Z dwarf-version=5` to control the compiler’s DWARF target version and `-g` to enable debug info generation.

# `emit-stack-sizes`

The tracking issue for this feature is: #54192

The rustc flag `-Z emit-stack-sizes` makes LLVM emit stack size metadata.

> NOTE: This LLVM feature only supports the ELF object format as of LLVM 8.0. Using this flag with targets that use other object formats (e.g. macOS and Windows) will result in it being ignored.

Consider this crate:

    #![crate_type = "lib"]

    use std::ptr;

    pub fn foo() {
        // this function doesn't use the stack
    }

    pub fn bar() {
        let xs = [0u32; 2];

        // force LLVM to allocate `xs` on the stack
        unsafe { ptr::read_volatile(&xs.as_ptr()); }
    }

Using the `-Z emit-stack-sizes` flag produces extra linker sections in the output object file.

    $ rustc -C opt-level=3 --emit=obj foo.rs

    $ size -A foo.o
    foo.o  :
    section                                 size   addr
    .text                                      0      0
    .text._ZN3foo3foo17he211d7b4a3a0c16eE      1      0
    .text._ZN3foo3bar17h1acb594305f70c2eE     22      0
    .note.GNU-stack                            0      0
    .eh_frame                                 72      0
    Total                                     95

    $ rustc -C opt-level=3 --emit=obj -Z emit-stack-sizes foo.rs

    $ size -A foo.o
    foo.o  :
    section                                 size   addr
    .text                                      0      0
    .text._ZN3foo3foo17he211d7b4a3a0c16eE      1      0
    .stack_sizes                               9      0
    .text._ZN3foo3bar17h1acb594305f70c2eE     22      0
    .stack_sizes                               9      0
    .note.GNU-stack                            0      0
    .eh_frame                                 72      0
    Total                                    113

As of LLVM 7.0 the data will be written into a section named `.stack_sizes` and the format is “an array of pairs of function symbol values (pointer size) and stack sizes (unsigned LEB128)”.

    $ objdump -d foo.o

    foo.o:     file format elf64-x86-64

    Disassembly of section .text._ZN3foo3foo17he211d7b4a3a0c16eE:

    0000000000000000 <_ZN3foo3foo17he211d7b4a3a0c16eE>:
       0:   c3                      retq

    Disassembly of section .text._ZN3foo3bar17h1acb594305f70c2eE:

    0000000000000000 <_ZN3foo3bar17h1acb594305f70c2eE>:
       0:   48 83 ec 10             sub    $0x10,%rsp
       4:   48 8d 44 24 08          lea    0x8(%rsp),%rax
       9:   48 89 04 24             mov    %rax,(%rsp)
       d:   48 8b 04 24             mov    (%rsp),%rax
      11:   48 83 c4 10             add    $0x10,%rsp
      15:   c3                      retq

    $ objdump -s -j .stack_sizes foo.o

    foo.o:     file format elf64-x86-64

    Contents of section .stack_sizes:
     0000 00000000 00000000 00                 .........
    Contents of section .stack_sizes:
     0000 00000000 00000000 10                 .........

It’s important to note that linkers will discard this linker section by default. To preserve the section you can use a linker script like the one shown below.

    /* file: keep-stack-sizes.x */
    SECTIONS
    {
      /* `INFO` makes the section not allocatable so it won't be loaded into memory */
      .stack_sizes (INFO) :
      {
        KEEP(*(.stack_sizes));
      }
    }

The linker script must be passed to the linker using a rustc flag like `-C link-arg`.

    // file: src/main.rs
    use std::ptr;

    #[inline(never)]
    fn main() {
        let xs = [0u32; 2];

        // force LLVM to allocate `xs` on the stack
        unsafe { ptr::read_volatile(&xs.as_ptr()); }
    }

    $ RUSTFLAGS="-Z emit-stack-sizes" cargo build --release

    $ size -A target/release/hello | grep stack_sizes || echo section was not found
    section was not found

    $ RUSTFLAGS="-Z emit-stack-sizes" cargo rustc --release -- \
        -C link-arg=-Wl,-Tkeep-stack-sizes.x \
        -C link-arg=-N

    $ size -A target/release/hello | grep stack_sizes
    .stack_sizes                               90   176272

    $ # non-allocatable section (flags don't contain the "A" (alloc) flag)
    $ readelf -S target/release/hello
    Section Headers:
      [Nr]   Name              Type             Address           Offset
           Size              EntSize            Flags  Link  Info  Align
    (..)
      [1031] .stack_sizes      PROGBITS         000000000002b090  0002b0f0
           000000000000005a  0000000000000000   L       5     0     1

    $ objdump -s -j .stack_sizes target/release/hello

    target/release/hello:     file format elf64-x86-64

    Contents of section .stack_sizes:
     2b090 c0040000 00000000 08f00400 00000000  ................
     2b0a0 00080005 00000000 00000810 05000000  ................
     2b0b0 00000000 20050000 00000000 10400500  .... ........@..
     2b0c0 00000000 00087005 00000000 00000080  ......p.........
     2b0d0 05000000 00000000 90050000 00000000  ................
     2b0e0 00a00500 00000000 0000               ..........

> Author note: I’m not entirely sure why, in this case, `-N` is required in addition to `-Tkeep-stack-sizes.x`. For example, it’s not required when producing statically linked files for the ARM Cortex-M architecture.

# `emscripten-wasm-eh`

Use the WebAssembly exception handling ABI to unwind for the `wasm32-unknown-emscripten`. If compiling with this setting, the `emcc` linker should be invoked with `-fwasm-exceptions`. If linking with C/C++ files, the C/C++ files should also be compiled with `-fwasm-exceptions`.

# `env-set`

The tracking issue for this feature is: #118372.

This option flag allows to specify environment variables value at compile time to be used by `env!` and `option_env!` macros. It also impacts `tracked_env::var` function from the `proc_macro` crate.

This information will be stored in the dep-info files. For more information about dep-info files, take a look here.

When retrieving an environment variable value, the one specified by `--env-set` will take precedence. For example, if you want have `PATH=a` in your environment and pass:

    rustc --env-set PATH=env

Then you will have:

    #![allow(unused)]
    fn main() {
    assert_eq!(env!("PATH"), "env");
    }

It will trigger a new compilation if any of the `--env-set` argument value is different. So if you first passed:

    --env-set A=B --env X=12

and then on next compilation:

    --env-set A=B

`X` value is different (not set) so the code will be re-compiled.

Please note that on Windows, environment variables are case insensitive but case preserving whereas `rustc`’s environment variables are case sensitive. For example, having `Path` in your environment (case insensitive) is different than using `rustc --env-set Path=...` (case sensitive).

# `export-executable-symbols`

The tracking issue for this feature is: #84161.

The `-Zexport-executable-symbols` compiler flag makes `rustc` export symbols from executables. The resulting binary is runnable, but can also be used as a dynamic library. This is useful for interoperating with programs written in other languages, in particular languages with a runtime like Java or Lua.

For example on windows:

    #[no_mangle]
    fn my_function() -> usize {
        return 42;
    }

    fn main() {
        println!("Hello, world!");
    }

A standard `cargo build` will produce a `.exe` without an export directory. When the `export-executable-symbols` flag is added

    export RUSTFLAGS="-Zexport-executable-symbols"
    cargo build

the binary has an export directory with the functions:

    The Export Tables (interpreted .edata section contents)

    ...

    [Ordinal/Name Pointer] Table
        [   0] my_function
        [   1] main

(the output of `objdump -x` on the binary)

Please note that the `#[no_mangle]` attribute is required. Without it, the symbol is not exported.

The equivalent of this flag in C and C++ compilers is the `__declspec(dllexport)` annotation or the `-rdynamic` linker flag.

# `--extern` Options

- Tracking issue for `--extern` crate modifiers: #98405
- Tracking issue for `noprelude`: #98398
- Tracking issue for `priv`: #98399
- Tracking issue for `nounused`: #98400
- Tracking issue for `force`: #111302

The behavior of the `--extern` flag can be modified with `noprelude`, `priv` or `nounused` options.

This is unstable feature, so you have to provide `-Zunstable-options` to enable it.

## Examples

Use your own build of the `core` crate.

`rustc main.rs -Z unstable-options --extern noprelude:core=libcore.rlib`

To use multiple options, separate them with a comma:

`rustc main.rs -Z unstable-options --extern noprelude,priv,nounused:mydep=mydep.rlib`

## Options

- `noprelude`: Do not add the crate to the external prelude. If used, it will need to be imported using `extern crate`. This is used by the build-std project to simulate compatibility with sysroot-only crates.
- `priv`: Mark the crate as a private dependency for the `exported_private_dependencies` lint.
- `nounused`: Suppress `unused-crate-dependencies` warnings for the crate.
- `force`: Resolve the crate as if it is used, even if it is not used. This can be used to satisfy compilation session requirements like the presence of an allocator or panic handler.

# `external-clangrt`

This option controls whether the compiler links in its own runtime library for sanitizers. Passing this flag makes the compiler not link its own library. For more information, see the section in the sanitizers doc on working with other languages.

# `fixed-x18`

This option prevents the compiler from using the x18 register. It is only supported on `aarch64`.

From the ABI spec:

> X18 is the platform register and is reserved for the use of platform ABIs. This is an additional temporary register on platforms that don’t assign a special meaning to it.

This flag only has an effect when the x18 register would otherwise be considered a temporary register. When the flag is applied, x18 is always a reserved register.

This flag is intended for use with the shadow call stack sanitizer. Generally, when that sanitizer is enabled, the x18 register is used to store a pointer to the shadow stack. Enabling this flag prevents the compiler from overwriting the shadow stack pointer with temporary data, which is necessary for the sanitizer to work correctly.

Currently, the `-Zsanitizer=shadow-call-stack` flag is only supported on platforms that always treat x18 as a reserved register, and the `-Zfixed-x18` flag is not required to use the sanitizer on such platforms. However, the sanitizer may be supported on targets where this is not the case in the future. One way to do so now on Nightly compilers is to explicitly supply this `-Zfixed-x18` flag with `aarch64` targets, so that the sanitizer is available for instrumentation on targets like `aarch64-unknown-none`, for instance. However, discretion is still required to make sure that the runtime support is in place for this sanitizer to be effective.

It is undefined behavior for `-Zsanitizer=shadow-call-stack` code to call into code where x18 is a temporary register. On the other hand, when you are not using the shadow call stack sanitizer, compilation units compiled with and without the `-Zfixed-x18` flag are compatible with each other.

# `fmt-debug`

The tracking issue for this feature is: #129709.

Option `-Z fmt-debug=val` controls verbosity of derived `Debug` implementations and debug formatting in format strings (`{:?}`).

- `full` — `#[derive(Debug)]` prints types recursively. This is the default behavior.

- `shallow` — `#[derive(Debug)]` prints only the type name, or name of a variant of a fieldless enums. Details of the `Debug` implementation are not stable and may change in the future. Behavior of custom `fmt::Debug` implementations is not affected.

- `none` — `#[derive(Debug)]` does not print anything at all. `{:?}` in formatting strings has no effect. This option may reduce size of binaries, and remove occurrences of type names in the binary that are not removed by striping symbols. However, it may also cause `panic!` and `assert!` messages to be incomplete.

# `function-return`

The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/116853.

Option `-Zfunction-return` controls how function returns are converted.

It is equivalent to Clang’s and GCC’s `-mfunction-return`. The Linux kernel uses it for RETHUNK builds. For details, see LLVM commit 2240d72f15f3 (“[X86] initial -mfunction-return=thunk-extern support”) which introduces the feature.

Supported values for this option are:

- `keep`: do not convert function returns.
- `thunk-extern`: convert function returns (`ret`) to jumps (`jmp`) to an external symbol called `__x86_return_thunk`.

Like in Clang, GCC’s values `thunk` and `thunk-inline` are not supported.

Only x86 and non-large code models are supported.

# `hint-mostly-unused`

This flag hints to the compiler that most of the crate will probably go unused. The compiler can optimize its operation based on this assumption, in order to compile faster. This is a hint, and does not guarantee any particular behavior.

This option can substantially speed up compilation if applied to a large dependency where the majority of the dependency does not get used. This flag may slow down compilation in other cases.

Currently, this option makes the compiler defer as much code generation as possible from functions in the crate, until later crates invoke those functions. Functions that never get invoked will never have code generated for them. For instance, if a crate provides thousands of functions, but only a few of them will get called, this flag will result in the compiler only doing code generation for the called functions. (This uses the same mechanisms as cross-crate inlining of functions.) This does not affect `extern` functions, or functions marked as `#[inline(never)]`.

To try applying this flag to one dependency out of a dependency tree, use the `profile-rustflags` feature of nightly cargo:

    cargo-features = ["profile-rustflags"]

    # ...
    [dependencies]
    mostly-unused-dependency = "1.2.3"

    [profile.release.package.mostly-unused-dependency]
    rustflags = ["-Zhint-mostly-unused"]

# `indirect-branch-cs-prefix`

The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/116852.

Option `-Zindirect-branch-cs-prefix` controls whether a `cs` prefix is added to `call` and `jmp` to indirect thunks.

It is equivalent to Clang’s and GCC’s `-mindirect-branch-cs-prefix`. The Linux kernel uses it for RETPOLINE builds. For details, see LLVM commit 6f867f910283 (“[X86] Support `-mindirect-branch-cs-prefix` for call and jmp to indirect thunk”) which introduces the feature.

Only x86 and x86_64 are supported.

# `instrument-xray`

The tracking issue for this feature is: #102921.

Enable generation of NOP sleds for XRay function tracing instrumentation. For more information on XRay, read LLVM documentation, and/or the XRay whitepaper.

Set the `-Z instrument-xray` compiler flag in order to enable XRay instrumentation.

- `-Z instrument-xray` – use the default settings
- `-Z instrument-xray=skip-exit` – configure a custom setting
- `-Z instrument-xray=ignore-loops,instruction-threshold=300` – multiple settings separated by commas

Supported options:

- `always` – force instrumentation of all functions
- `never` – do no instrument any functions
- `ignore-loops` – ignore presence of loops, instrument functions based only on instruction count
- `instruction-threshold=10` – set a different instruction threshold for instrumentation
- `skip-entry` – do no instrument function entry
- `skip-exit` – do no instrument function exit

The default settings are:

- instrument both entry & exit from functions
- instrument functions with at least 200 instructions, or containing a non-trivial loop

Note that `-Z instrument-xray` only enables generation of NOP sleds which on their own don’t do anything useful. In order to actually trace the functions, you will need to link a separate runtime library of your choice, such as Clang’s XRay Runtime Library.

# `link-native-libraries`

This option allows ignoring libraries specified in `#[link]` attributes instead of passing them to the linker. This can be useful in build systems that manage native libraries themselves and pass them manually, e.g. with `-Clink-arg`.

- `yes` - Pass native libraries to the linker. Default.
- `no` - Don’t pass native libraries to the linker.

# `lint-llvm-ir`

This flag will add `LintPass` to the start of the pipeline. You can use it to check for common errors in the LLVM IR generated by `rustc`. You can add `-Cllvm-args=-lint-abort-on-error` to abort the process if errors were found.

# `llvm-module-flag`

This flag allows adding a key/value to the `!llvm.module.flags` metadata in the LLVM-IR for a compiled Rust module. The syntax is

`-Z llvm_module_flag=<name>:<type>:<value>:<behavior>`

Currently only u32 values are supported but the type is required to be specified for forward compatibility. The `behavior` element must match one of the named LLVM metadata behaviors

# `location-detail`

The tracking issue for this feature is: #70580.

Option `-Z location-detail=val` controls what location details are tracked when using `caller_location`. This allows users to control what location details are printed as part of panic messages, by allowing them to exclude any combination of filenames, line numbers, and column numbers. This option is intended to provide users with a way to mitigate the size impact of `#[track_caller]`.

This option supports a comma separated list of location details to be included. Valid options within this list are:

- `file` - the filename of the panic will be included in the panic output
- `line` - the source line of the panic will be included in the panic output
- `column` - the source column of the panic will be included in the panic output

Any combination of these three options are supported. Alternatively, you can pass `none` to this option, which results in no location details being tracked. If this option is not specified, all three are included by default.

An example of a panic output when using `-Z location-detail=line`:

    panicked at 'Process blink had a fault', <redacted>:323:0

The code size savings from this option are two-fold. First, the `&'static str` values for each path to a file containing a panic are removed from the binary. For projects with deep directory structures and many files with panics, this can add up. This category of savings can only be realized by excluding filenames from the panic output. Second, savings can be realized by allowing multiple panics to be fused into a single panicking branch. It is often the case that within a single file, multiple panics with the same panic message exist – e.g. two calls to `Option::unwrap()` in a single line, or two calls to `Result::expect()` on adjacent lines. If column and line information are included in the `Location` struct passed to the panic handler, these branches cannot be fused, as the output is different depending on which panic occurs. However if line and column information is identical for all panics, these branches can be fused, which can lead to substantial code size savings, especially for small embedded binaries with many panics.

The savings from this option are amplified when combined with the use of `-Zbuild-std`, as otherwise paths for panics within the standard library are still included in your binary.

# `macro-stats`

This feature is perma-unstable and has no tracking issue.

Some macros, especially procedural macros, can generate a surprising amount of code, which can slow down compile times. This is hard to detect because the generated code is normally invisible to the programmer.

This flag helps identify such cases. When enabled, the compiler measures the effect on code size of all used macros and prints a table summarizing that effect. For each distinct macro, it counts how many times it is used, and how much code it produces when expanded (in lines of code, and bytes of code). The code size evaluation uses the compiler’s internal pretty-printing, and so will be independent of the formatting in the original code.

Note that the output size of a macro may be zero. E.g. the `cfg!` and `#[test]` macros often strip out code.

If a macro is identified as causing a large increase in code size, it is worth using `cargo expand` to inspect the post-expansion code, which includes the code produced by all macros. It may be possible to optimize the macro to produce smaller code, or it may be possible to avoid using it altogether.

# `min-function-alignment`

The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/82232.

The `-Zmin-function-alignment=<align>` flag specifies the minimum alignment of functions for which code is generated. The `align` value must be a power of 2, other values are rejected.

Note that `-Zbuild-std` (or similar) is required to apply this minimum alignment to standard library functions. By default, these functions come precompiled and their alignments won’t respect the `min-function-alignment` flag.

This flag is equivalent to:

- `-fmin-function-alignment` for GCC
- `-falign-functions` for Clang

The specified alignment is a minimum. A higher alignment can be specified for specific functions by using the `align(...)` feature and annotating the function with a `#[align(<align>)]` attribute. The attribute’s value is ignored when it is lower than the value passed to `min-function-alignment`.

There are two additional edge cases for this flag:

- targets have a minimum alignment for functions (e.g. on x86_64 the lowest that LLVM generates is 16 bytes). A `min-function-alignment` value lower than the target’s minimum has no effect.
- the maximum alignment supported by rust (and LLVM) is `2^29`. Trying to set a higher value results in an error.

# `move_size_limit`

The `-Zmove-size-limit=N` compiler flag enables `large_assignments` lints which will warn when moving objects whose size exceeds `N` bytes.

Lint warns only about moves in functions that participate in code generation. Consequently it will be ineffective for compiler invocation that emit metadata only, i.e., `cargo check` like workflows.

# `no-parallel-llvm`

This flag disables parallelization of codegen and linking, while otherwise preserving behavior with regard to codegen units and LTO.

This flag is not useful for regular users, but it can be useful for debugging the backend. Codegen issues commonly only manifest under specific circumstances, e.g. if multiple codegen units are used and ThinLTO is enabled. Serialization of these threaded configurations makes the use of LLVM debugging facilities easier, by avoiding the interleaving of output.

# `no-steal-thir`

By default, to save on memory, the THIR body (obtained from the `tcx.thir_body` query) is stolen once no longer used. This is inconvenient for authors of rustc drivers who want to access the THIR.

This option disables the stealing. This has no observable effect on compiler behavior, only on memory usage.

# `no-unique-section-names`

This flag currently applies only to ELF-based targets using the LLVM codegen backend. It prevents the generation of unique ELF section names for each separate code and data item when `-Z function-sections` is also in use, which is the default for most targets. This option can reduce the size of object files, and depending on the linker, the final ELF binary as well.

For example, a function `func` will by default generate a code section called `.text.func`. Normally this is fine because the linker will merge all those `.text.*` sections into a single one in the binary. However, starting with LLVM 12, the backend will also generate unique section names for exception handling, so you would see a section name of `.gcc_except_table.func` in the object file and potentially in the final ELF binary, which could add significant bloat to programs that contain many functions.

This flag instructs LLVM to use the same `.text` and `.gcc_except_table` section name for each function, and it is analogous to Clang’s `-fno-unique-section-names` option.

# `offload`

The tracking issue for this feature is: #131513.

This feature will later allow you to run functions on GPUs. It is work in progress. Set the `-Zoffload=Enable` compiler flag to experiment with it.

# `on-broken-pipe`

The tracking issue for this feature is: #97889

Note: The ui for this feature was previously an attribute named `#[unix_sigpipe = "..."]`.

## Overview

The `-Zon-broken-pipe=...` compiler flag can be used to specify how libstd shall setup `SIGPIPE` on Unix platforms before invoking `fn main()`. This flag is ignored on non-Unix targets. The flag can be used with three different values or be omitted entirely. It affects `SIGPIPE` before `fn main()` and before children get `exec()`’ed:

Compiler flag | `SIGPIPE` before `fn main()` | `SIGPIPE` before child `exec()`
--- | --- | ---
not used | `SIG_IGN` | `SIG_DFL`
`-Zon-broken-pipe=kill` | `SIG_DFL` | not touched
`-Zon-broken-pipe=error` | `SIG_IGN` | not touched
`-Zon-broken-pipe=inherit` | not touched | not touched

## `-Zon-broken-pipe` not used

If `-Zon-broken-pipe` is not used, libstd will behave in the manner it has since 2014, before Rust 1.0. `SIGPIPE` will be set to `SIG_IGN` before `fn main()` and result in `EPIPE` errors which are converted to `std::io::ErrorKind::BrokenPipe`.

When spawning child processes, `SIGPIPE` will be set to `SIG_DFL` before doing the underlying `exec()` syscall.

## `-Zon-broken-pipe=kill`

Set the `SIGPIPE` handler to `SIG_DFL` before invoking `fn main()`. This will result in your program getting killed if it tries to write to a closed pipe. This is normally what you want if your program produces textual output.

When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_DFL` for `SIGPIPE`.

### Example

    fn main() {
        loop {
            println!("hello world");
        }
    }

    $ rustc -Zon-broken-pipe=kill main.rs
    $ ./main | head -n1
    hello world

## `-Zon-broken-pipe=error`

Set the `SIGPIPE` handler to `SIG_IGN` before invoking `fn main()`. This will result in `ErrorKind::BrokenPipe` errors if you program tries to write to a closed pipe. This is normally what you want if you for example write socket servers, socket clients, or pipe peers.

When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_IGN` for `SIGPIPE`.

### Example

    fn main() {
        loop {
            println!("hello world");
        }
    }

    $ rustc -Zon-broken-pipe=error main.rs
    $ ./main | head -n1
    hello world
    thread 'main' panicked at library/std/src/io/stdio.rs:1118:9:
    failed printing to stdout: Broken pipe (os error 32)
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

## `-Zon-broken-pipe=inherit`

Leave `SIGPIPE` untouched before entering `fn main()`. Unless the parent process has changed the default `SIGPIPE` handler from `SIG_DFL` to something else, this will behave the same as `-Zon-broken-pipe=kill`.

When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_DFL` for `SIGPIPE`.

# `patchable-function-entry`

The `-Z patchable-function-entry=total_nops,prefix_nops` or `-Z patchable-function-entry=total_nops` compiler flag enables nop padding of function entries with ‘total_nops’ nops, with an offset for the entry of the function at ‘prefix_nops’ nops. In the second form, ‘prefix_nops’ defaults to 0.

As an illustrative example, `-Z patchable-function-entry=3,2` would produce:

    nop
    nop
    function_label:
    nop
    //Actual function code begins here

This flag is used for hotpatching, especially in the Linux kernel. The flag arguments are modeled after the `-fpatchable-function-entry` flag as defined for both Clang and gcc and is intended to provide the same effect.

# `print=check-cfg`

The tracking issue for this feature is: #125704.

This option of the `--print` flag print the list of all the expected cfgs.

This is related to the `--check-cfg` flag which allows specifying arbitrary expected names and values.

This print option outputs compatible `--check-cfg` arguments with a reduced syntax where all the expected values are on the same line and `values(...)` is always explicit.

`--check-cfg` | `--print=check-cfg`
--- | ---
`cfg(foo)` | `cfg(foo, values(none()))
`cfg(foo, values("bar"))` | `cfg(foo, values("bar"))`
`cfg(foo, values(none(), "bar"))` | `cfg(foo, values(none(), "bar"))`
`cfg(foo, values(any())` | `cfg(foo, values(any())`
`cfg(foo, values())` | `cfg(foo, values())`
`cfg(any())` | `cfg(any())`
nothing | nothing

The print option includes well known cfgs.

To be used like this:

    rustc --print=check-cfg -Zunstable-options lib.rs

> Note: Users should be resilient when parsing, in particular against new predicates that may be added in the future.

# `print=crate-root-lint-levels`

The tracking issue for this feature is: #139180.

This option of the `--print` flag print the list of lints with print out all the lints and their associated levels (`allow`, `warn`, `deny`, `forbid`) based on the regular Rust rules at crate root, that is (roughly):

- command line args (`-W`, `-A`, `--force-warn`, `--cap-lints`, …)
- crate root attributes (`#![allow]`, `#![warn]`, `#[expect]`, …)
- the special `warnings` lint group
- the default lint level

The output format is `LINT_NAME=LINT_LEVEL`, e.g.:

    unknown_lint=warn
    arithmetic_overflow=deny

To be used like this:

    rustc --print=crate-root-lint-levels -Zunstable-options lib.rs

# `print=supported-crate-types`

The tracking issue for this feature is: #138640.

This option of the `--print` flag produces a list of crate types (delimited by newlines) supported for the given target.

The crate type strings correspond to the values accepted by the `--crate-type` flag.

Intended to be used like this:

    rustc --print=supported-crate-types -Zunstable-options --target=x86_64-unknown-linux-gnu

Example output for `x86_64-unknown-linux-gnu`:

    bin
    cdylib
    dylib
    lib
    proc-macro
    rlib
    staticlib

# `profile-sample-use`

`-Zprofile-sample-use=code.prof` directs `rustc` to use the profile `code.prof` as a source for Automatic Feedback Directed Optimization (AFDO). See the documentation of `-Zdebug-info-for-profiling` for more information on using AFDO.

# `randomize-layout`

The tracking issue for this feature is: #106764.

The `-Zrandomize-layout` flag changes the layout algorithm for `repr(Rust)` types defined in the current crate from its normal optimization goals to pseudorandomly rearranging fields within the degrees of freedom provided by the largely unspecified default representation. This also affects type sizes and padding. Downstream instantiations of generic types defined in a crate with randomization enabled will also be randomized.

It can be used to find unsafe code that accidentally relies on unspecified behavior.

Randomization is not guaranteed to use a different permutation for each compilation session. `-Zlayout-seed=<u64>` can be used to supply additional entropy.

Randomization only approximates the intended freedom of repr(Rust). Sometimes two distinct types may still consistently result in the same layout due to limitations of the current implementation. Randomization may become more aggressive over time as our coverage of the available degrees of freedoms improves. Corollary: Randomization is not a safety oracle. Two struct layouts being observably the same under different layout seeds on the current compiler version does not guarantee that future compiler versions won’t give them distinct layouts.

Randomization may also become less aggressive in the future if additional guarantees get added to the default layout.

# `reg-struct-return`

The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/116973.

Option -Zreg-struct-return causes the compiler to return small structs in registers instead of on the stack for extern “C”-like functions. It is UNSOUND to link together crates that use different values for this flag. It is only supported on `x86`.

It is equivalent to Clang’s and GCC’s `-freg-struct-return`.

# `regparm`

The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/131749.

Option -Zregparm=N causes the compiler to pass N arguments in registers EAX, EDX, and ECX instead of on the stack for “C”, “cdecl”, and “stdcall” fn. It is UNSOUND to link together crates that use different values for this flag. It is only supported on `x86`.

It is equivalent to Clang’s and GCC’s `-mregparm`.

Supported values for this option are 0-3.

Implementation details: For eligible arguments, llvm `inreg` attribute is set.

# `remap-cwd-prefix`

The tracking issue for this feature is: #87325.

This flag will rewrite absolute paths under the current working directory, replacing the current working directory prefix with a specified value.

The given value may be absolute or relative, or empty. This switch takes precedence over `--remap-path-prefix` in case they would both match a given path.

This flag helps to produce deterministic output, by removing the current working directory from build output, while allowing the command line to be universally reproducible, such that the same execution will work on all machines, regardless of build environment.

## Example

    # This would produce an absolute path to main.rs in build outputs of
    # "./main.rs".
    rustc -Z remap-cwd-prefix=. main.rs

# `remap-path-scope`

The tracking issue for this feature is: #111540.

When the `--remap-path-prefix` option is passed to rustc, source path prefixes in all output will be affected by default. The `--remap-path-scope` argument can be used in conjunction with `--remap-path-prefix` to determine paths in which output context should be affected. This flag accepts a comma-separated list of values and may be specified multiple times, in which case the scopes are aggregated together. The valid scopes are:

- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from
- `diagnostics` - apply remappings to printed compiler diagnostics
- `debuginfo` - apply remappings to debug information
- `coverage` - apply remappings to coverage information
- `object` - apply remappings to all paths in compiled executables or libraries, but not elsewhere. Currently an alias for `macro,debuginfo`.
- `all` - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`.

## Example

    # This would produce an absolute path to main.rs in build outputs of
    # "./main.rs".
    rustc --remap-path-prefix=$(PWD)=/remapped -Zremap-path-scope=object main.rs

# `report-time`

The tracking issue for this feature is: #64888

The `report-time` feature adds a possibility to report execution time of the tests generated via `libtest`.

This is unstable feature, so you have to provide `-Zunstable-options` to get this feature working.

Sample usage command:

    ./test_executable -Zunstable-options --report-time

Available options:

    --report-time
                    Show execution time of each test.
                    Threshold values for colorized output can be
                    configured via
                    `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
                    and
                    `RUST_TEST_TIME_DOCTEST` environment variables.
                    Expected format of environment variable is
                    `VARIABLE=WARN_TIME,CRITICAL_TIME`.
                    Not available for --format=terse
    --ensure-time
                    Treat excess of the test execution time limit as
                    error.
                    Threshold values for this option can be configured via
                    `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
                    and
                    `RUST_TEST_TIME_DOCTEST` environment variables.
                    Expected format of environment variable is
                    `VARIABLE=WARN_TIME,CRITICAL_TIME`.
                    `CRITICAL_TIME` here means the limit that should not be
                    exceeded by test.

Example of the environment variable format:

    RUST_TEST_TIME_UNIT=100,200

where 100 stands for warn time, and 200 stands for critical time.

## Examples

    cargo test --tests -- -Zunstable-options --report-time
        Finished dev [unoptimized + debuginfo] target(s) in 0.02s
         Running target/debug/deps/example-27fb188025bec02c

    running 3 tests
    test tests::unit_test_quick ... ok <0.000s>
    test tests::unit_test_warn ... ok <0.055s>
    test tests::unit_test_critical ... ok <0.110s>

    test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

         Running target/debug/deps/tests-cedb06f6526d15d9

    running 3 tests
    test unit_test_quick ... ok <0.000s>
    test unit_test_warn ... ok <0.550s>
    test unit_test_critical ... ok <1.100s>

    test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

# `sanitizer`

Sanitizers are tools that help detect and prevent various types of bugs and vulnerabilities in software. They are available in compilers and work by instrumenting the code to add additional runtime checks. While they provide powerful tools for identifying bugs or security issues, it’s important to note that using sanitizers can introduce runtime overhead and might not catch all possible issues. Therefore, they are typically used alongside other best practices in software development, such as testing and fuzzing, to ensure the highest level of software quality and security.

The tracking issues for this feature are:

- #39699.
- #89653.

This feature allows for use of one of following sanitizers:

- Those intended for testing or fuzzing (but not production use):

  - AddressSanitizer a fast memory error detector.
  - HWAddressSanitizer a memory error detector similar to AddressSanitizer, but based on partial hardware assistance.
  - LeakSanitizer a run-time memory leak detector.
  - MemorySanitizer a detector of uninitialized reads.
  - RealtimeSanitizer a detector of calls to function with non-deterministic execution time in realtime contexts.
  - ThreadSanitizer a fast data race detector.

- Those that apart from testing, may be used in production:

  - ControlFlowIntegrity LLVM Control Flow Integrity (CFI) provides forward-edge control flow protection.
  - DataFlowSanitizer a generic dynamic data flow analysis framework.
  - KernelControlFlowIntegrity LLVM Kernel Control Flow Integrity (KCFI) provides forward-edge control flow protection for operating systems kernels.
  - MemTagSanitizer fast memory error detector based on Armv8.5-A Memory Tagging Extension.
  - SafeStack provides backward-edge control flow protection by separating the stack into safe and unsafe regions.
  - ShadowCallStack provides backward-edge control flow protection (aarch64 only).

To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=cfi`, `-Zsanitizer=dataflow`,`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`, `-Zsanitizer=memory`, `-Zsanitizer=memtag`, `-Zsanitizer=realtime`, `-Zsanitizer=shadow-call-stack` or `-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags. If you’re working with other languages that are also instrumented with sanitizers, you might need the `external-clangrt` flag. See the section on working with other languages.

Example:

    $ RUSTFLAGS=-Zsanitizer=address cargo build -Zbuild-std --target x86_64-unknown-linux-gnu

Additional options for sanitizers can be passed to LLVM command line argument processor via LLVM arguments using `llvm-args` codegen option (e.g., `-Cllvm-args=-dfsan-combine-pointer-labels-on-load=false`). See the sanitizer documentation for more information about additional options.

# AddressSanitizer

AddressSanitizer is a memory error detector. It can detect the following types of bugs:

- Out of bound accesses to heap, stack and globals
- Use after free
- Use after return (runtime flag `ASAN_OPTIONS=detect_stack_use_after_return=1`)
- Use after scope
- Double-free, invalid free
- Memory leaks

The memory leak detection is enabled by default on Linux, and can be enabled with runtime flag `ASAN_OPTIONS=detect_leaks=1` on macOS.

AddressSanitizer is supported on the following targets:

- `aarch64-apple-darwin`
- `aarch64-unknown-fuchsia`
- `aarch64-unknown-linux-gnu`
- `x86_64-apple-darwin`
- `x86_64-unknown-fuchsia`
- `x86_64-unknown-freebsd`
- `x86_64-unknown-linux-gnu`

AddressSanitizer works with non-instrumented code although it will impede its ability to detect some bugs. It is not expected to produce false positive reports.

See the Clang AddressSanitizer documentation for more details.

## Examples

Stack buffer overflow:

    fn main() {
        let xs = [0, 1, 2, 3];
        let _y = unsafe { *xs.as_ptr().offset(4) };
    }

    $ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
    $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
    ==37882==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe400e6250 at pc 0x5609a841fb20 bp 0x7ffe400e6210 sp 0x7ffe400e6208
    READ of size 4 at 0x7ffe400e6250 thread T0
        #0 0x5609a841fb1f in example::main::h628ffc6626ed85b2 /.../src/main.rs:3:23
        ...

    Address 0x7ffe400e6250 is located in stack of thread T0 at offset 48 in frame
        #0 0x5609a841f8af in example::main::h628ffc6626ed85b2 /.../src/main.rs:1

      This frame has 1 object(s):
        [32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
    HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
          (longjmp and C++ exceptions *are* supported)
    SUMMARY: AddressSanitizer: stack-buffer-overflow /.../src/main.rs:3:23 in example::main::h628ffc6626ed85b2
    Shadow bytes around the buggy address:
      0x100048014bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x100048014c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x100048014c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x100048014c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x100048014c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    =>0x100048014c40: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
      0x100048014c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x100048014c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x100048014c70: f1 f1 f1 f1 00 00 f3 f3 00 00 00 00 00 00 00 00
      0x100048014c80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
      0x100048014c90: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
    Shadow byte legend (one shadow byte represents 8 application bytes):
      Addressable:           00
      Partially addressable: 01 02 03 04 05 06 07
      Heap left redzone:       fa
      Freed heap region:       fd
      Stack left redzone:      f1
      Stack mid redzone:       f2
      Stack right redzone:     f3
      Stack after return:      f5
      Stack use after scope:   f8
      Global redzone:          f9
      Global init order:       f6
      Poisoned by user:        f7
      Container overflow:      fc
      Array cookie:            ac
      Intra object redzone:    bb
      ASan internal:           fe
      Left alloca redzone:     ca
      Right alloca redzone:    cb
      Shadow gap:              cc
    ==37882==ABORTING

Use of a stack object after its scope has already ended:

    static mut P: *mut usize = std::ptr::null_mut();

    fn main() {
        unsafe {
            {
                let mut x = 0;
                P = &mut x;
            }
            std::ptr::write_volatile(P, 123);
        }
    }

    $ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
    $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
    =================================================================
    ==39249==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc7ed3e1a0 at pc 0x55c98b262a8e bp 0x7ffc7ed3e050 sp 0x7ffc7ed3e048
    WRITE of size 8 at 0x7ffc7ed3e1a0 thread T0
        #0 0x55c98b262a8d in core::ptr::write_volatile::he21f1df5a82f329a /.../src/rust/src/libcore/ptr/mod.rs:1048:5
        #1 0x55c98b262cd2 in example::main::h628ffc6626ed85b2 /.../src/main.rs:9:9
        ...

    Address 0x7ffc7ed3e1a0 is located in stack of thread T0 at offset 32 in frame
        #0 0x55c98b262bdf in example::main::h628ffc6626ed85b2 /.../src/main.rs:3

      This frame has 1 object(s):
        [32, 40) 'x' (line 6) <== Memory access at offset 32 is inside this variable
    HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
          (longjmp and C++ exceptions *are* supported)
    SUMMARY: AddressSanitizer: stack-use-after-scope /.../src/rust/src/libcore/ptr/mod.rs:1048:5 in core::ptr::write_volatile::he21f1df5a82f329a
    Shadow bytes around the buggy address:
      0x10000fd9fbe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x10000fd9fbf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x10000fd9fc00: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
      0x10000fd9fc10: f8 f8 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
      0x10000fd9fc20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    =>0x10000fd9fc30: f1 f1 f1 f1[f8]f3 f3 f3 00 00 00 00 00 00 00 00
      0x10000fd9fc40: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
      0x10000fd9fc50: 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
      0x10000fd9fc60: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3
      0x10000fd9fc70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x10000fd9fc80: 00 00 00 00 f1 f1 f1 f1 00 00 f3 f3 00 00 00 00
    Shadow byte legend (one shadow byte represents 8 application bytes):
      Addressable:           00
      Partially addressable: 01 02 03 04 05 06 07
      Heap left redzone:       fa
      Freed heap region:       fd
      Stack left redzone:      f1
      Stack mid redzone:       f2
      Stack right redzone:     f3
      Stack after return:      f5
      Stack use after scope:   f8
      Global redzone:          f9
      Global init order:       f6
      Poisoned by user:        f7
      Container overflow:      fc
      Array cookie:            ac
      Intra object redzone:    bb
      ASan internal:           fe
      Left alloca redzone:     ca
      Right alloca redzone:    cb
      Shadow gap:              cc
    ==39249==ABORTING

# ControlFlowIntegrity

The LLVM CFI support in the Rust compiler provides forward-edge control flow protection for both Rust-compiled code only and for C or C++ and Rust -compiled code mixed-language binaries, also known as “mixed binaries” (i.e., for when C or C++ and Rust -compiled code share the same virtual address space), by aggregating function pointers in groups identified by their return and parameter types.

LLVM CFI can be enabled with `-Zsanitizer=cfi` and requires LTO (i.e., `-Clinker-plugin-lto` or `-Clto`). Cross-language LLVM CFI can be enabled with `-Zsanitizer=cfi`, and requires the `-Zsanitizer-cfi-normalize-integers` option to be used with Clang `-fsanitize-cfi-icall-experimental-normalize-integers` option for cross-language LLVM CFI support, and proper (i.e., non-rustc) LTO (i.e., `-Clinker-plugin-lto`).

It is recommended to rebuild the standard library with CFI enabled by using the Cargo build-std feature (i.e., `-Zbuild-std`) when enabling CFI.

See the Clang ControlFlowIntegrity documentation for more details.

## Example 1: Redirecting control flow using an indirect branch/call to an invalid destination

    fn add_one(x: i32) -> i32 {
        x + 1
    }

    #[unsafe(naked)]
    #[cfg(all(target_os = "linux", target_arch = "x86_64"))]
    pub extern "sysv64" fn add_two(x: i32) {
        // x + 2 preceded by a landing pad/nop block
        std::arch::naked_asm!(
            "
             nop
             nop
             nop
             nop
             nop
             nop
             nop
             nop
             nop
             lea eax, [rdi+2]
             ret
            "
        );
    }

    fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
        f(arg) + f(arg)
    }

    fn main() {
        let answer = do_twice(add_one, 5);

        println!("The answer is: {}", answer);

      #[cfg(all(target_os = "linux", target_arch = "x86_64"))] {
            println!("With CFI enabled, you should not see the next answer");
            let f: fn(i32) -> i32 = unsafe {
                // Offset 0 is a valid branch/call destination (i.e., the function entry
                // point), but offsets 1-8 within the landing pad/nop block are invalid
                // branch/call destinations (i.e., within the body of the function).
                std::mem::transmute::<*const u8, fn(i32) -> i32>((add_two as *const u8).offset(5))
            };
            let next_answer = do_twice(f, 5);

            println!("The next answer is: {}", next_answer);
      }
    }

Fig. 1. Redirecting control flow using an indirect branch/call to an invalid destination (i.e., within the body of the function).

    $ cargo run --release
       Compiling rust-cfi-1 v0.1.0 (/home/rcvalle/rust-cfi-1)
        Finished release [optimized] target(s) in 0.42s
         Running `target/release/rust-cfi-1`
    The answer is: 12
    With CFI enabled, you should not see the next answer
    The next answer is: 14
    $

Fig. 2. Build and execution of Fig. 1 with LLVM CFI disabled.

    $ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi" cargo run -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu
       ...
       Compiling rust-cfi-1 v0.1.0 (/home/rcvalle/rust-cfi-1)
        Finished release [optimized] target(s) in 1m 08s
         Running `target/x86_64-unknown-linux-gnu/release/rust-cfi-1`
    The answer is: 12
    With CFI enabled, you should not see the next answer
    Illegal instruction
    $

Fig. 3. Build and execution of Fig. 1 with LLVM CFI enabled.

When LLVM CFI is enabled, if there are any attempts to change/hijack control flow using an indirect branch/call to an invalid destination, the execution is terminated (see Fig. 3).

## Example 2: Redirecting control flow using an indirect branch/call to a function with a different number of parameters

    use std::mem;

    fn add_one(x: i32) -> i32 {
        x + 1
    }

    fn add_two(x: i32, _y: i32) -> i32 {
        x + 2
    }

    fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
        f(arg) + f(arg)
    }

    fn main() {
        let answer = do_twice(add_one, 5);

        println!("The answer is: {}", answer);

        println!("With CFI enabled, you should not see the next answer");
        let f: fn(i32) -> i32 =
            unsafe { mem::transmute::<*const u8, fn(i32) -> i32>(add_two as *const u8) };
        let next_answer = do_twice(f, 5);

        println!("The next answer is: {}", next_answer);
    }

Fig. 4. Redirecting control flow using an indirect branch/call to a function with a different number of parameters than arguments intended/passed in the call/branch site.

    $ cargo run --release
       Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2)
        Finished release [optimized] target(s) in 0.43s
         Running `target/release/rust-cfi-2`
    The answer is: 12
    With CFI enabled, you should not see the next answer
    The next answer is: 14
    $

Fig. 5. Build and execution of Fig. 4 with LLVM CFI disabled.

    $ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi" cargo run -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu
       ...
       Compiling rust-cfi-2 v0.1.0 (/home/rcvalle/rust-cfi-2)
        Finished release [optimized] target(s) in 1m 08s
         Running `target/x86_64-unknown-linux-gnu/release/rust-cfi-2`
    The answer is: 12
    With CFI enabled, you should not see the next answer
    Illegal instruction
    $

Fig. 6. Build and execution of Fig. 4 with LLVM CFI enabled.

When LLVM CFI is enabled, if there are any attempts to change/hijack control flow using an indirect branch/call to a function with different number of parameters than arguments intended/passed in the call/branch site, the execution is also terminated (see Fig. 6).

## Example 3: Redirecting control flow using an indirect branch/call to a function with different return and parameter types

    use std::mem;

    fn add_one(x: i32) -> i32 {
        x + 1
    }

    fn add_two(x: i64) -> i64 {
        x + 2
    }

    fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
        f(arg) + f(arg)
    }

    fn main() {
        let answer = do_twice(add_one, 5);

        println!("The answer is: {}", answer);

        println!("With CFI enabled, you should not see the next answer");
        let f: fn(i32) -> i32 =
            unsafe { mem::transmute::<*const u8, fn(i32) -> i32>(add_two as *const u8) };
        let next_answer = do_twice(f, 5);

        println!("The next answer is: {}", next_answer);
    }

Fig. 7. Redirecting control flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed at the call/branch site.

    $ cargo run --release
       Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3)
        Finished release [optimized] target(s) in 0.44s
         Running `target/release/rust-cfi-3`
    The answer is: 12
    With CFI enabled, you should not see the next answer
    The next answer is: 14
    $

Fig. 8. Build and execution of Fig. 7 with LLVM CFI disabled.

    $ RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi" cargo run -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu
       ...
       Compiling rust-cfi-3 v0.1.0 (/home/rcvalle/rust-cfi-3)
        Finished release [optimized] target(s) in 1m 07s
         Running `target/x86_64-unknown-linux-gnu/release/rust-cfi-3`
    The answer is: 12
    With CFI enabled, you should not see the next answer
    Illegal instruction
    $

Fig. 9. Build and execution of Fig. 7 with LLVM CFI enabled.

When LLVM CFI is enabled, if there are any attempts to change/hijack control flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed in the call/branch site, the execution is also terminated (see Fig. 9).

## Example 4: Redirecting control flow using an indirect branch/call to a function with different return and parameter types across the FFI boundary

    int
    do_twice(int (*fn)(int), int arg)
    {
        return fn(arg) + fn(arg);
    }

Fig. 10. Example C library.

    use std::mem;

    #[link(name = "foo")]
    extern "C" {
        fn do_twice(f: unsafe extern "C" fn(i32) -> i32, arg: i32) -> i32;
    }

    unsafe extern "C" fn add_one(x: i32) -> i32 {
        x + 1
    }

    unsafe extern "C" fn add_two(x: i64) -> i64 {
        x + 2
    }

    fn main() {
        let answer = unsafe { do_twice(add_one, 5) };

        println!("The answer is: {}", answer);

        println!("With CFI enabled, you should not see the next answer");
        let f: unsafe extern "C" fn(i32) -> i32 = unsafe {
            mem::transmute::<*const u8, unsafe extern "C" fn(i32) -> i32>(add_two as *const u8)
        };
        let next_answer = unsafe { do_twice(f, 5) };

        println!("The next answer is: {}", next_answer);
    }

Fig. 11. Redirecting control flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed in the call/branch site, across the FFI boundary.

    $ make
    mkdir -p target/release
    clang -I. -Isrc -Wall -c src/foo.c -o target/release/libfoo.o
    llvm-ar rcs target/release/libfoo.a target/release/libfoo.o
    RUSTFLAGS="-L./target/release -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build --release
       Compiling rust-cfi-4 v0.1.0 (/home/rcvalle/rust-cfi-4)
        Finished release [optimized] target(s) in 0.49s
    $ ./target/release/rust-cfi-4
    The answer is: 12
    With CFI enabled, you should not see the next answer
    The next answer is: 14
    $

Fig. 12. Build and execution of Figs. 10–11 with LLVM CFI disabled.

    $ make
    mkdir -p target/release
    clang -I. -Isrc -Wall -flto -fsanitize=cfi -fsanitize-cfi-icall-experimental-normalize-integers -fvisibility=hidden -c -emit-llvm src/foo.c -o target/release/libfoo.bc
    llvm-ar rcs target/release/libfoo.a target/release/libfoo.bc
    RUSTFLAGS="-L./target/release -Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers" cargo build -Zbuild-std -Zbuild-std-features --release --target x86_64-unknown-linux-gnu
       ...
       Compiling rust-cfi-4 v0.1.0 (/home/rcvalle/rust-cfi-4)
        Finished release [optimized] target(s) in 1m 06s
    $ ./target/x86_64-unknown-linux-gnu/release/rust-cfi-4
    The answer is: 12
    With CFI enabled, you should not see the next answer
    Illegal instruction
    $

Fig. 13. Build and execution of FIgs. 10–11 with LLVM CFI enabled.

When LLVM CFI is enabled, if there are any attempts to redirect control flow using an indirect branch/call to a function with different return and parameter types than the return type expected and arguments intended/passed in the call/branch site, even across the FFI boundary and for extern “C” function types indirectly called (i.e., callbacks/function pointers) across the FFI boundary, the execution is also terminated (see Fig. 13).

# HWAddressSanitizer

HWAddressSanitizer is a newer variant of AddressSanitizer that consumes much less memory.

HWAddressSanitizer is supported on the following targets:

- `aarch64-linux-android`
- `aarch64-unknown-linux-gnu`

HWAddressSanitizer requires `tagged-globals` target feature to instrument globals. To enable this target feature compile with `-C target-feature=+tagged-globals`

See the Clang HWAddressSanitizer documentation for more details.

## Example

Heap buffer overflow:

    fn main() {
        let xs = vec![0, 1, 2, 3];
        let _y = unsafe { *xs.as_ptr().offset(4) };
    }

    $ rustc main.rs -Zsanitizer=hwaddress -C target-feature=+tagged-globals -C
    linker=aarch64-linux-gnu-gcc -C link-arg=-fuse-ld=lld --target
    aarch64-unknown-linux-gnu

    $ ./main
    ==241==ERROR: HWAddressSanitizer: tag-mismatch on address 0xefdeffff0050 at pc 0xaaaae0ae4a98
    READ of size 4 at 0xefdeffff0050 tags: 2c/00 (ptr/mem) in thread T0
        #0 0xaaaae0ae4a94  (/.../main+0x54a94)
        ...

    [0xefdeffff0040,0xefdeffff0060) is a small allocated heap chunk; size: 32 offset: 16
    0xefdeffff0050 is located 0 bytes to the right of 16-byte region [0xefdeffff0040,0xefdeffff0050)
    allocated here:
        #0 0xaaaae0acb80c  (/.../main+0x3b80c)
        ...

    Thread: T0 0xeffe00002000 stack: [0xffffc28ad000,0xffffc30ad000) sz: 8388608 tls: [0xffffaa10a020,0xffffaa10a7d0)
    Memory tags around the buggy address (one tag corresponds to 16 bytes):
      0xfefcefffef80: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffef90: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffefa0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffefb0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffefc0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffefd0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffefe0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefcefffeff0: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
    =>0xfefceffff000: d7  d7  05  00  2c [00] 00  00  00  00  00  00  00  00  00  00
      0xfefceffff010: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff020: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff030: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff040: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff050: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff060: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff070: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      0xfefceffff080: 00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
    Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
      0xfefcefffeff0: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
    =>0xfefceffff000: ..  ..  8c  ..  .. [..] ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
      0xfefceffff010: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
    See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags
    Registers where the failure occurred (pc 0xaaaae0ae4a98):
        x0  2c00efdeffff0050  x1  0000000000000004  x2  0000000000000004  x3  0000000000000000
        x4  0000fffefc30ac37  x5  000000000000005d  x6  00000ffffc30ac37  x7  0000efff00000000
        x8  2c00efdeffff0050  x9  0200efff00000000  x10 0000000000000000  x11 0200efff00000000
        x12 0200effe00000310  x13 0200effe00000310  x14 0000000000000008  x15 5d00ffffc30ac360
        x16 0000aaaae0ad062c  x17 0000000000000003  x18 0000000000000001  x19 0000ffffc30ac658
        x20 4e00ffffc30ac6e0  x21 0000aaaae0ac5e10  x22 0000000000000000  x23 0000000000000000
        x24 0000000000000000  x25 0000000000000000  x26 0000000000000000  x27 0000000000000000
        x28 0000000000000000  x29 0000ffffc30ac5a0  x30 0000aaaae0ae4a98
    SUMMARY: HWAddressSanitizer: tag-mismatch (/.../main+0x54a94)

# KernelControlFlowIntegrity

The LLVM Kernel Control Flow Integrity (CFI) support to the Rust compiler initially provides forward-edge control flow protection for operating systems kernels for Rust-compiled code only by aggregating function pointers in groups identified by their return and parameter types. (See LLVM commit cff5bef “KCFI sanitizer”.)

Forward-edge control flow protection for C or C++ and Rust -compiled code “mixed binaries” (i.e., for when C or C++ and Rust -compiled code share the same virtual address space) will be provided in later work by defining and using compatible type identifiers (see Type metadata in the design document in the tracking issue #89653).

LLVM KCFI can be enabled with `-Zsanitizer=kcfi`.

LLVM KCFI is supported on the following targets:

- `aarch64-linux-android`
- `aarch64-unknown-linux-gnu`
- `x86_64-linux-android`
- `x86_64-unknown-linux-gnu`

See the Clang KernelControlFlowIntegrity documentation for more details.

# DataFlowSanitizer

DataFlowSanitizer is a generalised dynamic data flow analysis.

Unlike other Sanitizer tools, this tool is not designed to detect a specific class of bugs on its own. Instead, it provides a generic dynamic data flow analysis framework to be used by clients to help detect application-specific issues within their own code.

DataFlowSanitizer is supported on the following targets:

- `x86_64-unknown-linux-gnu`

See the Clang DataFlowSanitizer documentation for more details.

# KernelAddressSanitizer

KernelAddressSanitizer (KASAN) is a freestanding version of AddressSanitizer which is suitable for detecting memory errors in programs which do not have a runtime environment, such as operating system kernels. KernelAddressSanitizer requires manual implementation of the underlying functions used for tracking KernelAddressSanitizer state.

KernelAddressSanitizer is supported on the following targets:

- `aarch64-unknown-none`
- `riscv64gc-unknown-none-elf`
- `riscv64imac-unknown-none-elf`
- `x86_64-unknown-none`

See the Linux Kernel’s KernelAddressSanitizer documentation for more details.

# LeakSanitizer

LeakSanitizer is run-time memory leak detector.

LeakSanitizer is supported on the following targets:

- `aarch64-unknown-linux-gnu`
- `x86_64-apple-darwin`
- `x86_64-unknown-linux-gnu`

See the Clang LeakSanitizer documentation for more details.

# MemorySanitizer

MemorySanitizer is detector of uninitialized reads.

MemorySanitizer is supported on the following targets:

- `aarch64-unknown-linux-gnu`
- `x86_64-unknown-freebsd`
- `x86_64-unknown-linux-gnu`

MemorySanitizer requires all program code to be instrumented. C/C++ dependencies need to be recompiled using Clang with `-fsanitize=memory` option. Failing to achieve that will result in false positive reports.

See the Clang MemorySanitizer documentation for more details.

## Example

Detecting the use of uninitialized memory. The `-Zbuild-std` flag rebuilds and instruments the standard library, and is strictly necessary for the correct operation of the tool. The `-Zsanitizer-memory-track-origins` enables tracking of the origins of uninitialized memory:

    use std::mem::MaybeUninit;

    fn main() {
        unsafe {
            let a = MaybeUninit::<[usize; 4]>::uninit();
            let a = a.assume_init();
            println!("{}", a[2]);
        }
    }

    $ export \
      RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins' \
      RUSTDOCFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins'
    $ cargo clean
    $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
    ==9416==WARNING: MemorySanitizer: use-of-uninitialized-value
        #0 0x560c04f7488a in core::fmt::num::imp::fmt_u64::haa293b0b098501ca $RUST/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/src/libcore/fmt/num.rs:202:16
    ...
      Uninitialized value was stored to memory at
        #0 0x560c04ae898a in __msan_memcpy.part.0 $RUST/src/llvm-project/compiler-rt/lib/msan/msan_interceptors.cc:1558:3
        #1 0x560c04b2bf88 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:6:16

      Uninitialized value was created by an allocation of 'a' in the stack frame of function '_ZN6memory4main17hd2333c1899d997f5E'
        #0 0x560c04b2bc50 in memory::main::hd2333c1899d997f5 $CWD/src/main.rs:3

# MemTagSanitizer

MemTagSanitizer detects a similar class of errors as AddressSanitizer and HardwareAddressSanitizer, but with lower overhead suitable for use as hardening for production binaries.

MemTagSanitizer is supported on the following targets:

- `aarch64-linux-android`
- `aarch64-unknown-linux-gnu`

MemTagSanitizer requires hardware support and the `mte` target feature. To enable this target feature compile with `-C target-feature="+mte"`.

See the LLVM MemTagSanitizer documentation for more details.

# SafeStack

SafeStack provides backward edge control flow protection by separating the stack into data which is only accessed safely (the safe stack) and all other data (the unsafe stack).

SafeStack can be enabled with the `-Zsanitizer=safestack` option and is supported on the following targets:

- `x86_64-unknown-linux-gnu`

See the Clang SafeStack documentation for more details.

# ShadowCallStack

ShadowCallStack provides backward edge control flow protection by storing a function’s return address in a separately allocated ‘shadow call stack’ and loading the return address from that shadow call stack. AArch64 and RISC-V both have a platform register defined in their ABIs, which is `x18` and `x3`/`gp` respectively, that can optionally be reserved for this purpose. Software support from the operating system and runtime may be required depending on the target platform which is detailed in the remaining section. See the Clang ShadowCallStack documentation for more details.

ShadowCallStack can be enabled with `-Zsanitizer=shadow-call-stack` option and is supported on the following targets:

## AArch64 family

ShadowCallStack requires the use of the ABI defined platform register, `x18`, which is required for code generation purposes. When `x18` is not reserved, and is instead used as a scratch register subsequently, enabling ShadowCallStack would lead to undefined behaviour due to corruption of return address or invalid memory access when the instrumentation restores return register to the link register `lr` from the already clobbered `x18` register. In other words, code that is calling into or called by functions instrumented with ShadowCallStack must reserve the `x18` register or preserve its value.

### `aarch64-linux-android` and `aarch64-unknown-fuchsia`/`aarch64-fuchsia`

This target already reserves the `x18` register. A runtime must be provided by the application or operating system. If `bionic` is used on this target, the software support is provided. Otherwise, a runtime needs to prepare a memory region and points `x18` to the region which serves as the shadow call stack.

### `aarch64-unknown-none`

In addition to support from a runtime by the application or operating system, the `-Zfixed-x18` flag is also mandatory.

## RISC-V 64 family

ShadowCallStack uses either the `gp` register for software shadow stack, also known as `x3`, or the `ssp` register if `Zicfiss` extension is available. `gp`/`x3` is currently always reserved and available for ShadowCallStack instrumentation, and `ssp` in case of `Zicfiss` is only accessible through its dedicated shadow stack instructions.

Support from the runtime and operating system is required when `gp`/`x3` is used for software shadow stack. A runtime must prepare a memory region and point `gp`/`x3` to the region before executing the code.

The following targets support ShadowCallStack.

- `riscv64imac-unknown-none-elf`
- `riscv64gc-unknown-none-elf`
- `riscv64gc-unknown-fuchsia`

# ThreadSanitizer

ThreadSanitizer is a data race detection tool. It is supported on the following targets:

- `aarch64-apple-darwin`
- `aarch64-unknown-linux-gnu`
- `x86_64-apple-darwin`
- `x86_64-unknown-freebsd`
- `x86_64-unknown-linux-gnu`

To work correctly ThreadSanitizer needs to be “aware” of all synchronization operations in a program. It generally achieves that through combination of library interception (for example synchronization performed through `pthread_mutex_lock` / `pthread_mutex_unlock`) and compile time instrumentation (e.g. atomic operations). Using it without instrumenting all the program code can lead to false positive reports.

ThreadSanitizer does not support atomic fences `std::sync::atomic::fence`, nor synchronization performed using inline assembly code.

See the Clang ThreadSanitizer documentation for more details.

## Example

    static mut A: usize = 0;

    fn main() {
        let t = std::thread::spawn(|| {
            unsafe { A += 1 };
        });
        unsafe { A += 1 };

        t.join().unwrap();
    }

    $ export RUSTFLAGS=-Zsanitizer=thread RUSTDOCFLAGS=-Zsanitizer=thread
    $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
    ==================
    WARNING: ThreadSanitizer: data race (pid=10574)
      Read of size 8 at 0x5632dfe3d030 by thread T1:
        #0 example::main::_$u7b$$u7b$closure$u7d$$u7d$::h23f64b0b2f8c9484 ../src/main.rs:5:18 (example+0x86cec)
        ...

      Previous write of size 8 at 0x5632dfe3d030 by main thread:
        #0 example::main::h628ffc6626ed85b2 /.../src/main.rs:7:14 (example+0x868c8)
        ...
        #11 main <null> (example+0x86a1a)

      Location is global 'example::A::h43ac149ddf992709' of size 8 at 0x5632dfe3d030 (example+0x000000bd9030)

# RealtimeSanitizer

RealtimeSanitizer detects non-deterministic execution time calls in real-time contexts. Functions marked with the `#[sanitize(realtime = "nonblocking")]` attribute are considered real-time functions. When RTSan detects a call to a function with a non-deterministic execution time, like `malloc` or `free` while in a real-time context, it reports an error.

Besides “nonblocking” the attribute can also be used with “blocking” and “caller”.

- “blocking” allows the programmer to mark their own functions as having a non-deterministic execution time. When reaching such a function while in a real-time context a violation will be reported. A typical use case is a userland spinlock.
- functions marked with “caller” will be sanitized if they were called from a real-time context. If no attribute is set, this is the default. Between entering a “nonblocking” function and exiting that function again the program will get sanitized.

The santizer checks can be disabled using the external functions `__rtsan_disable()` and `__rtsan_enable()`. Each call to `__rtsan_disable()` must be paired with one following call to `__rtsan_enable()`, otherwise the behaviour is undefined.

    #![allow(unused)]
    fn main() {
    unsafe extern "C" {
      fn __rtsan_disable();
      fn __rtsan_enable();
    }
    }

    // in a real-time context
    #[cfg(debug_assertions)]
    {
        unsafe { __rtsan_disable() };
        log!("logging xyz");
        unsafe { __rtsan_enable() };
    }

See the Clang RealtimeSanitizer documentation for more details.

## Example

    #![allow(unused)]
    #![feature(sanitize)]
    fn main() {
    #[sanitize(realtime = "nonblocking")]
    fn real_time() {
      let vec = vec![0, 1, 2]; // call to malloc is detected and reported as an error
    }
    }

    ==8670==ERROR: RealtimeSanitizer: unsafe-library-call
    Intercepted call to real-time unsafe function `malloc` in real-time context!
        #0 0x00010107b0d8 in malloc rtsan_interceptors_posix.cpp:792
        #1 0x000100d94e70 in alloc::alloc::Global::alloc_impl::h9e1fc3206c868eea+0xa0 (realtime_vec:arm64+0x100000e70)
        #2 0x000100d94d90 in alloc::alloc::exchange_malloc::hd45b5788339eb5c8+0x48 (realtime_vec:arm64+0x100000d90)
        #3 0x000100d95020 in realtime_vec::main::hea6bd69b03eb9ca1+0x24 (realtime_vec:arm64+0x100001020)
        #4 0x000100d94a28 in core::ops::function::FnOnce::call_once::h493b6cb9dd87d87c+0xc (realtime_vec:arm64+0x100000a28)
        #5 0x000100d949b8 in std::sys::backtrace::__rust_begin_short_backtrace::hfcddb06c73c19eea+0x8 (realtime_vec:arm64+0x1000009b8)
        #6 0x000100d9499c in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h202288c05a2064f0+0xc (realtime_vec:arm64+0x10000099c)
        #7 0x000100d9fa34 in std::rt::lang_start_internal::h6c763158a05ac05f+0x6c (realtime_vec:arm64+0x10000ba34)
        #8 0x000100d94980 in std::rt::lang_start::h1c29cc56df0598b4+0x38 (realtime_vec:arm64+0x100000980)
        #9 0x000100d95118 in main+0x20 (realtime_vec:arm64+0x100001118)
        #10 0x000183a46b94 in start+0x17b8 (dyld:arm64+0xfffffffffff3ab94)

    SUMMARY: RealtimeSanitizer: unsafe-library-call rtsan_interceptors_posix.cpp:792 in malloc

# Instrumentation of external dependencies and std

The sanitizers to varying degrees work correctly with partially instrumented code. On the one extreme is LeakSanitizer that doesn’t use any compile time instrumentation, on the other is MemorySanitizer that requires that all program code to be instrumented (failing to achieve that will inevitably result in false positives).

It is strongly recommended to combine sanitizers with recompiled and instrumented standard library, for example using cargo `-Zbuild-std` functionality.

# Working with other languages

Sanitizers rely on compiler runtime libraries to function properly. Rust links in its own compiler runtime which might conflict with runtimes required by languages such as C++. Since Rust’s runtime doesn’t always contain the symbols required by C++ instrumented code, you might need to skip linking it so another runtime can be linked instead.

A separate unstable option `-Zexternal-clangrt` can be used to make rustc skip linking the compiler runtime for the sanitizer. This will require you to link in an external runtime, such as from clang instead.

# Build scripts and procedural macros

Use of sanitizers together with build scripts and procedural macros is technically possible, but in almost all cases it would be best avoided. This is especially true for procedural macros which would require an instrumented version of rustc.

In more practical terms when using cargo always remember to pass `--target` flag, so that rustflags will not be applied to build scripts and procedural macros.

# Symbolizing the Reports

Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PATH`.

# Additional Information

- Sanitizers project page
- AddressSanitizer in Clang
- ControlFlowIntegrity in Clang
- DataFlowSanitizer in Clang
- HWAddressSanitizer in Clang
- Linux Kernel’s KernelAddressSanitizer documentation
- LeakSanitizer in Clang
- MemorySanitizer in Clang
- MemTagSanitizer in LLVM
- ThreadSanitizer in Clang
- RealtimeSanitizer in Clang

# `self-profile`

The `-Zself-profile` compiler flag enables rustc’s internal profiler. When enabled, the compiler will output three binary files in the specified directory (or the current working directory if no directory is specified). These files can be analyzed by using the tools in the `measureme` repository.

To control the data recorded in the trace files, use the `-Zself-profile-events` flag.

For example:

First, run a compilation session and provide the `-Zself-profile` flag:

    $ rustc --crate-name foo -Zself-profile

This will generate three files in the working directory such as:

- `foo-1234.events`
- `foo-1234.string_data`
- `foo-1234.string_index`

Where `foo` is the name of the crate and `1234` is the process id of the rustc process.

To get a summary of where the compiler is spending its time:

    $ ../measureme/target/release/summarize summarize foo-1234

To generate a flamegraph of the same data:

    $ ../measureme/target/release/inferno foo-1234

To dump the event data in a Chromium-profiler compatible format:

    $ ../measureme/target/release/crox foo-1234

For more information, consult the `measureme` documentation.

# `self-profile-events`

The `-Zself-profile-events` compiler flag controls what events are recorded by the self-profiler when it is enabled via the `-Zself-profile` flag.

This flag takes a comma delimited list of event types to record.

For example:

    $ rustc -Zself-profile -Zself-profile-events=default,args

## Event types

- `query-provider`

  - Traces each query used internally by the compiler.

- `generic-activity`

  - Traces other parts of the compiler not covered by the query system.

- `query-cache-hit`

  - Adds tracing information that records when the in-memory query cache is “hit” and does not need to re-execute a query which has been cached.
  - Disabled by default because this significantly increases the trace file size.

- `query-blocked`

  - Tracks time that a query tries to run but is blocked waiting on another thread executing the same query to finish executing.
  - Query blocking only occurs when the compiler is built with parallel mode support.

- `incr-cache-load`

  - Tracks time that is spent loading and deserializing query results from the incremental compilation on-disk cache.

- `query-keys`

  - Adds a serialized representation of each query’s query key to the tracing data.
  - Disabled by default because this significantly increases the trace file size.

- `function-args`

  - Adds additional tracing data to some `generic-activity` events.
  - Disabled by default for parity with `query-keys`.

- `llvm`

  - Adds tracing information about LLVM passes and codegeneration.
  - Disabled by default because this significantly increases the trace file size.

## Event synonyms

- `none`

  - Disables all events. Equivalent to the self-profiler being disabled.

- `default`

  - The default set of events which stikes a balance between providing detailed tracing data and adding additional overhead to the compilation.

- `args`

  - Equivalent to `query-keys` and `function-args`.

- `all`

  - Enables all events.

## Examples

Enable the profiler and capture the default set of events (both invocations are equivalent):

    $ rustc -Zself-profile
    $ rustc -Zself-profile -Zself-profile-events=default

Enable the profiler and capture the default events and their arguments:

    $ rustc -Zself-profile -Zself-profile-events=default,args

# `shell-argfiles`

The `-Zshell-argfiles` compiler flag allows argfiles to be parsed using POSIX “shell-style” quoting. When enabled, the compiler will use `shlex` to parse the arguments from argfiles specified with `@shell:<path>`.

Because this feature controls the parsing of input arguments, the `-Zshell-argfiles` flag must be present before the argument specifying the shell-style argument file.

# `small-data-threshold`

This flag controls the maximum static variable size that may be included in the “small data sections” (.sdata, .sbss) supported by some architectures (RISCV, MIPS, M68K, Hexagon). Can be set to `0` to disable the use of small data sections.

Target support is indicated by the `small_data_threshold_support` target option which can be:

- `none` (`SmallDataThresholdSupport::None`) for no support
- `default-for-arch` (`SmallDataThresholdSupport::DefaultForArch`) which is automatically translated into an appropriate value for the target.
- `llvm-module-flag=<flag_name>` (`SmallDataThresholdSupport::LlvmModuleFlag`) for specifying the threshold via an LLVM module flag
- `llvm-arg=<arg_name>` (`SmallDataThresholdSupport::LlvmArg`) for specifying the threshold via an LLVM argument.

# `split-dwarf-out-dir`

On systems which use DWARF debug info this flag causes `.dwo` files produced by `-C split-debuginfo` to be written to the specified directory rather than placed next to the object files. This is mostly useful if you have a build system which needs to control where to find compile outputs without running the compiler and have to put your `.dwo` files in a separate directory.

# `src-hash-algorithm`

The tracking issue for this feature is: #70401.

The `-Z src-hash-algorithm` compiler flag controls which algorithm is used when hashing each source file. The hash is stored in the debug info and can be used by a debugger to verify the source code matches the executable.

Supported hash algorithms are: `md5`, `sha1`, and `sha256`. Note that not all hash algorithms are supported by all debug info formats.

By default, the compiler chooses the hash algorithm based on the target specification.

# `temps-dir`

The `-Ztemps-dir` compiler flag specifies the directory to write the intermediate files in. If not set, the output directory is used. This option is useful if you are running more than one instance of `rustc` (e.g. with different `--crate-type` settings), and you need to make sure they are not overwriting each other’s intermediate files. No files are kept unless `-C save-temps=yes` is also set.

# `-Z terminal-urls`

The tracking feature for this issue is #125586

This flag takes either a boolean or the string “auto”.

When enabled, use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output. Use “auto” to try and autodetect whether the terminal emulator supports hyperlinks. Currently, “auto” only enables hyperlinks if `COLORTERM=truecolor` and `TERM=xterm-256color`.

# `tiny-const-eval-limit`

The `-Ztiny-const-eval-limit` compiler flag sets a tiny, non-configurable limit for const eval. This flag should only be used by const eval tests in the rustc test suite.

# `tls_model`

The tracking issue for this feature is: None.

Option `-Z tls-model` controls TLS model used to generate code for accessing `#[thread_local]` `static` items.

Supported values for this option are:

- `global-dynamic` - General Dynamic TLS Model (alternatively called Global Dynamic) is the most general option usable in all circumstances, even if the TLS data is defined in a shared library loaded at runtime and is accessed from code outside of that library. This is the default for most targets.
- `local-dynamic` - model usable if the TLS data is only accessed from the shared library or executable it is defined in. The TLS data may be in a library loaded after startup (via `dlopen`).
- `initial-exec` - model usable if the TLS data is defined in the executable or in a shared library loaded at program startup. The TLS data must not be in a library loaded after startup (via `dlopen`).
- `local-exec` - model usable only if the TLS data is defined directly in the executable, but not in a shared library, and is accessed only from that executable.
- `emulated` - Uses thread-specific data keys to implement emulated TLS. It is like using a general-dynamic TLS model for all modes.

`rustc` and LLVM may use a more optimized model than specified if they know that we are producing an executable rather than a library, or that the `static` item is private enough.

# `track-diagnostics`

This feature is perma-unstable and has no tracking issue.

This flag prints the source code span in the compiler where a diagnostic was generated, respecting `#[track_caller]`. Note that this may be different from the place it was emitted. For full documentation, see the rustc-dev-guide.

# `treat-err-as-bug`

This feature is perma-unstable and has no tracking issue.

This flag converts the selected error to a `bug!` call, exiting the compiler immediately and allowing you to generate a backtrace of where the error occurred. For full documentation, see the rustc-dev-guide.

Note that the compiler automatically sets `RUST_BACKTRACE=1` for itself, and so you do not need to set it yourself when using this flag.

# `ub-checks`

The tracking issue for this feature is: #123499.

The `-Zub-checks` compiler flag enables additional runtime checks that detect some causes of Undefined Behavior at runtime. By default, `-Zub-checks` flag inherits the value of `-Cdebug-assertions`.

All checks are generated on a best-effort basis; even if we have a check implemented for some cause of Undefined Behavior, it may be possible for the check to not fire. If a dependency is compiled with `-Zub-checks=no` but the final binary or library is compiled with `-Zub-checks=yes`, UB checks reached by the dependency are likely to be optimized out.

When `-Zub-checks` detects UB, a non-unwinding panic is produced. That means that we will not unwind the stack and will not call any `Drop` impls, but we will execute the configured panic hook. We expect that unsafe code has been written which relies on code not unwinding which may have UB checks inserted. Ergo, an unwinding panic could easily turn works-as-intended UB into a much bigger problem. Calling the panic hook theoretically has the same implications, but we expect that the standard library panic hook will be stateless enough to be always called, and that if a user has configured a panic hook that the hook may be very helpful to debugging the detected UB.

# `unsound-mir-opts`

The `-Zunsound-mir-opts` compiler flag enables MIR optimization passes which can cause unsound behavior. This flag should only be used by MIR optimization tests in the rustc test suite.

# `verbose-asm`

The tracking issue for this feature is: #126802.

This enables passing `-Zverbose-asm` to get contextual comments added by LLVM.

Sample code:

    #![allow(unused)]
    fn main() {
    #[no_mangle]
    pub fn foo(a: i32, b: i32) -> i32 {
        a + b
    }
    }

Default output:

    foo:
            push    rax
            add     edi, esi
            mov     dword ptr [rsp + 4], edi
            seto    al
            jo      .LBB0_2
            mov     eax, dword ptr [rsp + 4]
            pop     rcx
            ret
    .LBB0_2:
            lea     rdi, [rip + .L__unnamed_1]
            mov     rax, qword ptr [rip + core::panicking::panic_const::panic_const_add_overflow::h9c85248fe0d735b2@GOTPCREL]
            call    rax

    .L__unnamed_2:
            .ascii  "/app/example.rs"

    .L__unnamed_1:
            .quad   .L__unnamed_2
            .asciz  "\017\000\000\000\000\000\000\000\004\000\000\000\005\000\000"

With `-Zverbose-asm`:

    foo:                                    # @foo
    # %bb.0:
            push    rax
            add     edi, esi
            mov     dword ptr [rsp + 4], edi        # 4-byte Spill
            seto    al
            jo      .LBB0_2
    # %bb.1:
            mov     eax, dword ptr [rsp + 4]        # 4-byte Reload
            pop     rcx
            ret
    .LBB0_2:
            lea     rdi, [rip + .L__unnamed_1]
            mov     rax, qword ptr [rip + core::panicking::panic_const::panic_const_add_overflow::h9c85248fe0d735b2@GOTPCREL]
            call    rax
                                            # -- End function
    .L__unnamed_2:
            .ascii  "/app/example.rs"

    .L__unnamed_1:
            .quad   .L__unnamed_2
            .asciz  "\017\000\000\000\000\000\000\000\004\000\000\000\005\000\000"

                                            # DW_AT_external

# `virtual-function-elimination`

This option controls whether LLVM runs the Virtual Function Elimination (VFE) optimization. This optimization in only available with LTO, so this flag can only be passed if `-Clto` is also passed.

VFE makes it possible to remove functions from vtables that are never dynamically called by the rest of the code. Without this flag, LLVM makes the really conservative assumption, that if any function in a vtable is called, no function that is referenced by this vtable can be removed. With this flag additional information are given to LLVM, so that it can determine which functions are actually called and remove the unused functions.

## Limitations

At the time of writing this flag may remove vtable functions too eagerly. One such example is in this code:

    #![allow(unused)]
    fn main() {
    trait Foo { fn foo(&self) { println!("foo") } }

    impl Foo for usize {}

    pub struct FooBox(Box<dyn Foo>);

    pub fn make_foo() -> FooBox { FooBox(Box::new(0)) }

    #[inline]
    pub fn f(a: FooBox) { a.0.foo() }
    }

In the above code the `Foo` trait is private, so an assumption is made that its functions can only be seen/called from the current crate and can therefore get optimized out, if unused. However, with `make_foo` you can produce a wrapped `dyn Foo` type outside of the current crate, which can then be used in `f`. Due to inlining of `f`, `Foo::foo` can then be called from a foreign crate. This can lead to miscompilations.

# `wasm-c-abi`

This option controls whether Rust uses the spec-compliant C ABI when compiling for the `wasm32-unknown-unknown` target.

This makes it possible to be ABI-compatible with all other spec-compliant Wasm targets like `wasm32-wasip1`.

This compiler flag is perma-unstable, as it will be enabled by default in the future with no option to fall back to the old non-spec-compliant ABI.

# Language features

# `aarch64_unstable_target_feature`

The remaining unstable target features on aarch64.

The tracking issue for this feature is: #150244

# `aarch64_ver_target_feature`

Instruction set “version” target features on aarch64.

The tracking issue for this feature is: #150245

# `abi_avr_interrupt`

Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`.

The tracking issue for this feature is: #69664

# `abi_cmse_nonsecure_call`

The tracking issue for this feature is: #81391

The TrustZone-M feature is available for targets with the Armv8-M architecture profile (`thumbv8m` in their target name). LLVM, the Rust compiler and the linker are providing support for the TrustZone-M feature.

One of the things provided with this unstable feature is the “cmse-nonsecure-call” function ABI. This ABI is used on function pointers to non-secure code to mark a non-secure function call (see section 5.5 for details).

With this ABI, the compiler will do the following to perform the call:

- save registers needed after the call to Secure memory
- clear all registers that might contain confidential information
- clear the Least Significant Bit of the function address
- branches using the BLXNS instruction

To avoid using the non-secure stack, the compiler will constrain the number and type of parameters/return value.

    #![no_std]
    #![feature(abi_cmse_nonsecure_call)]

    #[no_mangle]
    pub fn call_nonsecure_function(addr: usize) -> u32 {
        let non_secure_function =
            unsafe { core::mem::transmute::<usize, extern "cmse-nonsecure-call" fn() -> u32>(addr) };
        non_secure_function()
    }

    $ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs

    call_nonsecure_function:
            .fnstart
            .save   {r7, lr}
            push    {r7, lr}
            .setfp  r7, sp
            mov     r7, sp
            .pad    #16
            sub     sp, #16
            str     r0, [sp, #12]
            ldr     r0, [sp, #12]
            str     r0, [sp, #8]
            b       .LBB0_1
    .LBB0_1:
            ldr     r0, [sp, #8]
            push.w  {r4, r5, r6, r7, r8, r9, r10, r11}
            bic     r0, r0, #1
            mov     r1, r0
            mov     r2, r0
            mov     r3, r0
            mov     r4, r0
            mov     r5, r0
            mov     r6, r0
            mov     r7, r0
            mov     r8, r0
            mov     r9, r0
            mov     r10, r0
            mov     r11, r0
            mov     r12, r0
            msr     apsr_nzcvq, r0
            blxns   r0
            pop.w   {r4, r5, r6, r7, r8, r9, r10, r11}
            str     r0, [sp, #4]
            b       .LBB0_2
    .LBB0_2:
            ldr     r0, [sp, #4]
            add     sp, #16
            pop     {r7, pc}

# `abi_custom`

Allows `extern "custom" fn()`.

The tracking issue for this feature is: #140829

# `abi_gpu_kernel`

Allows `extern "gpu-kernel" fn()`.

The tracking issue for this feature is: #135467

# `abi_msp430_interrupt`

The tracking issue for this feature is: #38487

In the MSP430 architecture, interrupt handlers have a special calling convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply the right calling convention to the interrupt handlers you define.

    #![feature(abi_msp430_interrupt)]
    #![no_std]

    // Place the interrupt handler at the appropriate memory address
    // (Alternatively, you can use `#[used]` and remove `pub` and `#[no_mangle]`)
    #[link_section = "__interrupt_vector_10"]
    #[no_mangle]
    pub static TIM0_VECTOR: extern "msp430-interrupt" fn() = tim0;

    // The interrupt handler
    extern "msp430-interrupt" fn tim0() {
        // ..
    }

    $ msp430-elf-objdump -CD ./target/msp430/release/app
    Disassembly of section __interrupt_vector_10:

    0000fff2 <TIM0_VECTOR>:
        fff2:       00 c0           interrupt service routine at 0xc000

    Disassembly of section .text:

    0000c000 <int::tim0>:
        c000:       00 13           reti

# `abi_ptx`

The tracking issue for this feature is: #38788

When emitting PTX code, all vanilla Rust functions (`fn`) get translated to “device” functions. These functions are not callable from the host via the CUDA API so a crate with only device functions is not too useful!

OTOH, “global” functions can be called by the host; you can think of them as the real public API of your crate. To produce a global function use the `"ptx-kernel"` ABI.

    #![feature(abi_ptx)]
    #![no_std]

    pub unsafe extern "ptx-kernel" fn global_function() {
        device_function();
    }

    pub fn device_function() {
        // ..
    }

    $ xargo rustc --target nvptx64-nvidia-cuda --release -- --emit=asm

    $ cat $(find -name '*.s')
    //
    // Generated by LLVM NVPTX Back-End
    //

    .version 3.2
    .target sm_20
    .address_size 64

            // .globl       _ZN6kernel15global_function17h46111ebe6516b382E

    .visible .entry _ZN6kernel15global_function17h46111ebe6516b382E()
    {

            ret;
    }

            // .globl       _ZN6kernel15device_function17hd6a0e4993bbf3f78E
    .visible .func _ZN6kernel15device_function17hd6a0e4993bbf3f78E()
    {

            ret;
    }

# `abi_riscv_interrupt`

Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.

The tracking issue for this feature is: #111889

# `abi_unadjusted`

Allows using the `unadjusted` ABI; perma-unstable.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `abi_vectorcall`

The tracking issue for this feature is: #124485

Adds support for the Windows `"vectorcall"` ABI, the equivalent of `__vectorcall` in MSVC.

    extern "vectorcall" {
        fn add_f64s(x: f64, y: f64) -> f64;
    }

    fn main() {
        println!("{}", add_f64s(2.0, 4.0));
    }

# `abi_x86_interrupt`

Allows `extern "x86-interrupt" fn()`.

The tracking issue for this feature is: #40180

# `adt_const_params`

The tracking issue for this feature is: #95174

Allows for using more complex types for const parameters, such as structs or enums.

    #![allow(unused)]
    #![feature(adt_const_params)]
    #![allow(incomplete_features)]

    fn main() {
    use std::marker::ConstParamTy;

    #[derive(ConstParamTy, PartialEq, Eq)]
    enum Foo {
        A,
        B,
        C,
    }

    #[derive(ConstParamTy, PartialEq, Eq)]
    struct Bar {
        flag: bool,
    }

    fn is_foo_a_and_bar_true<const F: Foo, const B: Bar>() -> bool {
        match (F, B.flag) {
            (Foo::A, true) => true,
            _ => false,
        }
    }
    }

# `alloc_error_handler`

Allows defining an `#[alloc_error_handler]`.

The tracking issue for this feature is: #51540

# `allocator_internals`

This feature does not have a tracking issue, it is an unstable implementation detail of the `global_allocator` feature not intended for use outside the compiler.

# `allow_internal_unsafe`

Allows using `#[allow_internal_unsafe]`. This is an attribute on `macro_rules!` and can’t use the attribute handling below (it has to be checked before expansion possibly makes macros disappear).

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `allow_internal_unstable`

Allows using `#[allow_internal_unstable]`. This is an attribute on `macro_rules!` and can’t use the attribute handling below (it has to be checked before expansion possibly makes macros disappear).

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `anonymous_lifetime_in_impl_trait`

Allows using anonymous lifetimes in argument-position impl-trait.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `apx_target_feature`

The `apxf` target feature on x86

The tracking issue for this feature is: #139284

# `arbitrary_self_types`

The tracking issue for this feature is: #44874

Allows any type implementing `core::ops::Receiver<Target=T>` to be used as the type of `self` in a method belonging to `T`.

For example,

    #![feature(arbitrary_self_types)]

    struct A;

    impl A {
        fn f(self: SmartPtr<Self>) -> i32 { 1 }  // note self type
    }

    struct SmartPtr<T>(T);

    impl<T> core::ops::Receiver for SmartPtr<T> {
        type Target = T;
    }

    fn main() {
        let smart_ptr = SmartPtr(A);
        assert_eq!(smart_ptr.f(), 1);
    }

The `Receiver` trait has a blanket implementation for all `T: Deref`, so in fact things like this work too:

    #![feature(arbitrary_self_types)]

    use std::rc::Rc;

    struct A;

    impl A {
        fn f(self: Rc<Self>) -> i32 { 1 } // Rc implements Deref
    }

    fn main() {
        let smart_ptr = Rc::new(A);
        assert_eq!(smart_ptr.f(), 1);
    }

Interestingly, that works even without the `arbitrary_self_types` feature

- but that’s because certain types are effectively hard coded, including `Rc`. (“Hard coding” isn’t quite true; they use a lang-item called `LegacyReceiver` to denote their special-ness in this way). With the `arbitrary_self_types` feature, their special-ness goes away, and custom smart pointers can achieve the same.

## Changes to method lookup

Method lookup previously used to work by stepping through the `Deref` chain then using the resulting list of steps in two different ways:

- To identify types that might contribute methods via their `impl` blocks (inherent methods) or via traits
- To identify the types that the method receiver (`a` in the above examples) can be converted to.

With this feature, these lists are created by instead stepping through the `Receiver` chain. However, a note is kept about whether the type can be reached also via the `Deref` chain.

The full chain (via `Receiver` hops) is used for the first purpose (identifying relevant `impl` blocks and traits); whereas the shorter list (reachable via `Deref`) is used for the second purpose. That’s because, to convert the method target (`a` in `a.b()`) to the self type, Rust may need to be able to use `Deref::deref`. Type conversions, then, can only proceed as far as the end of the `Deref` chain whereas the longer `Receiver` chain can be used to explore more places where useful methods might reside.

## Types suitable for use as smart pointers

This feature allows the creation of customised smart pointers - for example your own equivalent to `Rc` or `Box` with whatever capabilities you like. Those smart pointers can either implement `Deref` (if it’s safe to create a reference to the referent) or `Receiver` (if it isn’t).

Either way, smart pointer types should mostly avoid having methods. Calling methods on a smart pointer leads to ambiguity about whether you’re aiming for a method on the pointer, or on the referent.

Best practice is therefore to put smart pointer functionality into associated functions instead - that’s what’s done in all the smart pointer types within Rust’s standard library which implement `Receiver`.

If you choose to add any methods to your smart pointer type, your users may run into errors from deshadowing, as described in the next section.

## Avoiding shadowing

With or without this feature, Rust emits an error if it finds two method candidates, like this:

    use std::pin::Pin;
    use std::pin::pin;

    struct A;

    impl A {
        fn get_ref(self: Pin<&A>) {}
    }

    fn main() {
        let pinned_a: Pin<&A> = pin!(A).as_ref();
        let pinned_a: Pin<&A> = pinned_a.as_ref();
        pinned_a.get_ref(); // error[E0034]: multiple applicable items in scope
    }

(this is why Rust’s smart pointers are mostly carefully designed to avoid having methods at all, and shouldn’t add new methods in future.)

With `arbitrary_self_types`, we take care to spot some other kinds of conflict:

    #![feature(arbitrary_self_types)]

    use std::pin::Pin;
    use std::pin::pin;

    struct A;

    impl A {
        fn get_ref(self: &Pin<&A>) {}  // note &Pin
    }

    fn main() {
        let pinned_a: Pin<&mut A> = pin!(A);
        let pinned_a: Pin<&A> = pinned_a.as_ref();
        pinned_a.get_ref();
    }

This is to guard against the case where an inner (referent) type has a method of a given name, taking the smart pointer by reference, and then the smart pointer implementer adds a similar method taking self by value. As noted in the previous section, the safe option is simply not to add methods to smart pointers, and then these errors can’t occur.

# `arbitrary_self_types_pointers`

The tracking issue for this feature is: [#44874]

This extends the arbitrary self types feature to allow methods to receive `self` by pointer. For example:

    #![feature(arbitrary_self_types_pointers)]

    struct A;

    impl A {
        fn m(self: *const Self) {}
    }

    fn main() {
        let a = A;
        let a_ptr: *const A = &a as *const A;
        a_ptr.m();
    }

In general this is not advised: it’s thought to be better practice to wrap raw pointers in a newtype wrapper which implements the `core::ops::Receiver` trait, then you need “only” the `arbitrary_self_types` feature. For example:

    #![feature(arbitrary_self_types)]
    #![allow(dead_code)]

    struct A;

    impl A {
        fn m(self: Wrapper<Self>) {} // can extract the pointer and do
            // what it needs
    }

    struct Wrapper<T>(*const T);

    impl<T> core::ops::Receiver for Wrapper<T> {
        type Target = T;
    }

    fn main() {
        let a = A;
        let a_ptr: *const A = &a as *const A;
        let a_wrapper = Wrapper(a_ptr);
        a_wrapper.m();
    }

# `arm_target_feature`

Target features on arm.

The tracking issue for this feature is: #150246

# `asm_experimental_arch`

The tracking issue for this feature is: #93335

This feature tracks `asm!` and `global_asm!` support for the following architectures:

- NVPTX
- PowerPC
- Hexagon
- MIPS32r2 and MIPS64r2
- wasm32
- BPF
- SPIR-V
- AVR
- MSP430
- M68k
- CSKY
- SPARC

## Register classes

Architecture | Register class | Registers | LLVM constraint code
--- | --- | --- | ---
MIPS | `reg` | `$[2-25]` | `r`
MIPS | `freg` | `$f[0-31]` | `f`
NVPTX | `reg16` | None* | `h`
NVPTX | `reg32` | None* | `r`
NVPTX | `reg64` | None* | `l`
Hexagon | `reg` | `r[0-28]` | `r`
Hexagon | `preg` | `p[0-3]` | Only clobbers
PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-29]`* | `r`
PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-29]`* | `b`
PowerPC | `freg` | `f[0-31]` | `f`
PowerPC | `vreg` | `v[0-31]` | `v`
PowerPC | `vsreg | `vs[0-63]` | `wa`
PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers
PowerPC | `ctr` | `ctr` | Only clobbers
PowerPC | `lr` | `lr` | Only clobbers
PowerPC | `xer` | `xer` | Only clobbers
PowerPC | `spe_acc` | `spe_acc` | Only clobbers
wasm32 | `local` | None* | `r`
BPF | `reg` | `r[0-10]` | `r`
BPF | `wreg` | `w[0-10]` | `w`
AVR | `reg` | `r[2-25]`, `XH`, `XL`, `ZH`, `ZL` | `r`
AVR | `reg_upper` | `r[16-25]`, `XH`, `XL`, `ZH`, `ZL` | `d`
AVR | `reg_pair` | `r3r2` .. `r25r24`, `X`, `Z` | `r`
AVR | `reg_iw` | `r25r24`, `X`, `Z` | `w`
AVR | `reg_ptr` | `X`, `Z` | `e`
MSP430 | `reg` | `r[0-15]` | `r`
M68k | `reg` | `d[0-7]`, `a[0-7]` | `r`
M68k | `reg_data` | `d[0-7]` | `d`
M68k | `reg_addr` | `a[0-3]` | `a`
CSKY | `reg` | `r[0-31]` | `r`
CSKY | `freg` | `f[0-31]` | `f`
SPARC | `reg` | `r[2-29]` | `r`
SPARC | `yreg` | `y` | Only clobbers

> Notes:

> - NVPTX doesn’t have a fixed register set, so named registers are not supported.

> - WebAssembly doesn’t have registers, so named registers are not supported.

> - r29 is reserved only on 32 bit PowerPC targets.

> - spe_acc is only available on PowerPC SPE targets.

# Register class supported types

Architecture | Register class | Target feature | Allowed types
--- | --- | --- | ---
MIPS32 | `reg` | None | `i8`, `i16`, `i32`, `f32`
MIPS32 | `freg` | None | `f32`, `f64`
MIPS64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64`
MIPS64 | `freg` | None | `f32`, `f64`
NVPTX | `reg16` | None | `i8`, `i16`
NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32`
NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`
Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32`
Hexagon | `preg` | N/A | Only clobbers
PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only)
PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only)
PowerPC | `freg` | None | `f32`, `f64`
PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4`
PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2`
PowerPC | `vsreg` | `vsx` | The union of vsx and altivec vreg types
PowerPC | `cr` | N/A | Only clobbers
PowerPC | `ctr` | N/A | Only clobbers
PowerPC | `lr` | N/A | Only clobbers
PowerPC | `xer` | N/A | Only clobbers
PowerPC | `spe_acc` | N/A | Only clobbers
wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64`
BPF | `reg` | None | `i8` `i16` `i32` `i64`
BPF | `wreg` | `alu32` | `i8` `i16` `i32`
AVR | `reg`, `reg_upper` | None | `i8`
AVR | `reg_pair`, `reg_iw`, `reg_ptr` | None | `i16`
MSP430 | `reg` | None | `i8`, `i16`
M68k | `reg`, `reg_addr` | None | `i16`, `i32`
M68k | `reg_data` | None | `i8`, `i16`, `i32`
CSKY | `reg` | None | `i8`, `i16`, `i32`
CSKY | `freg` | None | `f32`,
SPARC | `reg` | None | `i8`, `i16`, `i32`, `i64` (SPARC64 only)
SPARC | `yreg` | N/A | Only clobbers

## Register aliases

Architecture | Base register | Aliases
--- | --- | ---
Hexagon | `r29` | `sp`
Hexagon | `r30` | `fr`
Hexagon | `r31` | `lr`
PowerPC | `r1` | `sp`
PowerPC | `r31` | `fp`
PowerPC | `r[0-31]` | `[0-31]`
PowerPC | `f[0-31]` | `fr[0-31]`
BPF | `r[0-10]` | `w[0-10]`
AVR | `XH` | `r27`
AVR | `XL` | `r26`
AVR | `ZH` | `r31`
AVR | `ZL` | `r30`
MSP430 | `r0` | `pc`
MSP430 | `r1` | `sp`
MSP430 | `r2` | `sr`
MSP430 | `r3` | `cg`
MSP430 | `r4` | `fp`
M68k | `a5` | `bp`
M68k | `a6` | `fp`
M68k | `a7` | `sp`, `usp`, `ssp`, `isp`
CSKY | `r[0-3]` | `a[0-3]`
CSKY | `r[4-11]` | `l[0-7]`
CSKY | `r[12-13]` | `t[0-1]`
CSKY | `r14` | `sp`
CSKY | `r15` | `lr`
CSKY | `r[16-17]` | `l[8-9]`
CSKY | `r[18-25]` | `t[2-9]`
CSKY | `r28` | `rgb`
CSKY | `r29` | `rtb`
CSKY | `r30` | `svbr`
CSKY | `r31` | `tls`
SPARC | `r[0-7]` | `g[0-7]`
SPARC | `r[8-15]` | `o[0-7]`
SPARC | `r[16-23]` | `l[0-7]`
SPARC | `r[24-31]` | `i[0-7]`

> Notes:

> - TI does not mandate a frame pointer for MSP430, but toolchains are allowed to use one; LLVM uses `r4`.

## Unsupported registers

Architecture | Unsupported register | Reason
--- | --- | ---
All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block.
All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output.
All | `r19` (Hexagon), `r29` (PowerPC 32 bit only), `r30` (PowerPC) | These are used internally by LLVM as “base pointer” for functions with complex stack frames.
MIPS | `$0` or `$zero` | This is a constant zero register which can’t be modified.
MIPS | `$1` or `$at` | Reserved for assembler.
MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers.
MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs.
MIPS | `$ra` | Return address cannot be used as inputs or outputs.
Hexagon | `lr` | This is the link register which cannot be used as an input or output.
PowerPC | `r2`, `r13` | These are system reserved registers.
PowerPC | `vrsave` | The vrsave register cannot be used as an input or output.
AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block.
MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to.
M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer.
CSKY | `r7`, `r28` | Used internally by LLVM for the base pointer and global base pointer.
CSKY | `r8` | Used internally by LLVM for the frame pointer.
CSKY | `r14` | Used internally by LLVM for the stack pointer.
CSKY | `r15` | This is the link register.
CSKY | `r[26-30]` | Reserved by its ABI.
CSKY | `r31` | This is the TLS register.
SPARC | `r0`/`g0` | This is always zero and cannot be used as inputs or outputs.
SPARC | `r1`/`g1` | Used internally by LLVM.
SPARC | `r5`/`g5` | Reserved for system. (SPARC32 only)
SPARC | `r6`/`g6`, `r7`/`g7` | Reserved for system.
SPARC | `r31`/`i7` | Return address cannot be used as inputs or outputs.

## Template modifiers

Architecture | Register class | Modifier | Example output | LLVM modifier
--- | --- | --- | --- | ---
MIPS | `reg` | None | `$2` | None
MIPS | `freg` | None | `$f0` | None
NVPTX | `reg16` | None | `rs0` | None
NVPTX | `reg32` | None | `r0` | None
NVPTX | `reg64` | None | `rd0` | None
Hexagon | `reg` | None | `r0` | None
PowerPC | `reg` | None | `0` | None
PowerPC | `reg_nonzero` | None | `3` | None
PowerPC | `freg` | None | `0` | None
PowerPC | `vreg` | None | `0` | None
PowerPC | `vsreg` | None | `0` | None
SPARC | `reg` | None | `%o0` | None
CSKY | `reg` | None | `r0` | None
CSKY | `freg` | None | `f0` | None

# Flags covered by `preserves_flags`

These flags registers must be restored upon exiting the asm block if the `preserves_flags` option is set:

- AVR
  - The status register `SREG`.
- MSP430
  - The status register `r2`.
- M68k
  - The condition code register `ccr`.
- SPARC
  - Integer condition codes (`icc` and `xcc`)
  - Floating-point condition codes (`fcc[0-3]`)
- CSKY
  - Condition/carry bit (C) in `PSR`.

# `asm_experimental_arch`

The tracking issue for this feature is: #133416

This tracks support for additional registers in architectures where inline assembly is already stable.

## Register classes

Architecture | Register class | Registers | LLVM constraint code
--- | --- | --- | ---
s390x | `vreg` | `v[0-31]` | `v`

> Notes:

> - s390x `vreg` is clobber-only in stable.

## Register class supported types

Architecture | Register class | Target feature | Allowed types
--- | --- | --- | ---
s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`

## Register aliases

Architecture | Base register | Aliases
--- | --- | ---

## Unsupported registers

Architecture | Unsupported register | Reason
--- | --- | ---

## Template modifiers

Architecture | Register class | Modifier | Example output | LLVM modifier
--- | --- | --- | --- | ---
s390x | `vreg` | None | `%v0` | None

# `asm_goto_with_outputs`

The tracking issue for this feature is: #119364

This feature allows label operands to be used together with output operands.

Example:

    unsafe {
        let a: usize;
        asm!(
            "mov {}, 1"
            "jmp {}",
            out(reg) a,
            label {
                println!("Jumped from asm {}!", a);
            }
        );
    }

The output operands are assigned before the label blocks are executed.

# `asm_unwind`

The tracking issue for this feature is: #93334

This feature adds a `may_unwind` option to `asm!` which allows an `asm` block to unwind stack and be part of the stack unwinding process. This option is only supported by the LLVM backend right now.

# `associated_type_defaults`

Allows associated type defaults.

The tracking issue for this feature is: #29661

# `async_drop`

Allows implementing `AsyncDrop`.

The tracking issue for this feature is: #126482

# `async_fn_in_dyn_trait`

Allows async functions to be called from `dyn Trait`.

The tracking issue for this feature is: #133119

# `async_fn_track_caller`

Allows `#[track_caller]` on async functions.

The tracking issue for this feature is: #110011

# `async_for_loop`

Allows `for await` loops.

The tracking issue for this feature is: #118898

# `async_trait_bounds`

Allows `async` trait bound modifier.

The tracking issue for this feature is: #62290

# `auto_traits`

The tracking issue for this feature is #13231

The `auto_traits` feature gate allows you to define auto traits.

Auto traits, like `Send` or `Sync` in the standard library, are marker traits that are automatically implemented for every type, unless the type, or a type it contains, has explicitly opted out via a negative impl. (Negative impls are separately controlled by the `negative_impls` feature.)

    impl !Trait for Type {}

Example:

    #![feature(negative_impls)]
    #![feature(auto_traits)]

    auto trait Valid {}

    struct True;
    struct False;

    impl !Valid for False {}

    struct MaybeValid<T>(T);

    fn must_be_valid<T: Valid>(_t: T) { }

    fn main() {
        // works
        must_be_valid( MaybeValid(True) );

        // compiler error - trait bound not satisfied
        // must_be_valid( MaybeValid(False) );
    }

## Automatic trait implementations

When a type is declared as an `auto trait`, we will automatically create impls for every struct/enum/union, unless an explicit impl is provided. These automatic impls contain a where clause for each field of the form `T: AutoTrait`, where `T` is the type of the field and `AutoTrait` is the auto trait in question. As an example, consider the struct `List` and the auto trait `Send`:

    #![allow(unused)]
    fn main() {
    struct List<T> {
      data: T,
      next: Option<Box<List<T>>>,
    }
    }

Presuming that there is no explicit impl of `Send` for `List`, the compiler will supply an automatic impl of the form:

    #![allow(unused)]
    fn main() {
    struct List<T> {
      data: T,
      next: Option<Box<List<T>>>,
    }

    unsafe impl<T> Send for List<T>
    where
      T: Send, // from the field `data`
      Option<Box<List<T>>>: Send, // from the field `next`
    { }
    }

Explicit impls may be either positive or negative. They take the form:

    impl<...> AutoTrait for StructName<..> { }
    impl<...> !AutoTrait for StructName<..> { }

## Coinduction: Auto traits permit cyclic matching

Unlike ordinary trait matching, auto traits are coinductive. This means, in short, that cycles which occur in trait matching are considered ok. As an example, consider the recursive struct `List` introduced in the previous section. In attempting to determine whether `List: Send`, we would wind up in a cycle: to apply the impl, we must show that `Option<Box<List>>: Send`, which will in turn require `Box<List>: Send` and then finally `List: Send` again. Under ordinary trait matching, this cycle would be an error, but for an auto trait it is considered a successful match.

## Items

Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.

## Supertraits

Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.

# `avx10_target_feature`

Allows using Intel AVX10 target features and intrinsics

The tracking issue for this feature is: #138843

# `box_patterns`

The tracking issue for this feature is: #29641

> Note: This feature will be superseded by `deref_patterns` in the future.

Box patterns let you match on `Box<T>`s:

    #![feature(box_patterns)]

    fn main() {
        let b = Some(Box::new(5));
        match b {
            Some(box n) if n < 0 => {
                println!("Box contains negative number {n}");
            },
            Some(box n) if n >= 0 => {
                println!("Box contains non-negative number {n}");
            },
            None => {
                println!("No box");
            },
            _ => unreachable!()
        }
    }

# `bpf_target_feature`

Target features on bpf.

The tracking issue for this feature is: #150247

# `builtin_syntax`

Allows builtin # foo() syntax

The tracking issue for this feature is: #110680

# `c_variadic`

The tracking issue for this feature is: #44930

The `c_variadic` language feature enables C-variadic functions to be defined in Rust. They may be called both from within Rust and via FFI.

## Examples

    #![allow(unused)]
    #![feature(c_variadic)]

    fn main() {
    pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
        let mut sum = 0;
        for _ in 0..n {
            sum += args.arg::<usize>();
        }
        sum
    }
    }

# `c_variadic_naked_functions`

Allows defining c-variadic naked functions with any extern ABI that is allowed on c-variadic foreign functions.

The tracking issue for this feature is: #148767

# `cfg_contract_checks`

Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.

The tracking issue for this feature is: #128044

# `cfg_emscripten_wasm_eh`

Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `cfg_overflow_checks`

Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.

The tracking issue for this feature is: #111466

# `cfg_relocation_model`

Provides the relocation model information as cfg entry

The tracking issue for this feature is: #114929

# `cfg_sanitize`

The tracking issue for this feature is: #39699

The `cfg_sanitize` feature makes it possible to execute different code depending on whether a particular sanitizer is enabled or not.

## Examples

    #![allow(unused)]
    #![feature(cfg_sanitize)]

    fn main() {
    #[cfg(sanitize = "thread")]
    fn a() {
        // ...
    }

    #[cfg(not(sanitize = "thread"))]
    fn a() {
        // ...
    }

    fn b() {
        if cfg!(sanitize = "leak") {
            // ...
        } else {
            // ...
        }
    }
    }

# `cfg_sanitizer_cfi`

Allows `cfg(sanitizer_cfi_generalize_pointers)` and `cfg(sanitizer_cfi_normalize_integers)`.

The tracking issue for this feature is: #89653

# `cfg_target_compact`

Allows `cfg(target(abi = "..."))`.

The tracking issue for this feature is: #96901

# `cfg_target_has_atomic`

Allows `cfg(target_has_atomic_load_store = "...")`.

The tracking issue for this feature is: #94039

# `cfg_target_has_atomic_equal_alignment`

Allows `cfg(target_has_atomic_equal_alignment = "...")`.

The tracking issue for this feature is: #93822

# `cfg_target_has_reliable_f16_f128`

Allows checking whether or not the backend correctly supports unstable float types.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `cfg_target_thread_local`

Allows `cfg(target_thread_local)`.

The tracking issue for this feature is: #29594

# `cfg_ub_checks`

Allows the use of `#[cfg(ub_checks)` to check if UB checks are enabled.

The tracking issue for this feature is: #123499

# `cfg_version`

The tracking issue for this feature is: #64796

The `cfg_version` feature makes it possible to execute different code depending on the compiler version. It will return true if the compiler version is greater than or equal to the specified version.

## Examples

    #![allow(unused)]
    #![feature(cfg_version)]

    fn main() {
    #[cfg(version("1.42"))] // 1.42 and above
    fn a() {
        // ...
    }

    #[cfg(not(version("1.42")))] // 1.41 and below
    fn a() {
        // ...
    }

    fn b() {
        if cfg!(version("1.42")) {
            // ...
        } else {
            // ...
        }
    }
    }

# `cfi_encoding`

The tracking issue for this feature is: #89653

The `cfi_encoding` feature allows the user to define a CFI encoding for a type. It allows the user to use a different names for types that otherwise would be required to have the same name as used in externally defined C functions.

## Examples

    #![allow(unused)]
    #![feature(cfi_encoding, extern_types)]

    fn main() {
    #[cfi_encoding = "3Foo"]
    pub struct Type1(i32);

    extern {
        #[cfi_encoding = "3Bar"]
        type Type2;
    }
    }

# `closure_lifetime_binder`

Allows `for<...>` on closures and coroutines.

The tracking issue for this feature is: #97362

# `closure_track_caller`

The tracking issue for this feature is: #87417

Allows using the `#[track_caller]` attribute on closures and coroutines. Calls made to the closure or coroutine will have caller information available through `std::panic::Location::caller()`, just like using `#[track_caller]` on a function.

# `cmse_nonsecure_entry`

The tracking issue for this feature is: #75835

The TrustZone-M feature is available for targets with the Armv8-M architecture profile (`thumbv8m` in their target name). LLVM, the Rust compiler and the linker are providing support for the TrustZone-M feature.

One of the things provided with this unstable feature is the “cmse-nonsecure-entry” ABI. This ABI marks a Secure function as an entry function (see section 5.4 for details). With this ABI, the compiler will do the following:

- add a special symbol on the function which is the `__acle_se_` prefix and the standard function name
- constrain the number of parameters to avoid using the Non-Secure stack
- before returning from the function, clear registers that might contain Secure information
- use the `BXNS` instruction to return

Because the stack can not be used to pass parameters, there will be compilation errors if:

- the total size of all parameters is too big (for example, more than four 32-bit integers)

The special symbol `__acle_se_` will be used by the linker to generate a secure gateway veneer.

    #![no_std]
    #![feature(cmse_nonsecure_entry)]

    #[no_mangle]
    pub extern "cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
        input + 6
    }

    $ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
    $ arm-none-eabi-objdump -D function.o

    00000000 <entry_function>:
       0:   b580            push    {r7, lr}
       2:   466f            mov     r7, sp
       4:   b082            sub     sp, #8
       6:   9001            str     r0, [sp, #4]
       8:   1d81            adds    r1, r0, #6
       a:   460a            mov     r2, r1
       c:   4281            cmp     r1, r0
       e:   9200            str     r2, [sp, #0]
      10:   d30b            bcc.n   2a <entry_function+0x2a>
      12:   e7ff            b.n     14 <entry_function+0x14>
      14:   9800            ldr     r0, [sp, #0]
      16:   b002            add     sp, #8
      18:   e8bd 4080       ldmia.w sp!, {r7, lr}
      1c:   4671            mov     r1, lr
      1e:   4672            mov     r2, lr
      20:   4673            mov     r3, lr
      22:   46f4            mov     ip, lr
      24:   f38e 8800       msr     CPSR_f, lr
      28:   4774            bxns    lr
      2a:   f240 0000       movw    r0, #0
      2e:   f2c0 0000       movt    r0, #0
      32:   f240 0200       movw    r2, #0
      36:   f2c0 0200       movt    r2, #0
      3a:   211c            movs    r1, #28
      3c:   f7ff fffe       bl      0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E>
      40:   defe            udf     #254    ; 0xfe

# `compiler_builtins`

This feature is internal to the Rust compiler and is not intended for general use.

# `const_async_blocks`

Allows `async {}` expressions in const contexts.

The tracking issue for this feature is: #85368

# `const_closures`

Allows `const || {}` closures in const contexts.

The tracking issue for this feature is: #106003

# `const_destruct`

Allows using `[const] Destruct` bounds and calling drop impls in const contexts.

The tracking issue for this feature is: #133214

# `const_for`

Allows `for _ in _` loops in const contexts.

The tracking issue for this feature is: #87575

# `const_precise_live_drops`

Be more precise when looking for live drops in a const context.

The tracking issue for this feature is: #73255

# `const_trait_impl`

Allows `impl const Trait for T` syntax.

The tracking issue for this feature is: #143874

# `const_try`

Allows the `?` operator in const contexts.

The tracking issue for this feature is: #74935

# `contracts`

Allows use of contracts attributes.

The tracking issue for this feature is: #128044

# `contracts_internals`

Allows access to internal machinery used to implement contracts.

The tracking issue for this feature is: #128044

# `coroutine_clone`

Allows coroutines to be cloned.

The tracking issue for this feature is: #95360

# `coroutines`

The tracking issue for this feature is: #43122

The `coroutines` feature gate in Rust allows you to define coroutine or coroutine literals. A coroutine is a “resumable function” that syntactically resembles a closure but compiles to much different semantics in the compiler itself. The primary feature of a coroutine is that it can be suspended during execution to be resumed at a later date. Coroutines use the `yield` keyword to “return”, and then the caller can `resume` a coroutine to resume execution just after the `yield` keyword.

Coroutines are an extra-unstable feature in the compiler right now. Added in RFC 2033 they’re mostly intended right now as a information/constraint gathering phase. The intent is that experimentation can happen on the nightly compiler before actual stabilization. A further RFC will be required to stabilize coroutines and will likely contain at least a few small tweaks to the overall design.

A syntactical example of a coroutine is:

    #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]

    use std::ops::{Coroutine, CoroutineState};
    use std::pin::Pin;

    fn main() {
        let mut coroutine = #[coroutine] || {
            yield 1;
            return "foo"
        };

        match Pin::new(&mut coroutine).resume(()) {
            CoroutineState::Yielded(1) => {}
            _ => panic!("unexpected value from resume"),
        }
        match Pin::new(&mut coroutine).resume(()) {
            CoroutineState::Complete("foo") => {}
            _ => panic!("unexpected value from resume"),
        }
    }

Coroutines are closure-like literals which are annotated with `#[coroutine]` and can contain a `yield` statement. The `yield` statement takes an optional expression of a value to yield out of the coroutine. All coroutine literals implement the `Coroutine` trait in the `std::ops` module. The `Coroutine` trait has one main method, `resume`, which resumes execution of the coroutine at the previous suspension point.

An example of the control flow of coroutines is that the following example prints all numbers in order:

    #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]

    use std::ops::Coroutine;
    use std::pin::Pin;

    fn main() {
        let mut coroutine = #[coroutine] || {
            println!("2");
            yield;
            println!("4");
        };

        println!("1");
        Pin::new(&mut coroutine).resume(());
        println!("3");
        Pin::new(&mut coroutine).resume(());
        println!("5");
    }

At this time the main use case of coroutines is an implementation primitive for `async`/`await` and `gen` syntax, but coroutines will likely be extended to other primitives in the future. Feedback on the design and usage is always appreciated!

### The `Coroutine` trait

The `Coroutine` trait in `std::ops` currently looks like:

    #![allow(unused)]
    fn main() {
    #![feature(arbitrary_self_types, coroutine_trait)]
    use std::ops::CoroutineState;
    use std::pin::Pin;

    pub trait Coroutine<R = ()> {
        type Yield;
        type Return;
        fn resume(self: Pin<&mut Self>, resume: R) -> CoroutineState<Self::Yield, Self::Return>;
    }
    }

The `Coroutine::Yield` type is the type of values that can be yielded with the `yield` statement. The `Coroutine::Return` type is the returned type of the coroutine. This is typically the last expression in a coroutine’s definition or any value passed to `return` in a coroutine. The `resume` function is the entry point for executing the `Coroutine` itself.

The return value of `resume`, `CoroutineState`, looks like:

    #![allow(unused)]
    fn main() {
    pub enum CoroutineState<Y, R> {
        Yielded(Y),
        Complete(R),
    }
    }

The `Yielded` variant indicates that the coroutine can later be resumed. This corresponds to a `yield` point in a coroutine. The `Complete` variant indicates that the coroutine is complete and cannot be resumed again. Calling `resume` after a coroutine has returned `Complete` will likely result in a panic of the program.

### Closure-like semantics

The closure-like syntax for coroutines alludes to the fact that they also have closure-like semantics. Namely:

- When created, a coroutine executes no code. A closure literal does not actually execute any of the closure’s code on construction, and similarly a coroutine literal does not execute any code inside the coroutine when constructed.

- Coroutines can capture outer variables by reference or by move, and this can be tweaked with the `move` keyword at the beginning of the closure. Like closures all coroutines will have an implicit environment which is inferred by the compiler. Outer variables can be moved into a coroutine for use as the coroutine progresses.

- Coroutine literals produce a value with a unique type which implements the `std::ops::Coroutine` trait. This allows actual execution of the coroutine through the `Coroutine::resume` method as well as also naming it in return types and such.

- Traits like `Send` and `Sync` are automatically implemented for a `Coroutine` depending on the captured variables of the environment. Unlike closures, coroutines also depend on variables live across suspension points. This means that although the ambient environment may be `Send` or `Sync`, the coroutine itself may not be due to internal variables live across `yield` points being not-`Send` or not-`Sync`. Note that coroutines do not implement traits like `Copy` or `Clone` automatically.

- Whenever a coroutine is dropped it will drop all captured environment variables.

### Coroutines as state machines

In the compiler, coroutines are currently compiled as state machines. Each `yield` expression will correspond to a different state that stores all live variables over that suspension point. Resumption of a coroutine will dispatch on the current state and then execute internally until a `yield` is reached, at which point all state is saved off in the coroutine and a value is returned.

Let’s take a look at an example to see what’s going on here:

    #![feature(coroutines, coroutine_trait, stmt_expr_attributes)]

    use std::ops::Coroutine;
    use std::pin::Pin;

    fn main() {
        let ret = "foo";
        let mut coroutine = #[coroutine] move || {
            yield 1;
            return ret
        };

        Pin::new(&mut coroutine).resume(());
        Pin::new(&mut coroutine).resume(());
    }

This coroutine literal will compile down to something similar to:

    #![feature(arbitrary_self_types, coroutine_trait)]

    use std::ops::{Coroutine, CoroutineState};
    use std::pin::Pin;

    fn main() {
        let ret = "foo";
        let mut coroutine = {
            enum __Coroutine {
                Start(&'static str),
                Yield1(&'static str),
                Done,
            }

            impl Coroutine for __Coroutine {
                type Yield = i32;
                type Return = &'static str;

                fn resume(mut self: Pin<&mut Self>, resume: ()) -> CoroutineState<i32, &'static str> {
                    use std::mem;
                    match mem::replace(&mut *self, __Coroutine::Done) {
                        __Coroutine::Start(s) => {
                            *self = __Coroutine::Yield1(s);
                            CoroutineState::Yielded(1)
                        }

                        __Coroutine::Yield1(s) => {
                            *self = __Coroutine::Done;
                            CoroutineState::Complete(s)
                        }

                        __Coroutine::Done => {
                            panic!("coroutine resumed after completion")
                        }
                    }
                }
            }

            __Coroutine::Start(ret)
        };

        Pin::new(&mut coroutine).resume(());
        Pin::new(&mut coroutine).resume(());
    }

Notably here we can see that the compiler is generating a fresh type, `__Coroutine` in this case. This type has a number of states (represented here as an `enum`) corresponding to each of the conceptual states of the coroutine. At the beginning we’re closing over our outer variable `foo` and then that variable is also live over the `yield` point, so it’s stored in both states.

When the coroutine starts it’ll immediately yield 1, but it saves off its state just before it does so indicating that it has reached the yield point. Upon resuming again we’ll execute the `return ret` which returns the `Complete` state.

Here we can also note that the `Done` state, if resumed, panics immediately as it’s invalid to resume a completed coroutine. It’s also worth noting that this is just a rough desugaring, not a normative specification for what the compiler does.

# `coverage_attribute`

The tracking issue for this feature is: #84605

The `coverage` attribute can be used to selectively disable coverage instrumentation in an annotated function. This might be useful to:

- Avoid instrumentation overhead in a performance critical function
- Avoid generating coverage for a function that is not meant to be executed, but still target 100% coverage for the rest of the program.

## Example

    #![allow(unused)]
    #![feature(coverage_attribute)]

    fn main() {
    // `foo()` will get coverage instrumentation (by default)
    fn foo() {
      // ...
    }

    #[coverage(off)]
    fn bar() {
      // ...
    }
    }

# `csky_target_feature`

Target features on csky.

The tracking issue for this feature is: #150248

# `custom_inner_attributes`

Allows non-builtin attributes in inner attribute position.

The tracking issue for this feature is: #54726

# `custom_mir`

Allows writing custom MIR

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `custom_test_frameworks`

The tracking issue for this feature is: #50297

The `custom_test_frameworks` feature allows the use of `#[test_case]` and `#![test_runner]`. Any function, const, or static can be annotated with `#[test_case]` causing it to be aggregated (like `#[test]`) and be passed to the test runner determined by the `#![test_runner]` crate attribute.

    #![allow(unused)]
    #![feature(custom_test_frameworks)]
    #![test_runner(my_runner)]

    fn main() {
    fn my_runner(tests: &[&i32]) {
        for t in tests {
            if **t == 0 {
                println!("PASSED");
            } else {
                println!("FAILED");
            }
        }
    }

    #[test_case]
    const WILL_PASS: i32 = 0;

    #[test_case]
    const WILL_FAIL: i32 = 4;
    }

# `decl_macro`

Allows declarative macros 2.0 (`macro`).

The tracking issue for this feature is: #39412

# `default_field_values`

The tracking issue for this feature is: #132162

The RFC for this feature is: #3681

The `default_field_values` feature allows users to specify a const value for individual fields in struct definitions, allowing those to be omitted from initializers.

## Examples

    #![feature(default_field_values)]

    #[derive(Default)]
    struct Pet {
        name: Option<String>, // impl Default for Pet will use Default::default() for name
        age: i128 = 42, // impl Default for Pet will use the literal 42 for age
    }

    fn main() {
        let a = Pet { name: Some(String::new()), .. }; // Pet { name: Some(""), age: 42 }
        let b = Pet::default(); // Pet { name: None, age: 42 }
        assert_eq!(a.age, b.age);
        // The following would be a compilation error: `name` needs to be specified
        // let _ = Pet { .. };
    }

## `#[derive(Default)]`

When deriving Default, the provided values are then used. On enum variants, the variant must still be marked with `#[default]` and have all its fields with default values.

    #![allow(unused)]
    #![feature(default_field_values)]

    fn main() {
    #[derive(Default)]
    enum A {
        #[default]
        B {
            x: i32 = 0,
            y: i32 = 0,
        },
        C,
    }
    }

## Enum variants

This feature also supports enum variants for both specifying default values and `#[derive(Default)]`.

## Interaction with `#[non_exhaustive]`

A struct or enum variant marked with `#[non_exhaustive]` is not allowed to have default field values.

## Lints

When manually implementing the `Default` trait for a type that has default field values, if any of these are overridden in the impl the `default_overrides_default_fields` lint will trigger. This lint is in place to avoid surprising diverging behavior between `S { .. }` and `S::default()`, where using the same type in both ways could result in different values. The appropriate way to write a manual `Default` implementation is to use the functional update syntax:

    #![allow(unused)]
    #![feature(default_field_values)]

    fn main() {
    struct Pet {
        name: String,
        age: i128 = 42, // impl Default for Pet will use the literal 42 for age
    }

    impl Default for Pet {
        fn default() -> Pet {
            Pet {
                name: "no-name".to_string(),
                ..
            }
        }
    }
    }

# `deprecated_safe`

Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait

The tracking issue for this feature is: #94978

# `deprecated_suggestion`

Allows having using `suggestion` in the `#[deprecated]` attribute.

The tracking issue for this feature is: #94785

# `deref_patterns`

The tracking issue for this feature is: #87121

> Note: This feature is incomplete. In the future, it is meant to supersede `box_patterns`.

This feature permits pattern matching on smart pointers in the standard library through their `Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which is currently a placeholder).

    #![allow(unused)]
    #![feature(deref_patterns)]
    #![allow(incomplete_features)]

    fn main() {
    let mut v = vec![Box::new(Some(0))];

    // Implicit dereferences are inserted when a pattern can match against the
    // result of repeatedly dereferencing but can't match against a smart
    // pointer itself. This works alongside match ergonomics for references.
    if let [Some(x)] = &mut v {
        *x += 1;
    }

    // Explicit `deref!(_)` patterns may instead be used when finer control is
    // needed, e.g. to dereference only a single smart pointer, or to bind the
    // the result of dereferencing to a variable.
    if let deref!([deref!(opt_x @ Some(1))]) = &mut v {
        opt_x.as_mut().map(|x| *x += 1);
    }

    assert_eq!(v, [Box::new(Some(2))]);
    }

Without this feature, it may be necessary to introduce temporaries to represent dereferenced places when matching on nested structures:

    #![allow(unused)]
    fn main() {
    let mut v = vec![Box::new(Some(0))];
    if let [b] = &mut *v {
        if let Some(x) = &mut **b {
            *x += 1;
        }
    }
    if let [b] = &mut *v {
        if let opt_x @ Some(1) = &mut **b {
            opt_x.as_mut().map(|x| *x += 1);
        }
    }
    assert_eq!(v, [Box::new(Some(2))]);
    }

Like `box_patterns`, deref patterns may move out of boxes:

    #![allow(unused)]
    fn main() {
    #![feature(deref_patterns)]
    #![allow(incomplete_features)]
    struct NoCopy;
    let deref!(x) = Box::new(NoCopy);
    drop::<NoCopy>(x);
    }

Additionally, `deref_patterns` implements changes to string and byte string literal patterns, allowing then to be used in deref patterns:

    #![allow(unused)]
    fn main() {
    #![feature(deref_patterns)]
    #![allow(incomplete_features)]
    match ("test".to_string(), Box::from("test"), b"test".to_vec()) {
        ("test", "test", b"test") => {}
        _ => panic!(),
    }

    // This works through multiple layers of reference and smart pointer:
    match (&Box::new(&"test".to_string()), &&&"test") {
        ("test", "test") => {}
        _ => panic!(),
    }

    // `deref!("...")` syntax may also be used:
    match "test".to_string() {
        deref!("test") => {}
        _ => panic!(),
    }

    // Matching on slices and arrays using literals is possible elsewhere as well:
    match *"test" {
        "test" => {}
        _ => panic!(),
    }
    match *b"test" {
        b"test" => {}
        _ => panic!(),
    }
    match *(b"test" as &[u8]) {
        b"test" => {}
        _ => panic!(),
    }
    }

# `derive_from`

Allows deriving the From trait on single-field structs.

The tracking issue for this feature is: #144889

# `diagnostic_on_const`

Allows giving non-const impls custom diagnostic messages if attempted to be used as const

The tracking issue for this feature is: #143874

# `doc_cfg`

The tracking issue for this feature is: #43781

The `doc_cfg` feature allows an API be documented as only available in some specific platforms. This attribute has two effects:

1. In the annotated item’s documentation, there will be a message saying “Available on (platform) only”.

2. The item’s doc-tests will only run on the specific platform.

In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your crate.

This feature was introduced as part of PR #43348 to allow the platform-specific parts of the standard library be documented.

    #![allow(unused)]
    #![feature(doc_cfg)]

    fn main() {
    #[cfg(any(windows, doc))]
    #[doc(cfg(windows))]
    /// The application's icon in the notification area (a.k.a. system tray).
    ///
    /// # Examples
    ///
    /// ```no_run
    /// extern crate my_awesome_ui_library;
    /// use my_awesome_ui_library::current_app;
    /// use my_awesome_ui_library::windows::notification;
    ///
    /// let icon = current_app().get::<notification::Icon>();
    /// icon.show();
    /// icon.show_message("Hello");
    /// ```
    pub struct Icon {
        // ...
    }
    }

# `doc_masked`

The tracking issue for this feature is: #44027

The `doc_masked` feature allows a crate to exclude types from a given crate from appearing in lists of trait implementations. The specifics of the feature are as follows:

1. When rustdoc encounters an `extern crate` statement annotated with a `#[doc(masked)]` attribute, it marks the crate as being masked.

2. When listing traits a given type implements, rustdoc ensures that traits from masked crates are not emitted into the documentation.

3. When listing types that implement a given trait, rustdoc ensures that types from masked crates are not emitted into the documentation.

This feature was introduced in PR #44026 to ensure that compiler-internal and implementation-specific types and traits were not included in the standard library’s documentation. Such types would introduce broken links into the documentation.

# `doc_notable_trait`

The tracking issue for this feature is: #45040

The `doc_notable_trait` feature allows the use of the `#[doc(notable_trait)]` attribute, which will display the trait in a “Notable traits” dialog for functions returning types that implement the trait. For example, this attribute is applied to the `Iterator`, `Future`, `io::Read`, and `io::Write` traits in the standard library.

You can do this on your own traits like so:

    #![feature(doc_notable_trait)]

    #[doc(notable_trait)]
    pub trait MyTrait {}

    pub struct MyStruct;
    impl MyTrait for MyStruct {}

    /// The docs for this function will have a button that displays a dialog about
    /// `MyStruct` implementing `MyTrait`.
    pub fn my_fn() -> MyStruct { MyStruct }

This feature was originally implemented in PR #45039.

See also its documentation in the rustdoc book.

# `dropck_eyepatch`

Allows using the `may_dangle` attribute (RFC 1327).

The tracking issue for this feature is: #34761

# `effective_target_features`

Allows features to allow target_feature to better interact with traits.

The tracking issue for this feature is: #143352

# `eii_internals`

Implementation details of externally implementable items

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `ergonomic_clones`

Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }`

The tracking issue for this feature is: #132290

# `ermsb_target_feature`

ermsb target feature on x86.

The tracking issue for this feature is: #150249

# `exhaustive_patterns`

Allows exhaustive pattern matching on types that contain uninhabited types.

The tracking issue for this feature is: #51085

# `explicit_extern_abis`

The tracking issue for this feature is: #134986

Disallow `extern` without an explicit ABI. We should write `extern "C"` (or another ABI) instead of just `extern`.

By making the ABI explicit, it becomes much clearer that “C” is just one of the possible choices, rather than the “standard” way for external functions. Removing the default makes it easier to add a new ABI on equal footing as “C”.

    #![allow(unused)]
    #![feature(explicit_extern_abis)]

    fn main() {
    extern fn function1() {}  // ERROR `extern` declarations without an explicit ABI
                              // are disallowed

    extern "C" fn function2() {} // compiles

    extern "aapcs" fn function3() {} // compiles
    }

# `explicit_tail_calls`

Allows explicit tail calls via `become` expression.

The tracking issue for this feature is: #112788

# `export_stable`

Allows using `#[export_stable]` which indicates that an item is exportable.

The tracking issue for this feature is: #139939

# `extern_item_impls`

Externally implementable items

The tracking issue for this feature is: #125418

# `extern_types`

Allows defining `extern type`s.

The tracking issue for this feature is: #43467

# `f128`

The tracking issue for this feature is: #116909

Enable the `f128` type for IEEE 128-bit floating numbers (quad precision).

# `f16`

The tracking issue for this feature is: #116909

Enable the `f16` type for IEEE 16-bit floating numbers (half precision).

# `ffi_const`

The tracking issue for this feature is: #58328

The `#[ffi_const]` attribute applies clang’s `const` attribute to foreign functions declarations.

That is, `#[ffi_const]` functions shall have no effects except for its return value, which can only depend on the values of the function parameters, and is not affected by changes to the observable state of the program.

Applying the `#[ffi_const]` attribute to a function that violates these requirements is undefined behaviour.

This attribute enables Rust to perform common optimizations, like sub-expression elimination, and it can avoid emitting some calls in repeated invocations of the function with the same argument values regardless of other operations being performed in between these functions calls (as opposed to `#[ffi_pure]` functions).

## Pitfalls

A `#[ffi_const]` function can only read global memory that would not affect its return value for the whole execution of the program (e.g. immutable global memory). `#[ffi_const]` functions are referentially-transparent and therefore more strict than `#[ffi_pure]` functions.

A common pitfall involves applying the `#[ffi_const]` attribute to a function that reads memory through pointer arguments which do not necessarily point to immutable global memory.

A `#[ffi_const]` function that returns unit has no effect on the abstract machine’s state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`.

A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a call to `abort`) nor by infinite loops.

When translating C headers to Rust FFI, it is worth verifying for which targets the `const` attribute is enabled in those headers, and using the appropriate `cfg` macros in the Rust side to match those definitions. While the semantics of `const` are implemented identically by many C and C++ compilers, e.g., clang, GCC, ARM C/C++ compiler, IBM ILE C/C++, etc. they are not necessarily implemented in this way on all of them. It is therefore also worth verifying that the semantics of the C toolchain used to compile the binary being linked against are compatible with those of the `#[ffi_const]`.

# `ffi_pure`

The tracking issue for this feature is: #58329

The `#[ffi_pure]` attribute applies clang’s `pure` attribute to foreign functions declarations.

That is, `#[ffi_pure]` functions shall have no effects except for its return value, which shall not change across two consecutive function calls with the same parameters.

Applying the `#[ffi_pure]` attribute to a function that violates these requirements is undefined behavior.

This attribute enables Rust to perform common optimizations, like sub-expression elimination and loop optimizations. Some common examples of pure functions are `strlen` or `memcmp`.

These optimizations are only applicable when the compiler can prove that no program state observable by the `#[ffi_pure]` function has changed between calls of the function, which could alter the result. See also the `#[ffi_const]` attribute, which provides stronger guarantees regarding the allowable behavior of a function, enabling further optimization.

## Pitfalls

A `#[ffi_pure]` function can read global memory through the function parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not referentially-transparent, and are therefore more relaxed than `#[ffi_const]` functions.

However, accessing global memory through volatile or atomic reads can violate the requirement that two consecutive function calls shall return the same value.

A `pure` function that returns unit has no effect on the abstract machine’s state.

A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a call to `abort`) nor by infinite loops.

When translating C headers to Rust FFI, it is worth verifying for which targets the `pure` attribute is enabled in those headers, and using the appropriate `cfg` macros in the Rust side to match those definitions. While the semantics of `pure` are implemented identically by many C and C++ compilers, e.g., clang, GCC, ARM C/C++ compiler, IBM ILE C/C++, etc. they are not necessarily implemented in this way on all of them. It is therefore also worth verifying that the semantics of the C toolchain used to compile the binary being linked against are compatible with those of the `#[ffi_pure]`.

# `fmt_debug`

Controlling the behavior of fmt::Debug

The tracking issue for this feature is: #129709

# `fn_align`

Allows using `#[align(...)]` on function items

The tracking issue for this feature is: #82232

# `fn_delegation`

Support delegating implementation of functions to other already implemented functions.

The tracking issue for this feature is: #118212

# `freeze_impls`

Allows impls for the Freeze trait.

The tracking issue for this feature is: #121675

# `frontmatter`

The tracking issue for this feature is: #136889

The `frontmatter` feature allows an extra metadata block at the top of files for consumption by external tools. For example, it can be used by `cargo-script` files to specify dependencies.

    #!/usr/bin/env -S cargo -Zscript
    ---
    [dependencies]
    libc = "0.2.172"
    ---
    #![feature(frontmatter)]
    mod libc { pub type c_int = i32; }

    fn main() {
        let x: libc::c_int = 1i32;
    }

# `fundamental`

Allows using the `#[fundamental]` attribute.

The tracking issue for this feature is: #29635

# `gen_blocks`

Allows defining gen blocks and `gen fn`.

The tracking issue for this feature is: #117078

# `generic_assert`

Outputs useful `assert!` messages

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `generic_const_exprs`

Allows non-trivial generic constants which have to have wfness manually propagated to callers

The tracking issue for this feature is: #76560

# `generic_const_items`

Allows generic parameters and where-clauses on free & associated const items.

The tracking issue for this feature is: #113521

# `generic_const_parameter_types`

Allows the type of const generics to depend on generic parameters

The tracking issue for this feature is: #137626

# `generic_pattern_types`

Allows any generic constants being used as pattern type range ends

The tracking issue for this feature is: #136574

# `global_registration`

Allows registering static items globally, possibly across crates, to iterate over at runtime.

The tracking issue for this feature is: #125119

# `guard_patterns`

Allows using guards in patterns.

The tracking issue for this feature is: #129967

# `half_open_range_patterns_in_slices`

The tracking issue for this feature is: #67264 It is a future part of the `exclusive_range_pattern` feature, tracked at #37854.

This feature allow using top-level half-open range patterns in slices.

    #![feature(half_open_range_patterns_in_slices)]

    fn main() {
        let xs = [13, 1, 5, 2, 3, 1, 21, 8];
        let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { return; };
    }

Note that this feature is not required if the patterns are wrapped between parenthesis.

    fn main() {
        let xs = [13, 1];
        let [(a @ 3..), c] = xs else { return; };
    }

# `hexagon_target_feature`

Target features on hexagon.

The tracking issue for this feature is: #150250

# `if_let_guard`

Allows `if let` guard in match arms.

The tracking issue for this feature is: #51114

# `impl_trait_in_assoc_type`

Allows `impl Trait` to be used inside associated types (RFC 2515).

The tracking issue for this feature is: #63063

# `impl_trait_in_bindings`

Allows `impl Trait` in bindings (`let`).

The tracking issue for this feature is: #63065

# `impl_trait_in_fn_trait_return`

Allows `impl Trait` as output type in `Fn` traits in return position of functions.

The tracking issue for this feature is: #99697

# import_trait_associated_functions

The tracking issue for this feature is: #134691

This feature allows importing associated functions and constants from traits and then using them like regular items.

    #![feature(import_trait_associated_functions)]

    use std::ops::Add::add;

    fn main() {
        let numbers = vec![1, 2, 3, 4, 5, 6];
        let sum = numbers.into_iter().reduce(add); // instead of `.reduce(Add:add)`

        assert_eq!(sum, Some(21));
    }

# `inherent_associated_types`

Allows associated types in inherent impls.

The tracking issue for this feature is: #8995

# `intra-doc-pointers`

The tracking issue for this feature is: #80896

Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and raw pointers in intra-doc links are unstable until it does.

    #![allow(unused)]
    #![feature(intra_doc_pointers)]
    fn main() {
    //! [pointer::add]
    }

# `intrinsics`

The tracking issue for this feature is: None.

Intrinsics are rarely intended to be stable directly, but are usually exported in some sort of stable manner. Prefer using the stable interfaces to the intrinsic directly when you can.

## Intrinsics with fallback logic

Many intrinsics can be written in pure rust, albeit inefficiently or without supporting some features that only exist on some backends. Backends can simply not implement those intrinsics without causing any code miscompilations or failures to compile. All intrinsic fallback bodies are automatically made cross-crate inlineable (like `#[inline]`) by the codegen backend, but not the MIR inliner.

    #![allow(unused)]
    #![feature(intrinsics)]
    #![allow(internal_features)]

    fn main() {
    #[rustc_intrinsic]
    const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
    }

Since these are just regular functions, it is perfectly ok to create the intrinsic twice:

    #![allow(unused)]
    #![feature(intrinsics)]
    #![allow(internal_features)]

    fn main() {
    #[rustc_intrinsic]
    const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}

    mod foo {
        #[rustc_intrinsic]
        const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {
            panic!("noisy const dealloc")
        }
    }

    }

The behaviour on backends that override the intrinsic is exactly the same. On other backends, the intrinsic behaviour depends on which implementation is called, just like with any regular function.

## Intrinsics lowered to MIR instructions

Various intrinsics have native MIR operations that they correspond to. Instead of requiring backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass will convert the calls to the MIR operation. Backends do not need to know about these intrinsics at all. These intrinsics only make sense without a body, and can be declared as a `#[rustc_intrinsic]`. The body is never used as the lowering pass implements support for all backends, so we never have to use the fallback logic.

## Intrinsics without fallback logic

These must be implemented by all backends.

### `#[rustc_intrinsic]` declarations

These are written without a body:

    #![allow(unused)]
    #![feature(intrinsics)]
    #![allow(internal_features)]

    fn main() {
    #[rustc_intrinsic]
    pub fn abort() -> !;
    }

# `lahfsahf_target_feature`

lahfsahf target feature on x86.

The tracking issue for this feature is: #150251

# `lang_items`

The tracking issue for this feature is: None.

The `rustc` compiler has certain pluggable operations, that is, functionality that isn’t hard-coded into the language, but is implemented in libraries, with a special marker to tell the compiler it exists. The marker is the attribute `#[lang = "..."]` and there are various different values of `...`, i.e. various different ‘lang items’. Most of them can only be defined once.

Lang items are loaded lazily by the compiler; e.g. if one never uses `Box` then there is no need to define a function for `exchange_malloc`. `rustc` will emit an error when an item is needed but not found in the current crate or any that it depends on.

Some features provided by lang items:

- overloadable operators via traits: the traits corresponding to the `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all marked with lang items; those specific four are `eq`, `partial_ord`, `deref`/`deref_mut`, and `add` respectively.
- panicking: the `panic` and `panic_impl` lang items, among others.
- stack unwinding: the lang item `eh_personality` is a function used by the failure mechanisms of the compiler. This is often mapped to GCC’s personality function (see the `std` implementation for more information), but programs which don’t trigger a panic can be assured that this function is never called. Additionally, a `eh_catch_typeinfo` static is needed for certain targets which implement Rust panics on top of C++ exceptions.
- the traits in `core::marker` used to indicate types of various kinds; e.g. lang items `sized`, `sync` and `copy`.
- memory allocation, see below.

Most lang items are defined by `core`, but if you’re trying to build an executable without the `std` crate, you might run into the need for lang item definitions.

## Example: Implementing a `Box`

`Box` pointers require two lang items: one for the type itself and one for allocation. A freestanding program that uses the `Box` sugar for dynamic allocations via `malloc` and `free`:

    #![feature(lang_items, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)]
    #![allow(internal_features)]
    #![no_std]
    #![no_main]

    extern crate libc;
    extern crate unwind;

    use core::ffi::{c_int, c_void};
    use core::intrinsics;
    use core::panic::PanicInfo;
    use core::ptr::NonNull;

    pub struct Global; // the global allocator
    struct Unique<T>(NonNull<T>);

    #[lang = "owned_box"]
    pub struct Box<T, A = Global>(Unique<T>, A);

    impl<T> Box<T> {
        pub fn new(x: T) -> Self {
            #[rustc_box]
            Box::new(x)
        }
    }

    impl<T, A> Drop for Box<T, A> {
        fn drop(&mut self) {
            unsafe {
                libc::free(self.0.0.as_ptr() as *mut c_void);
            }
        }
    }

    #[lang = "exchange_malloc"]
    unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
        let p = libc::malloc(size) as *mut u8;

        // Check if `malloc` failed:
        if p.is_null() {
            intrinsics::abort();
        }

        p
    }

    #[no_mangle]
    extern "C" fn main(_argc: c_int, _argv: *const *const u8) -> c_int {
        let _x = Box::new(1);

        0
    }

    #[lang = "eh_personality"]
    fn rust_eh_personality() {}

    #[panic_handler]
    fn panic_handler(_info: &PanicInfo) -> ! { intrinsics::abort() }

Note the use of `abort`: the `exchange_malloc` lang item is assumed to return a valid pointer, and so needs to do the check internally.

## List of all language items

An up-to-date list of all language items can be found here in the compiler code.

# `large_assignments`

Allows setting the threshold for the `large_assignments` lint.

The tracking issue for this feature is: #83518

# `lazy_type_alias`

Allow to have type alias types for inter-crate use.

The tracking issue for this feature is: #112792

# `link_arg_attribute`

The tracking issue for this feature is: #99427

The `link_arg_attribute` feature allows passing arguments into the linker from inside of the source code. Order is preserved for link attributes as they were defined on a single extern block:

    #![allow(unused)]
    #![feature(link_arg_attribute)]

    fn main() {
    #[link(kind = "link-arg", name = "--start-group")]
    #[link(kind = "static", name = "c")]
    #[link(kind = "static", name = "gcc")]
    #[link(kind = "link-arg", name = "--end-group")]
    extern "C" {}
    }

# `link_cfg`

This feature is internal to the Rust compiler and is not intended for general use.

# `link_llvm_intrinsics`

Allows using `#[link_name="llvm.*"]`.

The tracking issue for this feature is: #29602

# `linkage`

Allows using the `#[linkage = ".."]` attribute.

The tracking issue for this feature is: #29603

# `loongarch_target_feature`

Target features on loongarch.

The tracking issue for this feature is: #150252

# `loop_match`

The tracking issue for this feature is: #132306

The `#[loop_match]` and `#[const_continue]` attributes can be used to improve the code generation of logic that fits this shape:

    loop {
        state = 'blk: {
            match state {
                State::A => {
                    break 'blk State::B
                }
                State::B => { /* ... */ }
                /* ... */
            }
        }
    }

Here the loop itself can be annotated with `#[loop_match]`, and any `break 'blk` with `#[const_continue]` if the value is know at compile time:

    #[loop_match]
    loop {
        state = 'blk: {
            match state {
                State::A => {
                    #[const_continue]
                    break 'blk State::B
                }
                State::B => { /* ... */ }
                /* ... */
            }
        }
    }

The observable behavior of this loop is exactly the same as without the extra attributes. The difference is in the generated output: normally, when the state is `A`, control flow moves from the `A` branch, back to the top of the loop, then to the `B` branch. With the attributes, The `A` branch will immediately jump to the `B` branch.

Removing the indirection can be beneficial for stack usage and branch prediction, and enables other optimizations by clearly splitting out the control flow paths that your program will actually use.

# `m68k_target_feature`

Target features on m68k.

The tracking issue for this feature is: #134328

# `macro_attr`

Allow `macro_rules!` attribute rules

The tracking issue for this feature is: #143547

# `macro_derive`

Allow `macro_rules!` derive rules

The tracking issue for this feature is: #143549

# `macro_metavar_expr`

The tracking issue for this feature is: #83527

> This feature is not to be confused with `macro_metavar_expr_concat`.

# `macro_metavar_expr_concat`

The tracking issue for this feature is: #124225

In stable Rust, there is no way to create new identifiers by joining identifiers to literals or other identifiers without using procedural macros such as `paste`. `#![feature(macro_metavar_expr_concat)]` introduces a way to do this, using the concat metavariable expression.

> This feature uses the syntax from `macro_metavar_expr` but is otherwise independent. It replaces the since-removed unstable feature `concat_idents`.

> This is an experimental feature; it and its syntax will require a RFC before stabilization.

### Overview

`#![feature(macro_metavar_expr_concat)]` provides the `concat` metavariable expression for creating new identifiers:

    #![allow(unused)]
    #![feature(macro_metavar_expr_concat)]

    fn main() {
    macro_rules! create_some_structs {
        ($name:ident) => {
            pub struct ${ concat(First, $name) };
            pub struct ${ concat(Second, $name) };
            pub struct ${ concat(Third, $name) };
        }
    }

    create_some_structs!(Thing);
    }

This macro invocation expands to:

    #![allow(unused)]
    fn main() {
    pub struct FirstThing;
    pub struct SecondThing;
    pub struct ThirdThing;
    }

### Syntax

This feature builds upon the metavariable expression syntax `${ .. }` as specified in RFC 3086 (`macro_metavar_expr`). `concat` is available like `${ concat(items) }`, where `items` is a comma separated sequence of idents and/or literals.

### Examples

#### Create a function or method with a concatenated name

    #![allow(unused)]
    #![feature(macro_metavar_expr_concat)]

    fn main() {
    macro_rules! make_getter {
        ($name:ident, $field: ident, $ret:ty) => {
            impl $name {
                pub fn ${ concat(get_, $field) }(&self) -> &$ret {
                    &self.$field
                }
            }
        }
    }

    pub struct Thing {
        description: String,
    }

    make_getter!(Thing, description, String);
    }

This expands to:

    #![allow(unused)]
    fn main() {
    pub struct Thing {
        description: String,
    }

    impl Thing {
        pub fn get_description(&self) -> &String {
            &self.description
        }
    }
    }

#### Create names for macro generated tests

    #![allow(unused)]
    #![feature(macro_metavar_expr_concat)]

    fn main() {
    macro_rules! test_math {
        ($integer:ident) => {
            #[test]
            fn ${ concat(test_, $integer, _, addition) } () {
                let a: $integer = 73;
                let b: $integer = 42;
                assert_eq!(a + b, 115)
            }

            #[test]
            fn ${ concat(test_, $integer, _, subtraction) } () {
                let a: $integer = 73;
                let b: $integer = 42;
                assert_eq!(a - b, 31)
            }
        }
    }

    test_math!(i32);
    test_math!(u64);
    test_math!(u128);
    }

Running this returns the following output:

    running 6 tests
    test test_i32_subtraction ... ok
    test test_i32_addition ... ok
    test test_u128_addition ... ok
    test test_u128_subtraction ... ok
    test test_u64_addition ... ok
    test test_u64_subtraction ... ok

    test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

# `marker_trait_attr`

The tracking issue for this feature is: #29864

Normally, Rust keeps you from adding trait implementations that could overlap with each other, as it would be ambiguous which to use. This feature, however, carves out an exception to that rule: a trait can opt-in to having overlapping implementations, at the cost that those implementations are not allowed to override anything (and thus the trait itself cannot have any associated items, as they’re pointless when they’d need to do the same thing for every type anyway).

    #![allow(unused)]
    #![feature(marker_trait_attr)]

    fn main() {
    #[marker] trait CheapToClone: Clone {}

    impl<T: Copy> CheapToClone for T {}

    // These could potentially overlap with the blanket implementation above,
    // so are only allowed because CheapToClone is a marker trait.
    impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
    impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}

    fn cheap_clone<T: CheapToClone>(t: T) -> T {
        t.clone()
    }
    }

This is expected to replace the unstable `overlapping_marker_traits` feature, which applied to all empty traits (without needing an opt-in).

# `min_generic_const_args`

Enables the generic const args MVP (only bare paths, not arbitrary computation).

The tracking issue for this feature is: #132980

# `min_specialization`

A minimal, sound subset of specialization intended to be used by the standard library until the soundness issues with specialization are fixed.

The tracking issue for this feature is: #31844

# `mips_target_feature`

Target features on mips.

The tracking issue for this feature is: #150253

# `more_maybe_bounds`

Allows using `?Trait` trait bounds in more contexts.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `more_qualified_paths`

The `more_qualified_paths` feature can be used in order to enable the use of qualified paths in patterns.

The tracking issue for this feature is: #86935.

## Example

    #![feature(more_qualified_paths)]

    fn main() {
        // destructure through a qualified path
        let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
    }

    struct StructStruct {
        br: i8,
    }

    struct Foo;

    trait A {
        type Assoc;
    }

    impl A for Foo {
        type Assoc = StructStruct;
    }

# `movrs_target_feature`

The `movrs` target feature on x86.

The tracking issue for this feature is: #137976

# `multiple_supertrait_upcastable`

Allows the `multiple_supertrait_upcastable` lint.

The tracking issue for this feature is: #150833

# `must_not_suspend`

Allows the `#[must_not_suspend]` attribute.

The tracking issue for this feature is: #83310

# `mut_ref`

Allows `mut ref` and `mut ref mut` identifier patterns.

The tracking issue for this feature is: #123076

# `naked_functions_rustic_abi`

Allows using `#[naked]` on `extern "Rust"` functions.

The tracking issue for this feature is: #138997

# `naked_functions_target_feature`

Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions.

The tracking issue for this feature is: #138568

# `native_link_modifiers_as_needed`

The tracking issue for this feature is: #81490

The `native_link_modifiers_as_needed` feature allows you to use the `as-needed` modifier.

`as-needed` is only compatible with the `dynamic` and `framework` linking kinds. Using any other kind will result in a compiler error.

`+as-needed` means that the library will be actually linked only if it satisfies some undefined symbols at the point at which it is specified on the command line, making it similar to static libraries in this regard.

This modifier translates to `--as-needed` for ld-like linkers, and to `-dead_strip_dylibs` / `-needed_library` / `-needed_framework` for ld64. The modifier does nothing for linkers that don’t support it (e.g. `link.exe`).

The default for this modifier is unclear, some targets currently specify it as `+as-needed`, some do not. We may want to try making `+as-needed` a default for all targets.

# `needs_panic_runtime`

Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.

The tracking issue for this feature is: #32837

# `negative_bounds`

Allow negative trait bounds. This is an internal-only feature for testing the trait solver!

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `negative_impls`

The tracking issue for this feature is #68318.

With the feature gate `negative_impls`, you can write negative impls as well as positive ones:

    #![allow(unused)]
    #![feature(negative_impls)]
    fn main() {
    trait DerefMut { }
    impl<T: ?Sized> !DerefMut for &T { }
    }

Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below.

Negative impls have the following characteristics:

- They do not have any items.
- They must obey the orphan rules as if they were a positive impl.
- They cannot “overlap” with any positive impls.

## Semver interaction

It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.

## Orphan and overlap rules

Negative impls must obey the same orphan rules as a positive impl. This implies you cannot add a negative impl for types defined in upstream crates and so forth.

Similarly, negative impls cannot overlap with positive impls, again using the same “overlap” check that we ordinarily use to determine if two impls overlap. (Note that positive impls typically cannot overlap with one another either, except as permitted by specialization.)

## Interaction with auto traits

Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an auto-trait serves two purposes:

- as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
- it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.

Note that, at present, there is no way to indicate that a given type does not implement an auto trait but that it may do so in the future. For ordinary types, this is done by simply not declaring any impl at all, but that is not an option for auto traits. A workaround is that one could embed a marker type as one of the fields, where the marker type is `!AutoTrait`.

## Immediate uses

Negative impls are used to declare that `&T: !DerefMut` and `&mut T: !Clone`, as required to fix the soundness of `Pin` described in #66544.

This serves two purposes:

- For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
- It prevents downstream crates from creating such impls.

# `never_patterns`

Allows the `!` pattern.

The tracking issue for this feature is: #118155

# `never_type`

Allows the `!` type. Does not imply ‘exhaustive_patterns’ (below) any more.

The tracking issue for this feature is: #35121

# `new_range`

The tracking issue for this feature is: #123741

Switch the syntaxes `a..`, `a..b`, and `a..=b` to resolve the new range types.

# `no_core`

Allows `#![no_core]`.

The tracking issue for this feature is: #29639

# `non_exhaustive_omitted_patterns_lint`

Allows using the `non_exhaustive_omitted_patterns` lint.

The tracking issue for this feature is: #89554

# `non_lifetime_binders`

Allows `for<T>` binders in where-clauses

The tracking issue for this feature is: #108185

# `nvptx_target_feature`

Target feaures on nvptx.

The tracking issue for this feature is: #150254

# `offset_of_enum`

The tracking issue for this feature is: #120141

When the `offset_of_enum` feature is enabled, the `offset_of!` macro may be used to obtain the offsets of fields of `enum`s; to express this, `enum` variants may be traversed as if they were fields. Variants themselves do not have an offset, so they cannot appear as the last path component.

    #![allow(unused)]
    #![feature(offset_of_enum)]
    fn main() {
    use std::mem;

    #[repr(u8)]
    enum Enum {
        A(u8, u16),
        B { one: u8, two: u16 },
    }

    assert_eq!(mem::offset_of!(Enum, A.0), 1);
    assert_eq!(mem::offset_of!(Enum, B.two), 2);

    assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
    }

# `offset_of_slice`

The tracking issue for this feature is: #126151

When the `offset_of_slice` feature is enabled, the `offset_of!` macro may be used to determine the offset of fields whose type is `[T]`, that is, a slice of dynamic size.

In general, fields whose type is dynamically sized do not have statically known offsets because they do not have statically known alignments. However, `[T]` has the same alignment as `T`, so it specifically may be allowed.

    #![feature(offset_of_slice)]

    #[repr(C)]
    pub struct Struct {
        head: u32,
        tail: [u8],
    }

    fn main() {
        assert_eq!(std::mem::offset_of!(Struct, tail), 4);
    }

# `optimize_attribute`

Allows using `#[optimize(X)]`.

The tracking issue for this feature is: #54882

# `panic_runtime`

Allows using the `#![panic_runtime]` attribute.

The tracking issue for this feature is: #32837

# `patchable_function_entry`

Allows specifying nop padding on functions for dynamic patching.

The tracking issue for this feature is: #123115

# `pattern_complexity_limit`

Set the maximum pattern complexity allowed (not limited by default).

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `pattern_types`

Allows using pattern types.

The tracking issue for this feature is: #123646

# `pin_ergonomics`

Experimental features that make `Pin` more ergonomic.

The tracking issue for this feature is: #130494

# `postfix-match`

`postfix-match` adds the feature for matching upon values postfix the expressions that generate the values.

The tracking issue for this feature is: #121618.

    #![allow(unused)]
    #![feature(postfix_match)]

    fn main() {
    enum Foo {
        Bar,
        Baz
    }

    fn get_foo() -> Foo {
        Foo::Bar
    }

    get_foo().match {
        Foo::Bar => {},
        Foo::Baz => panic!(),
    }
    }

# `powerpc_target_feature`

Target features on powerpc.

The tracking issue for this feature is: #150255

# `prelude_import`

Allows using `#[prelude_import]` on glob `use` items.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `prfchw_target_feature`

The prfchw target feature on x86.

The tracking issue for this feature is: #150256

# `proc_macro_hygiene`

Allows macro attributes on expressions, statements and non-inline modules.

The tracking issue for this feature is: #54727

# `profiler_runtime`

The tracking issue for this feature is: #42524.

# `raw_dylib_elf`

Allows the use of raw-dylibs on ELF platforms

The tracking issue for this feature is: #135694

# `reborrow`

The tracking issue for this feature is: #145612

# `ref_pat_eat_one_layer_2024`

The tracking issue for this feature is: #123076

This feature is incomplete and not yet intended for general use.

This implements experimental, Edition-dependent match ergonomics under consideration for inclusion in Rust, allowing `&` patterns in more places. For example:

    #![allow(unused)]
    #![feature(ref_pat_eat_one_layer_2024)]
    #![allow(incomplete_features)]
    fn main() {

    // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`.
    trait Eq<T> {}
    impl<T> Eq<T> for T {}
    fn has_type<T>(_: impl Eq<T>) {}

    // `&` can match against a `ref` binding mode instead of a reference type:
    let (x, &y) = &(0, 1);
    has_type::<&u8>(x);
    has_type::<u8>(y);

    // `&` can match against `&mut` references:
    let &z = &mut 2;
    has_type::<u8>(z);
    }

For specifics, see the corresponding typing rules for Editions 2021 and earlier and for Editions 2024 and later. For more information on binding modes, see The Rust Reference.

For alternative experimental match ergonomics, see the feature `ref_pat_eat_one_layer_2024_structural`.

# `ref_pat_eat_one_layer_2024_structural`

The tracking issue for this feature is: #123076

This feature is incomplete and not yet intended for general use.

This implements experimental, Edition-dependent match ergonomics under consideration for inclusion in Rust, allowing `&` patterns in more places. For example:

    #![allow(unused)]
    #![feature(ref_pat_eat_one_layer_2024_structural)]
    #![allow(incomplete_features)]
    fn main() {

    // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`.
    trait Eq<T> {}
    impl<T> Eq<T> for T {}
    fn has_type<T>(_: impl Eq<T>) {}

    // `&` can match against a `ref` binding mode instead of a reference type:
    let (x, &y) = &(0, 1);
    has_type::<&u8>(x);
    has_type::<u8>(y);

    // `&` can match against `&mut` references:
    let &z = &mut 2;
    has_type::<u8>(z);
    }

For specifics, see the corresponding typing rules for Editions 2021 and earlier and for Editions 2024 and later. For more information on binding modes, see The Rust Reference.

For alternative experimental match ergonomics, see the feature `ref_pat_eat_one_layer_2024`.

# `register_tool`

The tracking issue for this feature is: #66079

The `register_tool` language feature informs the compiler that attributes in your code are meant to be used with tools other than the compiler itself. This can be useful if your code has semantic meaning without the external tool, but enables additional features when the tool is present.

`register_tool` also allows configuring lint levels for external tools.

Tool attributes are only meant for ignorable attributes. If your code changes meaning when the attribute is present, it should not use a tool attribute (because it cannot be compiled with anything other than the external tool, and in a sense is a fork of the language).

`#![register_tool(tool)]` is an attribute, and is only valid at the crate root. Attributes using the registered tool are checked for valid syntax, and lint attributes are checked to be in a valid format. However, the compiler cannot validate the semantics of the attribute, nor can it tell whether the configured lint is present in the external tool.

Semantically, `clippy::*`, `rustdoc::*`, and `rustfmt::*` lints and attributes all behave as if `#![register_tool(clippy, rustdoc, rustfmt)]` were injected into the crate root, except that the `rustdoc` namespace can only be used for lints, not for attributes. When compiling with `-Z unstable-features`, `rustc::*` lints can also be used. Like `rustdoc`, the `rustc` namespace can only be used with lints, not attributes.

The compiler will emit an error if it encounters a lint/attribute whose namespace isn’t a registered tool.

Tool namespaces cannot be nested; `register_tool(main_tool::subtool)` is an error.

## Examples

Tool attributes:

    #![allow(unused)]
    #![feature(register_tool)]
    #![register_tool(c2rust)]

    fn main() {
    // Mark which C header file this module was generated from.
    #[c2rust::header_src = "operations.h"]
    pub mod operations_h {
        use std::ffi::c_int;

        // Mark which source line this struct was generated from.
        #[c2rust::src_loc = "11:0"]
        pub struct Point {
            pub x: c_int,
            pub y: c_int,
        }
    }
    }

Tool lints:

    #![feature(register_tool)]
    #![register_tool(bevy)]
    #![deny(bevy::duplicate_bevy_dependencies)]

# `repr_simd`

Allows `repr(simd)` and importing the various simd intrinsics.

The tracking issue for this feature is: #27731

# `return_type_notation`

Allows bounding the return type of AFIT/RPITIT.

The tracking issue for this feature is: #109417

# `riscv_target_feature`

Target features on riscv.

The tracking issue for this feature is: #150257

# `rtm_target_feature`

The rtm target feature on x86.

The tracking issue for this feature is: #150258

# `rust_cold_cc`

Allows `extern "rust-cold"`.

The tracking issue for this feature is: #97544

# `rustc_allow_const_fn_unstable`

Allows using `#[rustc_allow_const_fn_unstable]`. This is an attribute on `const fn` for the same purpose as `#[allow_internal_unstable]`.

The tracking issue for this feature is: #69399

# `rustc_attrs`

This feature has no tracking issue, and is therefore internal to the compiler, not being intended for general use.

Note: `rustc_attrs` enables many rustc-internal attributes and this page only discuss a few of them.

The `rustc_attrs` feature allows debugging rustc type layouts by using `#[rustc_layout(...)]` to debug layout at compile time (it even works with `cargo check`) as an alternative to `rustc -Z print-type-sizes` that is way more verbose.

Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`, `abi`. Note that it only works on sized types without generics.

## Examples

    #![allow(unused)]
    #![feature(rustc_attrs)]

    fn main() {
    #[rustc_layout(abi, size)]
    pub enum X {
        Y(u8, u8, u8),
        Z(isize),
    }
    }

When that is compiled, the compiler will error with something like

    error: abi: Aggregate { sized: true }
     --> src/lib.rs:4:1
      |
    4 | / pub enum T {
    5 | |     Y(u8, u8, u8),
    6 | |     Z(isize),
    7 | | }
      | |_^

    error: size: Size { raw: 16 }
     --> src/lib.rs:4:1
      |
    4 | / pub enum T {
    5 | |     Y(u8, u8, u8),
    6 | |     Z(isize),
    7 | | }
      | |_^

    error: aborting due to 2 previous errors

# `rustc_private`

The tracking issue for this feature is: #27812

This feature allows access to unstable internal compiler crates such as `rustc_driver`.

The presence of this feature changes the way the linkage format for dylibs is calculated in a way that is necessary for linking against dylibs that statically link `std` (such as `rustc_driver`). This makes this feature “viral” in linkage; its use in a given crate makes its use required in dependent crates which link to it (including integration tests, which are built as separate crates).

## Common linker failures related to missing LLVM libraries

### When using `rustc-private` with Official Toolchains

When using the `rustc_private` feature with official toolchains distributed via rustup, you’ll need to install:

1. The `rustc-dev` component (provides compiler libraries)
2. The `llvm-tools` component (provides LLVM libraries needed for linking)

You can install these components using `rustup`:

    rustup component add rustc-dev llvm-tools

Without the `llvm-tools` component, you may encounter linking errors like:

    error: linking with `cc` failed: exit status: 1
      |
      = note: rust-lld: error: unable to find library -lLLVM-{version}

### When using `rustc-private` with Custom Toolchains

For custom-built toolchains or environments not using rustup, different configuration may be required:

- Ensure LLVM libraries are available in your library search paths
- You might need to configure library paths explicitly depending on your LLVM installation

# `rustdoc_internals`

Allows using internal rustdoc features like `doc(keyword)`.

The tracking issue for this feature is: #90418

# `rustdoc_missing_doc_code_examples`

Allows using the `rustdoc::missing_doc_code_examples` lint

The tracking issue for this feature is: #101730

# `s390x_target_feature`

Target features on s390x.

The tracking issue for this feature is: #150259

# `sanitize`

The tracking issue for this feature is: #39699

The `sanitize` attribute can be used to selectively disable or enable sanitizer instrumentation in an annotated function. This might be useful to: avoid instrumentation overhead in a performance critical function, or avoid instrumenting code that contains constructs unsupported by given sanitizer.

The precise effect of this annotation depends on particular sanitizer in use. For example, with `sanitize(thread = "off")`, the thread sanitizer will no longer instrument non-atomic store / load operations, but it will instrument atomic operations to avoid reporting false positives and provide meaning full stack traces.

This attribute was previously named `no_sanitize`.

## Examples

    #![allow(unused)]
    #![feature(sanitize)]

    fn main() {
    #[sanitize(address = "off")]
    fn foo() {
      // ...
    }
    }

It is also possible to disable sanitizers for entire modules and enable them for single items or functions.

    #![allow(unused)]
    #![feature(sanitize)]

    fn main() {
    #[sanitize(address = "off")]
    mod foo {
      fn unsanitized() {
        // ...
      }

      #[sanitize(address = "on")]
      fn sanitized() {
        // ...
      }
    }
    }

It’s also applicable to impl blocks.

    #![allow(unused)]
    #![feature(sanitize)]

    fn main() {
    trait MyTrait {
      fn foo(&self);
      fn bar(&self);
    }

    #[sanitize(address = "off")]
    impl MyTrait for () {
      fn foo(&self) {
        // ...
      }

      #[sanitize(address = "on")]
      fn bar(&self) {
        // ...
      }
    }
    }

# `simd_ffi`

Allows the use of SIMD types in functions declared in `extern` blocks.

The tracking issue for this feature is: #27731

# `sized_hierarchy`

Introduces a hierarchy of `Sized` traits (RFC 3729).

The tracking issue for this feature is: #144404

# `sparc_target_feature`

Target features on sparc.

The tracking issue for this feature is: #132783

# `specialization`

Allows specialization of implementations (RFC 1210).

The tracking issue for this feature is: #31844

# `staged_api`

Allows using the `#[stable]` and `#[unstable]` attributes.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `static_align`

Allows using `#[rustc_align_static(...)]` on static items.

The tracking issue for this feature is: #146177

# `stmt_expr_attributes`

Allows attributes on expressions and non-item statements.

The tracking issue for this feature is: #15701

# `strict_provenance_lints`

The tracking issue for this feature is: #130351

The `strict_provenance_lints` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints. These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model.

## Example

    #![feature(strict_provenance_lints)]
    #![warn(fuzzy_provenance_casts)]

    fn main() {
        let _dangling = 16_usize as *const u8;
        //~^ WARNING: strict provenance disallows casting integer `usize` to pointer `*const u8`
    }

# `structural_match`

Allows using `#[structural_match]` which indicates that a type is structurally matchable. FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library feature with the same name exists.

The tracking issue for this feature is: #31434

# `super_let`

Allows `super let` statements.

The tracking issue for this feature is: #139076

# `supertrait_item_shadowing`

Allows subtrait items to shadow supertrait items.

The tracking issue for this feature is: #89151

# `target_feature_inline_always`

Allows the use of target_feature when a function is marked inline(always).

The tracking issue for this feature is: #145574

# `test_unstable_lint`

Added for testing unstable lints; perma-unstable.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `thread_local`

Allows using `#[thread_local]` on `static` items.

The tracking issue for this feature is: #29594

# `trait_alias`

The tracking issue for this feature is: #41517

The `trait_alias` feature adds support for trait aliases. These allow aliases to be created for one or more traits (currently just a single regular trait plus any number of auto-traits), and used wherever traits would normally be used as either bounds or trait objects.

    #![feature(trait_alias)]

    trait Foo = std::fmt::Debug + Send;
    trait Bar = Foo + Sync;

    // Use trait alias as bound on type parameter.
    fn foo<T: Foo>(v: &T) {
        println!("{:?}", v);
    }

    pub fn main() {
        foo(&1);

        // Use trait alias for trait objects.
        let a: &Bar = &123;
        println!("{:?}", a);
        let b = Box::new(456) as Box<dyn Foo>;
        println!("{:?}", b);
    }

# `transmute_generic_consts`

Allows for transmuting between arrays with sizes that contain generic consts.

The tracking issue for this feature is: #109929

# `transparent_unions`

The tracking issue for this feature is #60405

The `transparent_unions` feature allows you mark `union`s as `#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the same conditions in which a `struct` may be `#[repr(transparent)]` (generally, this means the `union` must have exactly one non-zero-sized field). Some concrete illustrations follow.

    #![allow(unused)]
    #![feature(transparent_unions)]

    fn main() {
    // This union has the same representation as `f32`.
    #[repr(transparent)]
    union SingleFieldUnion {
        field: f32,
    }

    // This union has the same representation as `usize`.
    #[repr(transparent)]
    union MultiFieldUnion {
        field: usize,
        nothing: (),
    }
    }

For consistency with transparent `struct`s, `union`s must have exactly one non-zero-sized field. If all fields are zero-sized, the `union` must not be `#[repr(transparent)]`:

    #![allow(unused)]
    #![feature(transparent_unions)]

    fn main() {
    // This (non-transparent) union is already valid in stable Rust:
    pub union GoodUnion {
        pub nothing: (),
    }

    // Error: transparent union needs exactly one non-zero-sized field, but has 0
    // #[repr(transparent)]
    // pub union BadUnion {
    //     pub nothing: (),
    // }
    }

The one exception is if the `union` is generic over `T` and has a field of type `T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:

    #![allow(unused)]
    #![feature(transparent_unions)]

    fn main() {
    // This union has the same representation as `T`.
    #[repr(transparent)]
    pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
        pub field: T,
        pub nothing: (),
    }

    // This is okay even though `()` is a zero-sized type.
    pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
    }

Like transparent `struct`s, a transparent `union` of type `U` has the same layout, size, and ABI as its single non-ZST field. If it is generic over a type `T`, and all its fields are ZSTs except for exactly one field of type `T`, then it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).

Like transparent `struct`s, transparent `union`s are FFI-safe if and only if their underlying representation type is also FFI-safe.

A `union` may not be eligible for the same nonnull-style optimizations that a `struct` or `enum` (with the same fields) are eligible for. Adding `#[repr(transparent)]` to `union` does not change this. To give a more concrete example, it is unspecified whether `size_of::<T>()` is equal to `size_of::<Option<T>>()`, where `T` is a `union` (regardless of whether or not it is transparent). The Rust compiler is free to perform this optimization if possible, but is not required to, and different compiler versions may differ in their application of these optimizations.

# `trivial_bounds`

Allows inconsistent bounds in where clauses.

The tracking issue for this feature is: #48214

# `try_blocks`

The tracking issue for this feature is: #31436

The `try_blocks` feature adds support for `try` blocks. A `try` block creates a new scope one can use the `?` operator in.

    #![allow(unused)]
    #![feature(try_blocks)]

    fn main() {
    use std::num::ParseIntError;

    let result: Result<i32, ParseIntError> = try {
        "1".parse::<i32>()?
            + "2".parse::<i32>()?
            + "3".parse::<i32>()?
    };
    assert_eq!(result, Ok(6));

    let result: Result<i32, ParseIntError> = try {
        "1".parse::<i32>()?
            + "foo".parse::<i32>()?
            + "3".parse::<i32>()?
    };
    assert!(result.is_err());
    }

# `try_blocks_heterogeneous`

Allows using `try bikeshed TargetType {...}` expressions.

The tracking issue for this feature is: #149488

# `type_alias_impl_trait`

The tracking issue for this feature is: #63063

> This feature is not to be confused with `trait_alias` or `impl_trait_in_assoc_type`.

### What is `impl Trait`?

`impl Trait` in return position is useful for declaring types that are constrained by traits, but whose concrete type should be hidden:

    use std::fmt::Debug;

    fn new() -> impl Debug {
        42
    }

    fn main() {
        let thing = new();
        // What actually is a `thing`?
        // No idea but we know it implements `Debug`, so we can debug print it
        println!("{thing:?}");
    }

See the reference for more information about `impl Trait` in return position.

### `type_alias_impl_trait`

However, we might want to use an `impl Trait` in multiple locations but actually use the same concrete type everywhere while keeping it hidden. This can be useful in libraries where you want to hide implementation details.

The `#[define_opaque]` attribute must be used to explicitly list opaque items constrained by the item it’s on.

    #![feature(type_alias_impl_trait)]
    #![allow(unused_variables, dead_code)]
    trait Trait {}

    struct MyType;

    impl Trait for MyType {}

    type Alias = impl Trait;

    #[define_opaque(Alias)] // To constrain the type alias to `MyType`
    fn new() -> Alias {
        MyType
    }

    #[define_opaque(Alias)] // So we can name the concrete type inside this item
    fn main() {
        let thing: MyType = new();
    }

    // It can be a part of a struct too
    struct HaveAlias {
        stuff: String,
        thing: Alias,
    }

In this example, the concrete type referred to by `Alias` is guaranteed to be the same wherever `Alias` occurs.

> Originally this feature included type aliases as an associated type of a trait. In #110237 this was split off to `impl_trait_in_assoc_type`.

### `type_alias_impl_trait` in argument position.

Note that using `Alias` as an argument type is not the same as argument-position `impl Trait`, as `Alias` refers to a unique type, whereas the concrete type for argument-position `impl Trait` is chosen by the caller.

    #![feature(type_alias_impl_trait)]
    #![allow(unused_variables)]
    pub mod x {
    pub trait Trait {}

    struct MyType;

    impl Trait for MyType {}

    pub type Alias = impl Trait;

    #[define_opaque(Alias)]
    pub fn new() -> Alias {
        MyType
    }
    }
    use x::*;
    // this...
    pub fn take_alias(x: Alias) {
        // ...
    }

    // ...is *not* the same as
    pub fn take_impl(x: impl Trait) {
        // ...
    }
    fn main(){}

    #![feature(type_alias_impl_trait)]
    #![allow(unused_variables)]
    pub mod x {
    pub trait Trait {}

    struct MyType;

    impl Trait for MyType {}

    pub type Alias = impl Trait;

    #[define_opaque(Alias)]
    pub fn new() -> Alias {
        MyType
    }
    }
    use x::*;
    pub fn take_alias(x: Alias) {
        // ...
    }

    pub fn take_impl(x: impl Trait) {
       // ...
    }

    // a user's crate using the trait and type alias
    struct UserType;
    impl Trait for UserType {}

    fn main(){
    let x = UserType;
    take_alias(x);
    // ERROR expected opaque type, found `UserType`
    // this function *actually* takes a `MyType` as is constrained in `new`

    let x = UserType;
    take_impl(x);
    // OK

    let x = new();
    take_alias(x);
    // OK

    let x = new();
    take_impl(x);
    // OK
    }

Note that the user cannot use `#[define_opaque(Alias)]` to reify the opaque type because only the crate where the type alias is declared may do so. But if this happened in the same crate and the opaque type was reified, they’d get a familiar error: “expected `MyType`, got `UserType`”.

# `type_changing_struct_update`

The tracking issue for this feature is: #86555

This implements RFC2528. When turned on, you can create instances of the same struct that have different generic type or lifetime parameters.

    #![allow(unused_variables, dead_code)]
    #![feature(type_changing_struct_update)]

    fn main () {
        struct Foo<T, U> {
            field1: T,
            field2: U,
        }

        let base: Foo<String, i32> = Foo {
            field1: String::from("hello"),
            field2: 1234,
        };
        let updated: Foo<f64, i32> = Foo {
            field1: 3.14,
            ..base
        };
    }

# `unboxed_closures`

The tracking issue for this feature is #29625

See Also: `fn_traits`

The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI, required for implementing the `Fn*` family of traits. `"rust-call"` functions must have exactly one (non self) argument, a tuple representing the argument list.

    #![feature(unboxed_closures)]

    extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
        args.0 + args.1
    }

    fn main() {}

# `unqualified_local_imports`

Helps with formatting for `group_imports = "StdExternalCrate"`.

The tracking issue for this feature is: #138299

# `unsafe_binders`

Allows using `unsafe<'a> &'a T` unsafe binder types.

The tracking issue for this feature is: #130516

# `unsafe_fields`

Allows declaring fields `unsafe`.

The tracking issue for this feature is: #132922

# `unsized_const_params`

Allows const generic parameters to be defined with types that are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.

The tracking issue for this feature is: #95174

# `unsized_fn_params`

Allows unsized fn parameters.

The tracking issue for this feature is: #48055

# `used_with_arg`

Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.

The tracking issue for this feature is: #93798

# `wasm_target_feature`

Target features on wasm.

The tracking issue for this feature is: #150260

# `where_clause_attrs`

Allows use of attributes in `where` clauses.

The tracking issue for this feature is: #115590

# `with_negative_coherence`

Use for stable + negative coherence and strict coherence depending on trait’s rustc_strict_coherence value.

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `x86_amx_intrinsics`

Allows use of x86 `AMX` target-feature attributes and intrinsics

The tracking issue for this feature is: #126622

# `x87_target_feature`

The x87 target feature on x86.

The tracking issue for this feature is: #150261

# `xop_target_feature`

Allows use of the `xop` target-feature

The tracking issue for this feature is: #127208

# `yeet_expr`

The tracking issue for this feature is: #96373

The `yeet_expr` feature adds support for `do yeet` expressions, which can be used to early-exit from a function or `try` block.

These are highly experimental, thus the placeholder syntax.

    #![allow(unused)]
    #![feature(yeet_expr)]

    fn main() {
    fn foo() -> Result<String, i32> {
        do yeet 4;
    }
    assert_eq!(foo(), Err(4));

    fn bar() -> Option<String> {
        do yeet;
    }
    assert_eq!(bar(), None);
    }

# `yield_expr`

The tracking issue for this feature is: #43122

# Library Features

# `abort_unwind`

The tracking issue for this feature is: #130338

# `acceptfilter`

The tracking issue for this feature is: #121891

# `addr_parse_ascii`

The tracking issue for this feature is: #101035

# `align_to_uninit_mut`

The tracking issue for this feature is: #139062

# `alloc_error_hook`

The tracking issue for this feature is: #51245

# `alloc_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `alloc_layout_extra`

The tracking issue for this feature is: #55724

# `alloc_slice_into_array`

The tracking issue for this feature is: #148082

# `allocator_api`

The tracking issue for this feature is #32838

Sometimes you want the memory for one collection to use a different allocator than the memory for another collection. In this case, replacing the global allocator is not a workable option. Instead, you need to pass in an instance of an `AllocRef` to each collection for which you want a custom allocator.

TBD

# `alloctests`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `arc_is_unique`

The tracking issue for this feature is: #138938

# `array_into_iter_constructors`

The tracking issue for this feature is: #91583

# `array_ptr_get`

The tracking issue for this feature is: #119834

# `array_try_from_fn`

The tracking issue for this feature is: #89379

# `array_try_map`

The tracking issue for this feature is: #79711

# `ascii_char`

The tracking issue for this feature is: #110998

# `ascii_char_variants`

The tracking issue for this feature is: #110998

# `assert_matches`

The tracking issue for this feature is: #82775

# `async_fn_traits`

See Also: `fn_traits`

The `async_fn_traits` feature allows for implementation of the `AsyncFn*` traits for creating custom closure-like types that return futures.

The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFnMut::CallRefFuture` does).

# `async_gen_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `async_iter_from_iter`

The tracking issue for this feature is: #81798

# `async_iterator`

The tracking issue for this feature is: #79024

# `atomic_from_mut`

The tracking issue for this feature is: #76314

# `atomic_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `atomic_ptr_null`

The tracking issue for this feature is: #150733

# `atomic_try_update`

The tracking issue for this feature is: #135894

# `autodiff`

The tracking issue for this feature is: #124509

# `backtrace_frames`

The tracking issue for this feature is: #79676

# `bigint_helper_methods`

The tracking issue for this feature is: #85532

# `bikeshed_guaranteed_no_drop`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `binary_heap_drain_sorted`

The tracking issue for this feature is: #59278

# `binary_heap_into_iter_sorted`

The tracking issue for this feature is: #59278

# `binary_heap_peek_mut_refresh`

The tracking issue for this feature is: #138355

# `bool_to_result`

The tracking issue for this feature is: #142748

# `bound_as_ref`

The tracking issue for this feature is: #80996

# `bound_copied`

The tracking issue for this feature is: #145966

# `box_as_ptr`

The tracking issue for this feature is: #129090

# `box_into_boxed_slice`

The tracking issue for this feature is: #71582

# `box_into_inner`

The tracking issue for this feature is: #80437

# `box_take`

The tracking issue for this feature is: #147212

# `box_vec_non_null`

The tracking issue for this feature is: #130364

# `breakpoint`

The tracking issue for this feature is: #133724

# `bstr`

The tracking issue for this feature is: #134915

# `bstr_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `btree_cursors`

The tracking issue for this feature is: #107540

# `btree_set_entry`

The tracking issue for this feature is: #133549

# `btreemap_alloc`

The tracking issue for this feature is: #32838

# `buf_read_has_data_left`

The tracking issue for this feature is: #86423

# `bufreader_peek`

The tracking issue for this feature is: #128405

# `c_size_t`

The tracking issue for this feature is: #88345

# `c_void_variant`

This feature is internal to the Rust compiler and is not intended for general use.

# `can_vector`

The tracking issue for this feature is: #69941

# `cast_maybe_uninit`

The tracking issue for this feature is: #145036

# `cell_get_cloned`

The tracking issue for this feature is: #145329

# `cell_leak`

The tracking issue for this feature is: #69099

# `cfg_accessible`

The tracking issue for this feature is: #64797

# `cfg_eval`

The tracking issue for this feature is: #82679

# `cfg_select`

The tracking issue for this feature is: #115585

# `char_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `char_max_len`

The tracking issue for this feature is: #121714

# `clamp_magnitude`

The tracking issue for this feature is: #148519

# `clone_from_ref`

The tracking issue for this feature is: #149075

# `clone_to_uninit`

The tracking issue for this feature is: #126799

# `cmp_minmax`

The tracking issue for this feature is: #115939

# `coerce_pointee_validated`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `coerce_unsized`

The tracking issue for this feature is: #18598

# `cold_path`

The tracking issue for this feature is: #136873

# `command_resolved_envs`

The tracking issue for this feature is: #149070

# `concat_bytes`

The tracking issue for this feature is: #87555

# `const_alloc_error`

The tracking issue for this feature is: #92523

# `const_array`

The tracking issue for this feature is: #147606

# `const_btree_len`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `const_carrying_mul_add`

The tracking issue for this feature is: #85532

# `const_cell_traits`

The tracking issue for this feature is: #147787

# `const_clone`

The tracking issue for this feature is: #142757

# `const_cmp`

The tracking issue for this feature is: #143800

# `const_control_flow`

The tracking issue for this feature is: #148739

# `const_convert`

The tracking issue for this feature is: #143773

# `const_default`

The tracking issue for this feature is: #143894

# `const_drop_guard`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `const_drop_in_place`

The tracking issue for this feature is: #109342

# `const_eval_select`

The tracking issue for this feature is: #124625

# `const_format_args`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `const_heap`

The tracking issue for this feature is: #79597

# `const_index`

The tracking issue for this feature is: #143775

# `const_manually_drop_take`

The tracking issue for this feature is: #148773

# `const_never_short_circuit`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `const_ops`

The tracking issue for this feature is: #143802

# `const_option_ops`

The tracking issue for this feature is: #143956

# `const_range`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `const_range_bounds`

The tracking issue for this feature is: #108082

# `const_raw_ptr_comparison`

The tracking issue for this feature is: #53020

# `const_ref_cell`

The tracking issue for this feature is: #137844

# `const_result_trait_fn`

The tracking issue for this feature is: #144211

# `const_result_unwrap_unchecked`

The tracking issue for this feature is: #148714

# `const_select_unpredictable`

The tracking issue for this feature is: #145938

# `const_slice_from_mut_ptr_range`

The tracking issue for this feature is: #89792

# `const_slice_from_ptr_range`

The tracking issue for this feature is: #89792

# `const_slice_make_iter`

The tracking issue for this feature is: #137737

# `const_split_off_first_last`

The tracking issue for this feature is: #138539

# `const_swap_with_slice`

The tracking issue for this feature is: #142204

# `const_try_residual`

The tracking issue for this feature is: #91285

# `const_type_name`

The tracking issue for this feature is: #63084

# `container_error_extra`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `context_ext`

The tracking issue for this feature is: #123392

# `control_flow_into_value`

The tracking issue for this feature is: #137461

# `control_flow_ok`

The tracking issue for this feature is: #140266

# `convert_float_to_int`

The tracking issue for this feature is: #67057

# `copied_into_inner`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `core_float_math`

The tracking issue for this feature is: #137578

# `core_intrinsics`

This feature is internal to the Rust compiler and is not intended for general use.

# `core_intrinsics_fallbacks`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `core_io_borrowed_buf`

The tracking issue for this feature is: #117693

# `core_private_bignum`

This feature is internal to the Rust compiler and is not intended for general use.

# `core_private_diy_float`

This feature is internal to the Rust compiler and is not intended for general use.

# `coroutine_trait`

The tracking issue for this feature is: #43122

# `cow_is_borrowed`

The tracking issue for this feature is: #65143

# `cstr_bytes`

The tracking issue for this feature is: #112115

# `cstr_display`

The tracking issue for this feature is: #139984

# `cstr_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `current_thread_id`

The tracking issue for this feature is: #147194

# `cursor_split`

The tracking issue for this feature is: #86369

# `darwin_objc`

The tracking issue for this feature is: #145496

# `deadline_api`

The tracking issue for this feature is: #46316

# `debug_closure_helpers`

The tracking issue for this feature is: #117729

# `dec2flt`

This feature is internal to the Rust compiler and is not intended for general use.

# `deque_extend_front`

The tracking issue for this feature is: #146975

# `deref_pure_trait`

The tracking issue for this feature is: #87121

# `derive_clone_copy_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `derive_coerce_pointee`

The tracking issue for this feature is: #123430

# `derive_const`

The tracking issue for this feature is: #118304

# `derive_eq_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `dir_entry_ext2`

The tracking issue for this feature is: #85573

# `dirfd`

The tracking issue for this feature is: #120426

# `dirhandle`

The tracking issue for this feature is: #120426

# `discriminant_kind`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `disjoint_bitor`

The tracking issue for this feature is: #135758

# `dispatch_from_dyn`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `downcast_unchecked`

The tracking issue for this feature is: #90850

# `drain_keep_rest`

The tracking issue for this feature is: #101122

# `drop_guard`

The tracking issue for this feature is: #144426

# `duration_constants`

The tracking issue for this feature is: #57391

# `duration_constructors`

The tracking issue for this feature is: #120301

Add the methods `from_days` and `from_weeks` to `Duration`.

# `duration_integer_division`

The tracking issue for this feature is: #149573

# `duration_millis_float`

The tracking issue for this feature is: #122451

# `duration_units`

The tracking issue for this feature is: #120301

# `edition_panic`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `error_generic_member_access`

The tracking issue for this feature is: #99301

# `error_iter`

The tracking issue for this feature is: #58520

# `error_reporter`

The tracking issue for this feature is: #90172

# `error_type_id`

The tracking issue for this feature is: #60784

# `exact_bitshifts`

The tracking issue for this feature is: #144336

# `exact_div`

The tracking issue for this feature is: #139911

# `exact_size_is_empty`

The tracking issue for this feature is: #35428

# `exclusive_wrapper`

The tracking issue for this feature is: #98407

# `exit_status_error`

The tracking issue for this feature is: #84908

# `exitcode_exit_method`

The tracking issue for this feature is: #97100

# `extend_one`

The tracking issue for this feature is: #72631

# `extend_one_unchecked`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `fd`

This feature is internal to the Rust compiler and is not intended for general use.

# `file_buffered`

The tracking issue for this feature is: #130804

# `float_algebraic`

The tracking issue for this feature is: #136469

# `float_erf`

The tracking issue for this feature is: #136321

# `float_gamma`

The tracking issue for this feature is: #99842

# `float_minimum_maximum`

The tracking issue for this feature is: #91079

# `flt2dec`

This feature is internal to the Rust compiler and is not intended for general use.

# `fmt_arguments_from_str`

The tracking issue for this feature is: #148905

# `fmt_helpers_for_derive`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `fmt_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `fn_ptr_trait`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `fn_traits`

The tracking issue for this feature is #29625

See Also: `unboxed_closures`

The `fn_traits` feature allows for implementation of the `Fn*` traits for creating custom closure-like types.

    #![feature(unboxed_closures)]
    #![feature(fn_traits)]

    struct Adder {
        a: u32
    }

    impl FnOnce<(u32, )> for Adder {
        type Output = u32;
        extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output {
            self.a + b.0
        }
    }

    fn main() {
        let adder = Adder { a: 3 };
        assert_eq!(adder(2), 5);
    }

# `forget_unsized`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `format_args_nl`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `formatting_options`

The tracking issue for this feature is: #118117

# `freeze`

The tracking issue for this feature is: #121675

# `fs_set_times`

The tracking issue for this feature is: #147455

# `funnel_shifts`

The tracking issue for this feature is: #145686

# `future_join`

The tracking issue for this feature is: #91642

# `gen_future`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `generic_assert_internals`

The tracking issue for this feature is: #44838

# `generic_atomic`

The tracking issue for this feature is: #130539

# `get_disjoint_mut_helpers`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `get_mut_unchecked`

The tracking issue for this feature is: #63292

# `gethostname`

The tracking issue for this feature is: #135142

# `gpu_intrinsics`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `hash_set_entry`

The tracking issue for this feature is: #60896

# `hasher_prefixfree_extras`

The tracking issue for this feature is: #96762

# `hashmap_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `hint_must_use`

The tracking issue for this feature is: #94745

# `hint_prefetch`

The tracking issue for this feature is: #146941

# `inplace_iteration`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `int_format_into`

The tracking issue for this feature is: #138215

# `int_from_ascii`

The tracking issue for this feature is: #134821

# `int_lowest_highest_one`

The tracking issue for this feature is: #145203

# `int_roundings`

The tracking issue for this feature is: #88581

# `integer_atomics`

The tracking issue for this feature is: #99069

# `internal_impls_macro`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `internal_output_capture`

This feature is internal to the Rust compiler and is not intended for general use.

# `io_const_error`

The tracking issue for this feature is: #133448

# `io_const_error_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `io_error_inprogress`

The tracking issue for this feature is: #130840

# `io_error_more`

The tracking issue for this feature is: #86442

# `io_error_uncategorized`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `io_slice_as_bytes`

The tracking issue for this feature is: #132818

# `ip`

The tracking issue for this feature is: #27709

# `ip_as_octets`

The tracking issue for this feature is: #137259

# `is_ascii_octdigit`

The tracking issue for this feature is: #101288

# `is_loongarch_feature_detected`

The tracking issue for this feature is: #117425

# `is_riscv_feature_detected`

The tracking issue for this feature is: #111192

# `isolate_most_least_significant_one`

The tracking issue for this feature is: #136909

# `iter_advance_by`

The tracking issue for this feature is: #77404

# `iter_array_chunks`

The tracking issue for this feature is: #100450

# `iter_collect_into`

The tracking issue for this feature is: #94780

# `iter_from_coroutine`

The tracking issue for this feature is: #43122

# `iter_intersperse`

The tracking issue for this feature is: #79524

# `iter_is_partitioned`

The tracking issue for this feature is: #62544

# `iter_macro`

The tracking issue for this feature is: #142269

# `iter_map_windows`

The tracking issue for this feature is: #87155

# `iter_next_chunk`

The tracking issue for this feature is: #98326

# `iter_order_by`

The tracking issue for this feature is: #64295

# `iter_partition_in_place`

The tracking issue for this feature is: #62543

# `iterator_try_collect`

The tracking issue for this feature is: #94047

# `iterator_try_reduce`

The tracking issue for this feature is: #87053

# `junction_point`

The tracking issue for this feature is: #121709

# `layout_for_ptr`

The tracking issue for this feature is: #69835

# `lazy_cell_into_inner`

The tracking issue for this feature is: #125623

# `legacy_receiver_trait`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `liballoc_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `libstd_sys_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `likely_unlikely`

The tracking issue for this feature is: #136873

# `linked_list_cursors`

The tracking issue for this feature is: #58533

# `linked_list_remove`

The tracking issue for this feature is: #69210

# `linked_list_retain`

The tracking issue for this feature is: #114135

# `linux_pidfd`

The tracking issue for this feature is: #82971

# `local_key_cell_update`

The tracking issue for this feature is: #143989

# `local_waker`

The tracking issue for this feature is: #118959

# `lock_value_accessors`

The tracking issue for this feature is: #133407

# `log_syntax`

The tracking issue for this feature is: #29598

# `map_try_insert`

The tracking issue for this feature is: #82766

# `mapped_lock_guards`

The tracking issue for this feature is: #117108

# `maybe_dangling`

The tracking issue for this feature is: #118166

# `maybe_uninit_array_assume_init`

The tracking issue for this feature is: #96097

# `maybe_uninit_as_bytes`

The tracking issue for this feature is: #93092

# `maybe_uninit_fill`

The tracking issue for this feature is: #117428

# `maybe_uninit_uninit_array_transpose`

The tracking issue for this feature is: #96097

# `mem_conjure_zst`

The tracking issue for this feature is: #95383

# `mem_copy_fn`

The tracking issue for this feature is: #98262

# `min_const_control_flow`

The tracking issue for this feature is: #148738

# `more_float_constants`

The tracking issue for this feature is: #146939

# `motor_ext`

The tracking issue for this feature is: #147456

# `mpmc_channel`

The tracking issue for this feature is: #126840

# `mutex_data_ptr`

The tracking issue for this feature is: #140368

# `new_range_api`

The tracking issue for this feature is: #125687

# `next_index`

The tracking issue for this feature is: #130711

# `nonpoison_condvar`

The tracking issue for this feature is: #134645

# `nonpoison_mutex`

The tracking issue for this feature is: #134645

# `nonpoison_rwlock`

The tracking issue for this feature is: #134645

# `nonzero_bitwise`

The tracking issue for this feature is: #128281

# `nonzero_from_mut`

The tracking issue for this feature is: #106290

# `nonzero_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `nonzero_ops`

The tracking issue for this feature is: #84186

# `normalize_lexically`

The tracking issue for this feature is: #134694

# `numfmt`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `objc_class_variant`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `objc_selector_variant`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `once_cell_get_mut`

The tracking issue for this feature is: #121641

# `once_cell_try`

The tracking issue for this feature is: #109737

# `once_cell_try_insert`

The tracking issue for this feature is: #116693

# `one_sided_range`

The tracking issue for this feature is: #69780

# `oneshot_channel`

The tracking issue for this feature is: #143674

# `option_array_transpose`

The tracking issue for this feature is: #130828

# `option_into_flat_iter`

The tracking issue for this feature is: #148441

# `option_reduce`

The tracking issue for this feature is: #144273

# `option_reference_flattening`

The tracking issue for this feature is: #149221

# `option_zip`

The tracking issue for this feature is: #70086

# `os_str_slice`

The tracking issue for this feature is: #118485

# `os_string_truncate`

The tracking issue for this feature is: #133262

# `panic_abort`

The tracking issue for this feature is: #32837

# `panic_always_abort`

The tracking issue for this feature is: #84438

# `panic_backtrace_config`

The tracking issue for this feature is: #93346

# `panic_can_unwind`

The tracking issue for this feature is: #92988

# `panic_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `panic_unwind`

The tracking issue for this feature is: #32837

# `panic_update_hook`

The tracking issue for this feature is: #92649

# `partial_ord_chaining_methods`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `path_is_empty`

The tracking issue for this feature is: #148494

# `path_trailing_sep`

The tracking issue for this feature is: #142503

# `pattern`

The tracking issue for this feature is: #27721

# `pattern_type_macro`

The tracking issue for this feature is: #123646

# `pattern_type_range_trait`

The tracking issue for this feature is: #123646

# `peer_credentials_unix_socket`

The tracking issue for this feature is: #42839

# `phantom_variance_markers`

The tracking issue for this feature is: #135806

# `pin_coerce_unsized_trait`

The tracking issue for this feature is: #150112

# `pin_derefmut_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `pointer_is_aligned_to`

The tracking issue for this feature is: #96284

# `pointer_try_cast_aligned`

The tracking issue for this feature is: #141221

# `portable_simd`

The tracking issue for this feature is: #86656

# `prelude_future`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `prelude_next`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `print_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `proc_macro_def_site`

The tracking issue for this feature is: #54724

# `proc_macro_diagnostic`

The tracking issue for this feature is: #54140

# `proc_macro_expand`

The tracking issue for this feature is: #90765

# `proc_macro_internals`

The tracking issue for this feature is: #27812

# `proc_macro_quote`

The tracking issue for this feature is: #54722

# `proc_macro_span`

The tracking issue for this feature is: #54725

# `proc_macro_totokens`

The tracking issue for this feature is: #130977

# `proc_macro_tracked_env`

The tracking issue for this feature is: #99515

# `proc_macro_tracked_path`

The tracking issue for this feature is: #99515

# `proc_macro_value`

The tracking issue for this feature is: #136652

# `process_chroot`

The tracking issue for this feature is: #141298

# `process_exitcode_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `process_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `process_setsid`

The tracking issue for this feature is: #105376

# `profiler_runtime_lib`

This feature is internal to the Rust compiler and is not intended for general use.

# `profiling_marker_api`

The tracking issue for this feature is: #148197

# `ptr_alignment_type`

The tracking issue for this feature is: #102070

# `ptr_as_ref_unchecked`

The tracking issue for this feature is: #122034

# `ptr_as_uninit`

The tracking issue for this feature is: #75402

# `ptr_cast_array`

The tracking issue for this feature is: #144514

# `ptr_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `ptr_mask`

The tracking issue for this feature is: #98290

# `ptr_metadata`

The tracking issue for this feature is: #81513

# `pub_crate_should_not_need_unstable_attr`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `push_mut`

The tracking issue for this feature is: #135974

# `random`

The tracking issue for this feature is: #130703

# `range_bounds_is_empty`

The tracking issue for this feature is: #137300

# `range_into_bounds`

The tracking issue for this feature is: #136903

# `raw_os_error_ty`

The tracking issue for this feature is: #107792

# `raw_slice_split`

The tracking issue for this feature is: #95595

# `raw_vec_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `read_array`

The tracking issue for this feature is: #148848

# `read_buf`

The tracking issue for this feature is: #78485

# `read_buf_at`

The tracking issue for this feature is: #140771

# `reentrant_lock`

The tracking issue for this feature is: #121440

# `reentrant_lock_data_ptr`

The tracking issue for this feature is: #140368

# `refcell_try_map`

The tracking issue for this feature is: #143801

# `restricted_std`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `result_option_map_or_default`

The tracking issue for this feature is: #138099

# `rev_into_inner`

The tracking issue for this feature is: #144277

# `rt`

This feature is internal to the Rust compiler and is not intended for general use.

# `rwlock_data_ptr`

The tracking issue for this feature is: #140368

# `sealed`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `seek_io_take_position`

The tracking issue for this feature is: #97227

# `seek_stream_len`

The tracking issue for this feature is: #59359

# `set_permissions_nofollow`

The tracking issue for this feature is: #141607

# `set_ptr_value`

The tracking issue for this feature is: #75091

# `setgroups`

The tracking issue for this feature is: #90747

# `sgx_platform`

The tracking issue for this feature is: #56975

# `sized_type_properties`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `slice_concat_ext`

The tracking issue for this feature is: #27747

# `slice_concat_trait`

The tracking issue for this feature is: #27747

# `slice_from_ptr_range`

The tracking issue for this feature is: #89792

# `slice_index_methods`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `slice_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `slice_iter_mut_as_mut_slice`

The tracking issue for this feature is: #93079

# `slice_partial_sort_unstable`

The tracking issue for this feature is: #149046

# `slice_partition_dedup`

The tracking issue for this feature is: #54279

# `slice_pattern`

The tracking issue for this feature is: #56345

# `slice_ptr_get`

The tracking issue for this feature is: #74265

# `slice_range`

The tracking issue for this feature is: #76393

# `slice_split_once`

The tracking issue for this feature is: #112811

# `slice_swap_unchecked`

The tracking issue for this feature is: #88539

# `sliceindex_wrappers`

The tracking issue for this feature is: #146179

# `smart_pointer_try_map`

The tracking issue for this feature is: #144419

# `solid_ext`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `sort_floats`

The tracking issue for this feature is: #93396

# `split_array`

The tracking issue for this feature is: #90091

# `split_as_slice`

The tracking issue for this feature is: #96137

# `std_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `stdarch_aarch64_feature_detection`

The tracking issue for this feature is: #127764

# `stdarch_arm_feature_detection`

The tracking issue for this feature is: #111190

# `stdarch_internal`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `stdarch_loongarch_feature_detection`

The tracking issue for this feature is: #117425

# `stdarch_mips_feature_detection`

The tracking issue for this feature is: #111188

# `stdarch_powerpc_feature_detection`

The tracking issue for this feature is: #111191

# `stdarch_riscv_feature_detection`

The tracking issue for this feature is: #111192

# `stdio_makes_pipe`

The tracking issue for this feature is: #98288

# `stdio_swap`

The tracking issue for this feature is: #150667

# `step_trait`

The tracking issue for this feature is: #42168

# `str_as_str`

The tracking issue for this feature is: #130366

# `str_from_raw_parts`

The tracking issue for this feature is: #119206

# `str_from_utf16_endian`

The tracking issue for this feature is: #116258

# `str_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `str_lines_remainder`

The tracking issue for this feature is: #77998

# `str_split_inclusive_remainder`

The tracking issue for this feature is: #77998

# `str_split_remainder`

The tracking issue for this feature is: #77998

# `str_split_whitespace_remainder`

The tracking issue for this feature is: #77998

# `string_from_utf8_lossy_owned`

The tracking issue for this feature is: #129436

# `string_into_chars`

The tracking issue for this feature is: #133125

# `string_remove_matches`

The tracking issue for this feature is: #72826

# `string_replace_in_place`

The tracking issue for this feature is: #147949

# `strip_circumfix`

The tracking issue for this feature is: #147946

# `substr_range`

The tracking issue for this feature is: #126769

# `sync_nonpoison`

The tracking issue for this feature is: #134645

# `sync_poison_mod`

The tracking issue for this feature is: #134646

# `sync_unsafe_cell`

The tracking issue for this feature is: #95439

# `tcp_deferaccept`

The tracking issue for this feature is: #119639

# `tcp_linger`

The tracking issue for this feature is: #88494

# `tcplistener_into_incoming`

The tracking issue for this feature is: #88373

# `temporary_niche_types`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `test`

The tracking issue for this feature is: None.

The internals of the `test` crate are unstable, behind the `test` flag. The most widely used part of the `test` crate are benchmark tests, which can test the performance of your code. Let’s make our `src/lib.rs` look like this (comments elided):

    #![allow(unused)]
    #![feature(test)]

    fn main() {
    extern crate test;

    pub fn add_two(a: i32) -> i32 {
        a + 2
    }

    #[cfg(test)]
    mod tests {
        use super::*;
        use test::Bencher;

        #[test]
        fn it_works() {
            assert_eq!(4, add_two(2));
        }

        #[bench]
        fn bench_add_two(b: &mut Bencher) {
            b.iter(|| add_two(2));
        }
    }
    }

Note the `test` feature gate, which enables this unstable feature.

We’ve imported the `test` crate, which contains our benchmarking support. We have a new function as well, with the `bench` attribute. Unlike regular tests, which take no arguments, benchmark tests take a `&mut Bencher`. This `Bencher` provides an `iter` method, which takes a closure. This closure contains the code we’d like to benchmark.

We can run benchmark tests with `cargo bench`:

    $ cargo bench
       Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
         Running target/release/adder-91b3e234d4ed382a

    running 2 tests
    test tests::it_works ... ignored
    test tests::bench_add_two ... bench:         1 ns/iter (+/- 0)

    test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured

Our non-benchmark test was ignored. You may have noticed that `cargo bench` takes a bit longer than `cargo test`. This is because Rust runs our benchmark a number of times, and then takes the average. Because we’re doing so little work in this example, we have a `1 ns/iter (+/- 0)`, but this would show the variance if there was one.

Advice on writing benchmarks:

- Move setup code outside the `iter` loop; only put the part you want to measure inside
- Make the code do “the same thing” on each iteration; do not accumulate or change state
- Make the outer function idempotent too; the benchmark runner is likely to run it many times
- Make the inner `iter` loop short and fast so benchmark runs are fast and the calibrator can adjust the run-length at fine resolution
- Make the code in the `iter` loop do something simple, to assist in pinpointing performance improvements (or regressions)

## Gotcha: optimizations

There’s another tricky part to writing benchmarks: benchmarks compiled with optimizations activated can be dramatically changed by the optimizer so that the benchmark is no longer benchmarking what one expects. For example, the compiler might recognize that some calculation has no external effects and remove it entirely.

    #![allow(unused)]
    #![feature(test)]

    fn main() {
    extern crate test;
    use test::Bencher;

    #[bench]
    fn bench_xor_1000_ints(b: &mut Bencher) {
        b.iter(|| {
            (0..1000).fold(0, |old, new| old ^ new);
        });
    }
    }

gives the following results

    running 1 test
    test bench_xor_1000_ints ... bench:         0 ns/iter (+/- 0)

    test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured

The benchmarking runner offers two ways to avoid this. Either, the closure that the `iter` method receives can return an arbitrary value which forces the optimizer to consider the result used and ensures it cannot remove the computation entirely. This could be done for the example above by adjusting the `b.iter` call to

    #![allow(unused)]
    fn main() {
    struct X;
    impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
    b.iter(|| {
        // Note lack of `;` (could also use an explicit `return`).
        (0..1000).fold(0, |old, new| old ^ new)
    });
    }

Or, the other option is to call the generic `test::black_box` function, which is an opaque “black box” to the optimizer and so forces it to consider any argument as used.

    #![feature(test)]

    extern crate test;

    fn main() {
    struct X;
    impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
    b.iter(|| {
        let n = test::black_box(1000);

        (0..n).fold(0, |a, b| a ^ b)
    })
    }

Neither of these read or modify the value, and are very cheap for small values. Larger values can be passed indirectly to reduce overhead (e.g. `black_box(&huge_struct)`).

Performing either of the above changes gives the following benchmarking results

    running 1 test
    test bench_xor_1000_ints ... bench:       131 ns/iter (+/- 3)

    test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured

However, the optimizer can still modify a testcase in an undesirable manner even when using either of the above.

# `thin_box`

The tracking issue for this feature is: #92791

# `thread_id_value`

The tracking issue for this feature is: #67939

# `thread_local_internals`

This feature is internal to the Rust compiler and is not intended for general use.

# `thread_raw`

The tracking issue for this feature is: #97523

# `thread_sleep_until`

The tracking issue for this feature is: #113752

# `thread_spawn_hook`

The tracking issue for this feature is: #132951

# `time_systemtime_limits`

The tracking issue for this feature is: #149067

# `trace_macros`

The tracking issue for this feature is #29598.

With `trace_macros` you can trace the expansion of macros in your code.

## Examples

    #![feature(trace_macros)]

    fn main() {
        trace_macros!(true);
        println!("Hello, Rust!");
        trace_macros!(false);
    }

The `cargo build` output:

    note: trace_macro
     --> src/main.rs:5:5
      |
    5 |     println!("Hello, Rust!");
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: expanding `println! { "Hello, Rust!" }`
      = note: to `print ! ( concat ! ( "Hello, Rust!" , "\n" ) )`
      = note: expanding `print! { concat ! ( "Hello, Rust!" , "\n" ) }`
      = note: to `$crate :: io :: _print ( format_args ! ( concat ! ( "Hello, Rust!" , "\n" ) )
              )`

        Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs

# `transmutability`

The tracking issue for this feature is: #99571

# `trim_prefix_suffix`

The tracking issue for this feature is: #142312

# `trivial_clone`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `trusted_fused`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `trusted_len`

The tracking issue for this feature is: #37572

# `trusted_len_next_unchecked`

The tracking issue for this feature is: #37572

# `trusted_random_access`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `trusted_step`

The tracking issue for this feature is: #85731

# `try_as_dyn`

The tracking issue for this feature is: #144361

# `try_find`

The tracking issue for this feature is: #63178

# `try_reserve_kind`

The tracking issue for this feature is: #48043

# `try_trait_v2`

The tracking issue for this feature is: #84277

# `try_trait_v2_residual`

The tracking issue for this feature is: #91285

# `try_trait_v2_yeet`

The tracking issue for this feature is: #96374

# `try_with_capacity`

The tracking issue for this feature is: #91913

# `tuple_trait`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `type_ascription`

The tracking issue for this feature is: #23416

# `type_info`

The tracking issue for this feature is: #146922

# `ub_checks`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `uefi_std`

The tracking issue for this feature is: #100499

# `uint_bit_width`

The tracking issue for this feature is: #142326

# `uint_gather_scatter_bits`

The tracking issue for this feature is: #149069

# `unicode_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `unique_rc_arc`

The tracking issue for this feature is: #112566

# `unix_file_vectored_at`

The tracking issue for this feature is: #89517

# `unix_mkfifo`

The tracking issue for this feature is: #139324

# `unix_send_signal`

The tracking issue for this feature is: #141975

# `unix_set_mark`

The tracking issue for this feature is: #96467

# `unix_socket_ancillary_data`

The tracking issue for this feature is: #76915

# `unix_socket_exclbind`

The tracking issue for this feature is: #123481

# `unix_socket_peek`

The tracking issue for this feature is: #76923

# `unsafe_cell_access`

The tracking issue for this feature is: #136327

# `unsafe_pinned`

The tracking issue for this feature is: #125735

# `unsize`

The tracking issue for this feature is: #18598

# `unwrap_infallible`

The tracking issue for this feature is: #61695

# `update_panic_count`

This feature is internal to the Rust compiler and is not intended for general use.

# `utf16_extra`

The tracking issue for this feature is: #94919

# `variant_count`

The tracking issue for this feature is: #73662

# `vec_deque_extract_if`

The tracking issue for this feature is: #147750

# `vec_deque_iter_as_slices`

The tracking issue for this feature is: #123947

# `vec_deque_truncate_front`

The tracking issue for this feature is: #140667

# `vec_from_fn`

The tracking issue for this feature is: #149698

# `vec_into_chunks`

The tracking issue for this feature is: #142137

# `vec_peek_mut`

The tracking issue for this feature is: #122742

# `vec_push_within_capacity`

The tracking issue for this feature is: #100486

# `vec_recycle`

The tracking issue for this feature is: #148227

# `vec_split_at_spare`

The tracking issue for this feature is: #81944

# `vec_try_remove`

The tracking issue for this feature is: #146954

# `waker_fn`

The tracking issue for this feature is: #149580

# `waker_from_fn_ptr`

The tracking issue for this feature is: #148457

# `wasi_ext`

The tracking issue for this feature is: #71213

# `windows_by_handle`

The tracking issue for this feature is: #63010

# `windows_c`

This feature is internal to the Rust compiler and is not intended for general use.

# `windows_change_time`

The tracking issue for this feature is: #121478

# `windows_freeze_file_times`

The tracking issue for this feature is: #149715

# `windows_handle`

This feature is internal to the Rust compiler and is not intended for general use.

# `windows_net`

This feature is internal to the Rust compiler and is not intended for general use.

# `windows_process_exit_code_from`

The tracking issue for this feature is: #111688

# `windows_process_extensions_async_pipes`

The tracking issue for this feature is: #98289

# `windows_process_extensions_force_quotes`

The tracking issue for this feature is: #82227

# `windows_process_extensions_inherit_handles`

The tracking issue for this feature is: #146407

# `windows_process_extensions_main_thread_handle`

The tracking issue for this feature is: #96723

# `windows_process_extensions_raw_attribute`

The tracking issue for this feature is: #114854

# `windows_process_extensions_show_window`

The tracking issue for this feature is: #127544

# `windows_process_extensions_startupinfo`

The tracking issue for this feature is: #141010

# `windows_stdio`

This feature is internal to the Rust compiler and is not intended for general use.

# `wrapping_int_impl`

The tracking issue for this feature is: #32463

# `wrapping_next_power_of_two`

The tracking issue for this feature is: #32463

# `write_all_vectored`

The tracking issue for this feature is: #70436

# `wtf8_internals`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.

# `yeet_desugar_details`

This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.