The rustc book

# What is rustc?

Welcome to "The rustc book"! `rustc` is the compiler for the Rust programming language, provided by the project itself. Compilers take your source code and produce binary code, either as a library or executable.

Most Rust programmers don't invoke `rustc` directly, but instead do it through Cargo. It's all in service of `rustc` though! If you want to see how Cargo calls `rustc`, you can

    $ cargo build --verbose

And it will print out each `rustc` invocation. This book can help you understand what each of these options does. Additionally, while most Rustaceans use Cargo, not all do: sometimes they integrate `rustc` into other build systems. This book should provide a guide to all of the options you'd need to do so.

## Basic usage

Let's say you've got a little hello world program in a file `hello.rs`:

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

To turn this source code into an executable, you can use `rustc`:

    $ rustc hello.rs
    $ ./hello # on a *NIX
    $ .\hello.exe # on Windows

Note that we only ever pass `rustc` the crate root, not every file we wish to compile. For example, if we had a `main.rs` that looked like this:

    mod foo;

    fn main() {
        foo::hello();
    }

And a `foo.rs` that had this:

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

To compile this, we'd run this command:

    $ rustc main.rs

No need to tell `rustc` about `foo.rs`; the `mod` statements give it everything that it needs. This is different than how you would use a C compiler, where you invoke the compiler on each file, and then link everything together. In other words, the crate is a translation unit, not a particular module.

# Command-line arguments

Here's a list of command-line arguments to `rustc` and what they do.

## `-h`/`--help`: get help

This flag will print out help information for `rustc`.

## `--cfg`: configure the compilation environment

This flag can turn on or off various `#[cfg]` settings for conditional compilation.

The value can either be a single identifier or two identifiers separated by `=`.

For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.

## `-L`: add a directory to the library search path

The `-L` flag adds a path to search for external crates and libraries.

The kind of search path can optionally be specified with the form `-L KIND=PATH` where `KIND` may be one of:

- `dependency` — Only search for transitive dependencies in this directory.
- `crate` — Only search for this crate's direct dependencies in this directory.
- `native` — Only search for native libraries in this directory.
- `framework` — Only search for macOS frameworks in this directory.
- `all` — Search for all library kinds in this directory. This is the default if `KIND` is not specified.

## `-l`: link the generated crate to a native library

This flag allows you to specify linking to a specific native library when building a crate.

The kind of library can optionally be specified with the form `-l KIND=lib` where `KIND` may be one of:

- `dylib` — A native dynamic library.
- `static` — A native static library (such as a `.a` archive).
- `framework` — A macOS framework.

The kind of library can be specified in a `#[link]` attribute. If the kind is not specified in the `link` attribute or on the command-line, it will link a dynamic library if available, otherwise it will use a static library. If the kind is specified on the command-line, it will override the kind specified in a `link` attribute.

The name used in a `link` attribute may be overridden using the form `-l ATTR_NAME:LINK_NAME` where `ATTR_NAME` is the name in the `link` attribute, and `LINK_NAME` is the name of the actual library that will be linked.

## `--crate-type`: a list of types of crates for the compiler to emit

This instructs `rustc` on which crate type to build. This flag accepts a comma-separated list of values, and may be specified multiple times. The valid crate types are:

- `lib` — Generates a library kind preferred by the compiler, currently defaults to `rlib`.
- `rlib` — A Rust static library.
- `staticlib` — A native static library.
- `dylib` — A Rust dynamic library.
- `cdylib` — A native dynamic library.
- `bin` — A runnable executable program.
- `proc-macro` — Generates a format suitable for a procedural macro library that may be loaded by the compiler.

The crate type may be specified with the `crate_type` attribute. The `--crate-type` command-line value will override the `crate_type` attribute.

More details may be found in the linkage chapter of the reference.

## `--crate-name`: specify the name of the crate being built

This informs `rustc` of the name of your crate.

## `--edition`: specify the edition to use

This flag takes a value of `2015` or `2018`. The default is `2015`. More information about editions may be found in the edition guide.

## `--emit`: specifies the types of output files to generate

This flag controls the types of output files generated by the compiler. It accepts a comma-separated list of values, and may be specified multiple times. The valid emit kinds are:

- `asm` — Generates a file with the crate's assembly code. The default output filename is `CRATE_NAME.s`.
- `dep-info` — Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate. The default output filename is `CRATE_NAME.d`.
- `link` — Generates the crates specified by `--crate-type`. The default output filenames depend on the crate type and platform. This is the default if `--emit` is not specified.
- `llvm-bc` — Generates a binary file containing the LLVM bitcode. The default output filename is `CRATE_NAME.bc`.
- `llvm-ir` — Generates a file containing LLVM IR. The default output filename is `CRATE_NAME.ll`.
- `metadata` — Generates a file containing metadata about the crate. The default output filename is `CRATE_NAME.rmeta`.
- `mir` — Generates a file containing rustc's mid-level intermediate representation. The default output filename is `CRATE_NAME.mir`.
- `obj` — Generates a native object file. The default output filename is `CRATE_NAME.o`.

The output filename can be set with the `-o` flag. A suffix may be added to the filename with the `-C extra-filename` flag. The files are written to the current directory unless the `--out-dir` flag is used. Each emission type may also specify the output filename with the form `KIND=PATH`, which takes precedence over the `-o` flag.

## `--print`: print compiler information

This flag prints out various information about the compiler. This flag may be specified multiple times, and the information is printed in the order the flags are specified. Specifying a `--print` flag will usually disable the `--emit` step and will only print the requested information. The valid types of print values are:

- `crate-name` — The name of the crate.
- `file-names` — The names of the files created by the `link` emit kind.
- `sysroot` — Path to the sysroot.
- `target-libdir` - Path to the target libdir.
- `cfg` — List of cfg values. See conditional compilation for more information about cfg values.
- `target-list` — List of known targets. The target may be selected with the `--target` flag.
- `target-cpus` — List of available CPU values for the current target. The target CPU may be selected with the `-C target-cpu=val` flag.
- `target-features` — List of available target features for the current target. Target features may be enabled with the `-C target-feature=val` flag. This flag is unsafe. See known issues for more details.
- `relocation-models` — List of relocation models. Relocation models may be selected with the `-C relocation-model=val` flag.
- `code-models` — List of code models. Code models may be selected with the `-C code-model=val` flag.
- `tls-models` — List of Thread Local Storage models supported. The model may be selected with the `-Z tls-model=val` flag.
- `native-static-libs` — This may be used when creating a `staticlib` crate type. If this is the only flag, it will perform a full compilation and include a diagnostic note that indicates the linker flags to use when linking the resulting static library. The note starts with the text `native-static-libs:` to make it easier to fetch the output.

## `-g`: include debug information

A synonym for `-C debuginfo=2`.

## `-O`: optimize your code

A synonym for `-C opt-level=2`.

## `-o`: filename of the output

This flag controls the output filename.

## `--out-dir`: directory to write the output in

The outputted crate will be written to this directory. This flag is ignored if the `-o` flag is used.

## `--explain`: provide a detailed explanation of an error message

Each error of `rustc`'s comes with an error code; this will print out a longer explanation of a given error.

## `--test`: build a test harness

When compiling this crate, `rustc` will ignore your `main` function and instead produce a test harness.

## `--target`: select a target triple to build

This controls which target to produce.

## `-W`: set lint warnings

This flag will set which lints should be set to the warn level.

Note: The order of these lint level arguments is taken into account, see lint level via compiler flag for more information.

## `-A`: set lint allowed

This flag will set which lints should be set to the allow level.

Note: The order of these lint level arguments is taken into account, see lint level via compiler flag for more information.

## `-D`: set lint denied

This flag will set which lints should be set to the deny level.

Note: The order of these lint level arguments is taken into account, see lint level via compiler flag for more information.

## `-F`: set lint forbidden

This flag will set which lints should be set to the forbid level.

Note: The order of these lint level arguments is taken into account, see lint level via compiler flag for more information.

## `-Z`: set unstable options

This flag will allow you to set unstable options of rustc. In order to set multiple options, the -Z flag can be used multiple times. For example: `rustc -Z verbose -Z time`. Specifying options with -Z is only available on nightly. To view all available options run: `rustc -Z help`.

## `--cap-lints`: set the most restrictive lint level

This flag lets you 'cap' lints, for more, see here.

## `-C`/`--codegen`: code generation options

This flag will allow you to set codegen options.

## `-V`/`--version`: print a version

This flag will print out `rustc`'s version.

## `-v`/`--verbose`: use verbose output

This flag, when combined with other flags, makes them produce extra output.

## `--extern`: specify where an external library is located

This flag allows you to pass the name and location for an external crate of a direct dependency. Indirect dependencies (dependencies of dependencies) are located using the `-L` flag. The given crate name is added to the extern prelude, similar to specifying `extern crate` within the root module. The given crate name does not need to match the name the library was built with.

Specifying `--extern` has one behavior difference from `extern crate`: `--extern` merely makes the crate a candidate for being linked; it does not actually link it unless it's actively used. In rare occasions you may wish to ensure a crate is linked even if you don't actively use it from your code: for example, if it changes the global allocator or if it contains `#[no_mangle]` symbols for use by other programming languages. In such cases you'll need to use `extern crate`.

This flag may be specified multiple times. This flag takes an argument with either of the following formats:

- `CRATENAME=PATH` — Indicates the given crate is found at the given path.
- `CRATENAME` — Indicates the given crate may be found in the search path, such as within the sysroot or via the `-L` flag.

The same crate name may be specified multiple times for different crate types. If both an `rlib` and `dylib` are found, an internal algorithm is used to decide which to use for linking. The `-C prefer-dynamic` flag may be used to influence which is used.

If the same crate name is specified with and without a path, the one with the path is used and the pathless flag has no effect.

## `--sysroot`: Override the system root

The "sysroot" is where `rustc` looks for the crates that come with the Rust distribution; this flag allows that to be overridden.

## `--error-format`: control how errors are produced

This flag lets you control the format of messages. Messages are printed to stderr. The valid options are:

- `human` — Human-readable output. This is the default.
- `json` — Structured JSON output. See the JSON chapter for more detail.
- `short` — Short, one-line messages.

## `--color`: configure coloring of output

This flag lets you control color settings of the output. The valid options are:

- `auto` — Use colors if output goes to a tty. This is the default.
- `always` — Always use colors.
- `never` — Never colorize output.

## `--remap-path-prefix`: remap source names in output

Remap source path prefixes in all output, including compiler diagnostics, debug information, macro expansions, etc. It takes a value of the form `FROM=TO` where a path prefix equal to `FROM` is rewritten to the value `TO`. The `FROM` may itself contain an `=` symbol, but the `TO` value may not. This flag may be specified multiple times.

This is useful for normalizing build products, for example by removing the current directory out of pathnames emitted into the object files. The replacement is purely textual, with no consideration of the current system's pathname syntax. For example `--remap-path-prefix foo=bar` will match `foo/lib.rs` but not `./foo/lib.rs`.

## `--json`: configure json messages printed by the compiler

When the `--error-format=json` option is passed to rustc then all of the compiler's diagnostic output will be emitted in the form of JSON blobs. The `--json` argument can be used in conjunction with `--error-format=json` to configure what the JSON blobs contain as well as which ones are emitted.

With `--error-format=json` the compiler will always emit any compiler errors as a JSON blob, but the following options are also available to the `--json` flag to customize the output:

- `diagnostic-short` - json blobs for diagnostic messages should use the "short" rendering instead of the normal "human" default. This means that the output of `--error-format=short` will be embedded into the JSON diagnostics instead of the default `--error-format=human`.

- `diagnostic-rendered-ansi` - by default JSON blobs in their `rendered` field will contain a plain text rendering of the diagnostic. This option instead indicates that the diagnostic should have embedded ANSI color codes intended to be used to colorize the message in the manner rustc typically already does for terminal outputs. Note that this is usefully combined with crates like `fwdansi` to translate these ANSI codes on Windows to console commands or `strip-ansi-escapes` if you'd like to optionally remove the ansi colors afterwards.

- `artifacts` - this instructs rustc to emit a JSON blob for each artifact that is emitted. An artifact corresponds to a request from the `--emit` CLI argument, and as soon as the artifact is available on the filesystem a notification will be emitted.

Note that it is invalid to combine the `--json` argument with the `--color` argument, and it is required to combine `--json` with `--error-format=json`.

See the JSON chapter for more detail.

## `@path`: load command-line flags from a path

If you specify `@path` on the command-line, then it will open `path` and read command line options from it. These options are one per line; a blank line indicates an empty option. The file can use Unix or Windows style line endings, and must be encoded as UTF-8.

# Lints

In software, a "lint" is a tool used to help improve your source code. The Rust compiler contains a number of lints, and when it compiles your code, it will also run the lints. These lints may produce a warning, an error, or nothing at all, depending on how you've configured things.

Here's a small example:

    $ cat main.rs
    fn main() {
        let x = 5;
    }
    $ rustc main.rs
    warning: unused variable: `x`
     --> main.rs:2:9
      |
    2 |     let x = 5;
      |         ^
      |
      = note: `#[warn(unused_variables)]` on by default
      = note: to avoid this warning, consider using `_x` instead

This is the `unused_variables` lint, and it tells you that you've introduced a variable that you don't use in your code. That's not wrong, so it's not an error, but it might be a bug, so you get a warning.

## Future-incompatible lints

Sometimes the compiler needs to be changed to fix an issue that can cause existing code to stop compiling. "Future-incompatible" lints are issued in these cases to give users of Rust a smooth transition to the new behavior. Initially, the compiler will continue to accept the problematic code and issue a warning. The warning has a description of the problem, a notice that this will become an error in the future, and a link to a tracking issue that provides detailed information and an opportunity for feedback. This gives users some time to fix the code to accommodate the change. After some time, the warning may become an error.

The following is an example of what a future-incompatible looks like:

    warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
      --> lint_example.rs:11:13
       |
    11 |     let y = &x.data.0;
       |             ^^^^^^^^^
       |
       = note: `#[warn(safe_packed_borrows)]` on by default
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
       = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior

For more information about the process and policy of future-incompatible changes, see RFC 1589.

# Lint levels

In `rustc`, lints are divided into four levels:

1. allow
2. warn
3. deny
4. forbid

Each lint has a default level (explained in the lint listing later in this chapter), and the compiler has a default warning level. First, let's explain what these levels mean, and then we'll talk about configuration.

## allow

These lints exist, but by default, do nothing. For example, consider this source:

    #![allow(unused)]
    fn main() {
    pub fn foo() {}
    }

Compiling this file produces no warnings:

    $ rustc lib.rs --crate-type=lib
    $

But this code violates the `missing_docs` lint.

These lints exist mostly to be manually turned on via configuration, as we'll talk about later in this section.

## warn

The 'warn' lint level will produce a warning if you violate the lint. For example, this code runs afoul of the `unused_variables` lint:

    #![allow(unused)]
    fn main() {
    pub fn foo() {
        let x = 5;
    }
    }

This will produce this warning:

    $ rustc lib.rs --crate-type=lib
    warning: unused variable: `x`
     --> lib.rs:2:9
      |
    2 |     let x = 5;
      |         ^
      |
      = note: `#[warn(unused_variables)]` on by default
      = note: to avoid this warning, consider using `_x` instead

## deny

A 'deny' lint produces an error if you violate it. For example, this code runs into the `exceeding_bitshifts` lint.

    fn main() {
        100u8 << 10;
    }

    $ rustc main.rs
    error: bitshift exceeds the type's number of bits
     --> main.rs:2:13
      |
    2 |     100u8 << 10;
      |     ^^^^^^^^^^^
      |
      = note: `#[deny(exceeding_bitshifts)]` on by default

What's the difference between an error from a lint and a regular old error? Lints are configurable via levels, so in a similar way to 'allow' lints, warnings that are 'deny' by default let you allow them. Similarly, you may wish to set up a lint that is `warn` by default to produce an error instead. This lint level gives you that.

## forbid

'forbid' is a special lint level that's stronger than 'deny'. It's the same as 'deny' in that a lint at this level will produce an error, but unlike the 'deny' level, the 'forbid' level can not be overridden to be anything lower than an error. However, lint levels may still be capped with `--cap-lints` (see below) so `rustc --cap-lints warn` will make lints set to 'forbid' just warn.

## Configuring warning levels

Remember our `missing_docs` example from the 'allow' lint level?

    $ cat lib.rs
    pub fn foo() {}
    $ rustc lib.rs --crate-type=lib
    $

We can configure this lint to operate at a higher level, both with compiler flags, as well as with an attribute in the source code.

You can also "cap" lints so that the compiler can choose to ignore certain lint levels. We'll talk about that last.

### Via compiler flag

The `-A`, `-W`, `-D`, and `-F` flags let you turn one or more lints into allowed, warning, deny, or forbid levels, like this:

    $ rustc lib.rs --crate-type=lib -W missing-docs
    warning: missing documentation for crate
     --> lib.rs:1:1
      |
    1 | pub fn foo() {}
      | ^^^^^^^^^^^^
      |
      = note: requested on the command line with `-W missing-docs`

    warning: missing documentation for a function
     --> lib.rs:1:1
      |
    1 | pub fn foo() {}
      | ^^^^^^^^^^^^

    $ rustc lib.rs --crate-type=lib -D missing-docs
    error: missing documentation for crate
     --> lib.rs:1:1
      |
    1 | pub fn foo() {}
      | ^^^^^^^^^^^^
      |
      = note: requested on the command line with `-D missing-docs`

    error: missing documentation for a function
     --> lib.rs:1:1
      |
    1 | pub fn foo() {}
      | ^^^^^^^^^^^^

    error: aborting due to 2 previous errors

You can also pass each flag more than once for changing multiple lints:

    $ rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables

And of course, you can mix these four flags together:

    $ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables

The order of these command line arguments is taken into account. The following allows the `unused-variables` lint, because it is the last argument for that lint:

    $ rustc lib.rs --crate-type=lib -D unused-variables -A unused-variables

You can make use of this behavior by overriding the level of one specific lint out of a group of lints. The following example denies all the lints in the `unused` group, but explicitly allows the `unused-variables` lint in that group (forbid still trumps everything regardless of ordering):

    $ rustc lib.rs --crate-type=lib -D unused -A unused-variables

### Via an attribute

You can also modify the lint level with a crate-wide attribute:

    $ cat lib.rs
    #![warn(missing_docs)]

    pub fn foo() {}
    $ rustc lib.rs --crate-type=lib
    warning: missing documentation for crate
     --> lib.rs:1:1
      |
    1 | / #![warn(missing_docs)]
    2 | |
    3 | | pub fn foo() {}
      | |_______________^
      |
    note: lint level defined here
     --> lib.rs:1:9
      |
    1 | #![warn(missing_docs)]
      |         ^^^^^^^^^^^^

    warning: missing documentation for a function
     --> lib.rs:3:1
      |
    3 | pub fn foo() {}
      | ^^^^^^^^^^^^

All four, `warn`, `allow`, `deny`, and `forbid` all work this way.

You can also pass in multiple lints per attribute:

    #![allow(unused)]
    #![warn(missing_docs, unused_variables)]

    fn main() {
    pub fn foo() {}
    }

And use multiple attributes together:

    #![allow(unused)]
    #![warn(missing_docs)]
    #![deny(unused_variables)]

    fn main() {
    pub fn foo() {}
    }

### Capping lints

`rustc` supports a flag, `--cap-lints LEVEL` that sets the "lint cap level." This is the maximum level for all lints. So for example, if we take our code sample from the "deny" lint level above:

    fn main() {
        100u8 << 10;
    }

And we compile it, capping lints to warn:

    $ rustc lib.rs --cap-lints warn
    warning: bitshift exceeds the type's number of bits
     --> lib.rs:2:5
      |
    2 |     100u8 << 10;
      |     ^^^^^^^^^^^
      |
      = note: `#[warn(exceeding_bitshifts)]` on by default

    warning: this expression will panic at run-time
     --> lib.rs:2:5
      |
    2 |     100u8 << 10;
      |     ^^^^^^^^^^^ attempt to shift left with overflow

It now only warns, rather than errors. We can go further and allow all lints:

    $ rustc lib.rs --cap-lints allow
    $

This feature is used heavily by Cargo; it will pass `--cap-lints allow` when compiling your dependencies, so that if they have any warnings, they do not pollute the output of your build.

# Lint Groups

`rustc` has the concept of a "lint group", where you can toggle several warnings through one name.

For example, the `nonstandard-style` lint sets `non-camel-case-types`, `non-snake-case`, and `non-upper-case-globals` all at once. So these are equivalent:

    $ rustc -D nonstandard-style
    $ rustc -D non-camel-case-types -D non-snake-case -D non-upper-case-globals

Here's a list of each lint group, and the lints that they are made up of:

Group | Description | Lints
--- | --- | ---
warnings | All lints that are set to issue warnings | See warn-by-default for the default set of warnings
future-incompatible | Lints that detect code that has future-compatibility problems | absolute-paths-not-starting-with-crate, ambiguous-associated-items, anonymous-parameters, array-into-iter, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, forbidden-lint-groups, ill-formed-attribute-input, illegal-floating-point-literal-pattern, indirect-structural-match, invalid-type-param-default, keyword-idents, late-bound-lifetime-arguments, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, mutable-borrow-reservation-conflict, nontrivial-structural-match, order-dependent-trait-objects, patterns-in-fns-without-body, pointer-structural-match, private-in-public, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, safe-packed-borrows, soft-unstable, tyvar-behind-raw-pointer, uninhabited-static, unstable-name-collisions, unsupported-naked-functions, where-clauses-object-safety
nonstandard-style | Violation of standard naming conventions | non-camel-case-types, non-snake-case, non-upper-case-globals
rust-2018-compatibility | Lints used to transition code from the 2015 edition to 2018 | absolute-paths-not-starting-with-crate, anonymous-parameters, keyword-idents, tyvar-behind-raw-pointer
rust-2018-idioms | Lints to nudge you toward idiomatic features of Rust 2018 | bare-trait-objects, elided-lifetimes-in-paths, ellipsis-inclusive-range-patterns, explicit-outlives-requirements, unused-extern-crates
rustdoc | Rustdoc-specific lints | broken-intra-doc-links, invalid-codeblock-attributes, invalid-html-tags, missing-doc-code-examples, non-autolinks, private-doc-tests, private-intra-doc-links
unused | Lints that detect things being declared but not used, or excess syntax | dead-code, path-statements, redundant-semicolons, unreachable-code, unreachable-patterns, unused-allocation, unused-assignments, unused-attributes, unused-braces, unused-doc-comments, unused-extern-crates, unused-features, unused-imports, unused-labels, unused-macros, unused-must-use, unused-mut, unused-parens, unused-unsafe, unused-variables

Additionally, there's a `bad-style` lint group that's a deprecated alias for `nonstandard-style`.

Finally, you can also see the table above by invoking `rustc -W help`. This will give you the exact values for the specific compiler you have installed.

# Lint listing

This section lists out all of the lints, grouped by their default lint levels.

You can also see this list by running `rustc -W help`.

# Allowed-by-default lints

These lints are all set to the 'allow' level by default. As such, they won't show up unless you set them to a higher lint level with a flag or attribute.

- `absolute_paths_not_starting_with_crate`
- `anonymous_parameters`
- `box_pointers`
- `elided_lifetimes_in_paths`
- `explicit_outlives_requirements`
- `invalid_html_tags`
- `keyword_idents`
- `macro_use_extern_crate`
- `meta_variable_misuse`
- `missing_copy_implementations`
- `missing_crate_level_docs`
- `missing_debug_implementations`
- `missing_doc_code_examples`
- `missing_docs`
- `non_ascii_idents`
- `pointer_structural_match`
- `private_doc_tests`
- `single_use_lifetimes`
- `trivial_casts`
- `trivial_numeric_casts`
- `unaligned_references`
- `unreachable_pub`
- `unsafe_code`
- `unsafe_op_in_unsafe_fn`
- `unstable_features`
- `unused_crate_dependencies`
- `unused_extern_crates`
- `unused_import_braces`
- `unused_lifetimes`
- `unused_qualifications`
- `unused_results`
- `variant_size_differences`

## absolute-paths-not-starting-with-crate

The `absolute_paths_not_starting_with_crate` lint detects fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name

### Example

    #![deny(absolute_paths_not_starting_with_crate)]

    mod foo {
        pub fn bar() {}
    }

    fn main() {
        ::foo::bar();
    }

This will produce:

    error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition
     --> lint_example.rs:8:5
      |
    8 |     ::foo::bar();
      |     ^^^^^^^^^^ help: use `crate`: `crate::foo::bar`
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(absolute_paths_not_starting_with_crate)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
      = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130>

### Explanation

Rust editions allow the language to evolve without breaking backwards compatibility. This lint catches code that uses absolute paths in the style of the 2015 edition. In the 2015 edition, absolute paths (those starting with `::`) refer to either the crate root or an external crate. In the 2018 edition it was changed so that they only refer to external crates. The path prefix `crate::` should be used instead to reference items from the crate root.

If you switch the compiler from the 2015 to 2018 edition without updating the code, then it will fail to compile if the old style paths are used. You can manually change the paths to use the `crate::` prefix to transition to the 2018 edition.

This lint solves the problem automatically. It is "allow" by default because the code is perfectly valid in the 2015 edition. The `cargo fix` tool with the `--edition` flag will switch this lint to "warn" and automatically apply the suggested fix from the compiler. This provides a completely automated way to update old code to the 2018 edition.

## anonymous-parameters

The `anonymous_parameters` lint detects anonymous parameters in trait definitions.

### Example

    #![deny(anonymous_parameters)]
    // edition 2015
    pub trait Foo {
        fn foo(usize);
    }
    fn main() {}

This will produce:

    error: anonymous parameters are deprecated and will be removed in the next edition.
     --> lint_example.rs:4:12
      |
    4 |     fn foo(usize);
      |            ^^^^^ help: try naming the parameter or explicitly ignoring it: `_: usize`
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(anonymous_parameters)]
      |         ^^^^^^^^^^^^^^^^^^^^
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
      = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>

### Explanation

This syntax is mostly a historical accident, and can be worked around quite easily by adding an `_` pattern or a descriptive identifier:

    #![allow(unused)]
    fn main() {
    trait Foo {
        fn foo(_: usize);
    }
    }

This syntax is now a hard error in the 2018 edition. In the 2015 edition, this lint is "allow" by default, because the old code is still valid, and warning for all old code can be noisy. This lint enables the `cargo fix` tool with the `--edition` flag to automatically transition old code from the 2015 edition to 2018. The tool will switch this lint to "warn" and will automatically apply the suggested fix from the compiler (which is to add `_` to each parameter). This provides a completely automated way to update old code for a new edition. See issue #41686 for more details.

## box-pointers

The `box_pointers` lints use of the Box type.

### Example

    #![allow(unused)]
    #![deny(box_pointers)]
    fn main() {
    struct Foo {
        x: Box<isize>,
    }
    }

This will produce:

    error: type uses owned (Box type) pointers: Box<isize>
     --> lint_example.rs:4:5
      |
    4 |     x: Box<isize>,
      |     ^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(box_pointers)]
      |         ^^^^^^^^^^^^

### Explanation

This lint is mostly historical, and not particularly useful. `Box<T>` used to be built into the language, and the only way to do heap allocation. Today's Rust can call into other allocators, etc.

## elided-lifetimes-in-paths

The `elided_lifetimes_in_paths` lint detects the use of hidden lifetime parameters.

### Example

    #![allow(unused)]
    #![deny(elided_lifetimes_in_paths)]
    fn main() {
    struct Foo<'a> {
        x: &'a u32
    }

    fn foo(x: &Foo) {
    }
    }

This will produce:

    error: hidden lifetime parameters in types are deprecated
     --> lint_example.rs:7:12
      |
    7 | fn foo(x: &Foo) {
      |            ^^^- help: indicate the anonymous lifetime: `<'_>`
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(elided_lifetimes_in_paths)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

Elided lifetime parameters can make it difficult to see at a glance that borrowing is occurring. This lint ensures that lifetime parameters are always explicitly stated, even if it is the `'_` placeholder lifetime.

This lint is "allow" by default because it has some known issues, and may require a significant transition for old code.

## explicit-outlives-requirements

The `explicit_outlives_requirements` lint detects unnecessary lifetime bounds that can be inferred.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    #![deny(explicit_outlives_requirements)]

    struct SharedRef<'a, T>
    where
        T: 'a,
    {
        data: &'a T,
    }
    }

This will produce:

    error: outlives requirements can be inferred
     --> lint_example.rs:5:24
      |
    5 |   struct SharedRef<'a, T>
      |  ________________________^
    6 | | where
    7 | |     T: 'a,
      | |__________^ help: remove this bound
      |
    note: the lint level is defined here
     --> lint_example.rs:2:9
      |
    2 | #![deny(explicit_outlives_requirements)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

If a `struct` contains a reference, such as `&'a T`, the compiler requires that `T` outlives the lifetime `'a`. This historically required writing an explicit lifetime bound to indicate this requirement. However, this can be overly explicit, causing clutter and unnecessary complexity. The language was changed to automatically infer the bound if it is not specified. Specifically, if the struct contains a reference, directly or indirectly, to `T` with lifetime `'x`, then it will infer that `T: 'x` is a requirement.

This lint is "allow" by default because it can be noisy for existing code that already had these requirements. This is a stylistic choice, as it is still valid to explicitly state the bound. It also has some false positives that can cause confusion.

See RFC 2093 for more details.

## invalid-html-tags

The `invalid_html_tags` lint detects invalid HTML tags. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## keyword-idents

The `keyword_idents` lint detects edition keywords being used as an identifier.

### Example

    #![allow(unused)]
    #![deny(keyword_idents)]
    fn main() {
    // edition 2015
    fn dyn() {}
    }

This will produce:

    error: `dyn` is a keyword in the 2018 edition
     --> lint_example.rs:4:4
      |
    4 | fn dyn() {}
      |    ^^^ help: you can use a raw identifier to stay compatible: `r#dyn`
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(keyword_idents)]
      |         ^^^^^^^^^^^^^^
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
      = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>

### Explanation

Rust editions allow the language to evolve without breaking backwards compatibility. This lint catches code that uses new keywords that are added to the language that are used as identifiers (such as a variable name, function name, etc.). If you switch the compiler to a new edition without updating the code, then it will fail to compile if you are using a new keyword as an identifier.

You can manually change the identifiers to a non-keyword, or use a raw identifier, for example `r#dyn`, to transition to a new edition.

This lint solves the problem automatically. It is "allow" by default because the code is perfectly valid in older editions. The `cargo fix` tool with the `--edition` flag will switch this lint to "warn" and automatically apply the suggested fix from the compiler (which is to use a raw identifier). This provides a completely automated way to update old code for a new edition.

## macro-use-extern-crate

The `macro_use_extern_crate` lint detects the use of the `macro_use` attribute.

### Example

    #![deny(macro_use_extern_crate)]

    #[macro_use]
    extern crate serde_json;

    fn main() {
        let _ = json!{{}};
    }

This will produce:

    error: deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead
     --> src/main.rs:3:1
      |
    3 | #[macro_use]
      | ^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> src/main.rs:1:9
      |
    1 | #![deny(macro_use_extern_crate)]
      |         ^^^^^^^^^^^^^^^^^^^^^^

### Explanation

The `macro_use` attribute on an `extern crate` item causes macros in that external crate to be brought into the prelude of the crate, making the macros in scope everywhere. As part of the efforts to simplify handling of dependencies in the 2018 edition, the use of `extern crate` is being phased out. To bring macros from extern crates into scope, it is recommended to use a `use` import.

This lint is "allow" by default because this is a stylistic choice that has not been settled, see issue #52043 for more information.

## meta-variable-misuse

The `meta_variable_misuse` lint detects possible meta-variable misuse in macro definitions.

### Example

    #![deny(meta_variable_misuse)]

    macro_rules! foo {
        () => {};
        ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* };
    }

    fn main() {
        foo!();
    }

This will produce:

    error: unknown macro variable `k`
     --> lint_example.rs:5:55
      |
    5 |     ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* };
      |                                                       ^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(meta_variable_misuse)]
      |         ^^^^^^^^^^^^^^^^^^^^

### Explanation

There are quite a few different ways a `macro_rules` macro can be improperly defined. Many of these errors were previously only detected when the macro was expanded or not at all. This lint is an attempt to catch some of these problems when the macro is defined.

This lint is "allow" by default because it may have false positives and other issues. See issue #61053 for more details.

## missing-copy-implementations

The `missing_copy_implementations` lint detects potentially-forgotten implementations of `Copy`.

### Example

    #![deny(missing_copy_implementations)]
    pub struct Foo {
        pub field: i32
    }
    fn main() {}

This will produce:

    error: type could implement `Copy`; consider adding `impl Copy`
     --> lint_example.rs:2:1
      |
    2 | / pub struct Foo {
    3 | |     pub field: i32
    4 | | }
      | |_^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(missing_copy_implementations)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

Historically (before 1.0), types were automatically marked as `Copy` if possible. This was changed so that it required an explicit opt-in by implementing the `Copy` trait. As part of this change, a lint was added to alert if a copyable type was not marked `Copy`.

This lint is "allow" by default because this code isn't bad; it is common to write newtypes like this specifically so that a `Copy` type is no longer `Copy`. `Copy` types can result in unintended copies of large data which can impact performance.

## missing-crate-level-docs

The `missing_crate_level_docs` lint detects if documentation is missing at the crate root. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## missing-debug-implementations

The `missing_debug_implementations` lint detects missing implementations of `fmt::Debug`.

### Example

    #![deny(missing_debug_implementations)]
    pub struct Foo;
    fn main() {}

This will produce:

    error: type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation
     --> lint_example.rs:2:1
      |
    2 | pub struct Foo;
      | ^^^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(missing_debug_implementations)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

Having a `Debug` implementation on all types can assist with debugging, as it provides a convenient way to format and display a value. Using the `#[derive(Debug)]` attribute will automatically generate a typical implementation, or a custom implementation can be added by manually implementing the `Debug` trait.

This lint is "allow" by default because adding `Debug` to all types can have a negative impact on compile time and code size. It also requires boilerplate to be added to every type, which can be an impediment.

## missing-doc-code-examples

The `missing_doc_code_examples` lint detects publicly-exported items without code samples in their documentation. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## missing-docs

The `missing_docs` lint detects missing documentation for public items.

### Example

    #![allow(unused)]
    #![deny(missing_docs)]
    fn main() {
    pub fn foo() {}
    }

This will produce:

    error: missing documentation for the crate
     --> lint_example.rs:1:1
      |
    1 | / #![deny(missing_docs)]
    2 | | fn main() {
    3 | | pub fn foo() {}
    4 | | }
      | |_^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(missing_docs)]
      |         ^^^^^^^^^^^^

### Explanation

This lint is intended to ensure that a library is well-documented. Items without documentation can be difficult for users to understand how to use properly.

This lint is "allow" by default because it can be noisy, and not all projects may want to enforce everything to be documented.

## non-ascii-idents

The `non_ascii_idents` lint detects non-ASCII identifiers.

### Example

    #![allow(unused)]
    #![feature(non_ascii_idents)]
    #![deny(non_ascii_idents)]
    fn main() {
        let föö = 1;
    }

This will produce:

    error: identifier contains non-ASCII characters
     --> lint_example.rs:5:9
      |
    5 |     let föö = 1;
      |         ^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:3:9
      |
    3 | #![deny(non_ascii_idents)]
      |         ^^^^^^^^^^^^^^^^

### Explanation

Currently on stable Rust, identifiers must contain ASCII characters. The `non_ascii_idents` nightly-only feature allows identifiers to contain non-ASCII characters. This lint allows projects that wish to retain the limit of only using ASCII characters to switch this lint to "forbid" (for example to ease collaboration or for security reasons). See RFC 2457 for more details.

## pointer-structural-match

The `pointer_structural_match` lint detects pointers used in patterns whose behaviour cannot be relied upon across compiler versions and optimization levels.

### Example

    #![deny(pointer_structural_match)]
    fn foo(a: usize, b: usize) -> usize { a + b }
    const FOO: fn(usize, usize) -> usize = foo;
    fn main() {
        match FOO {
            FOO => {},
            _ => {},
        }
    }

This will produce:

    error: function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
     --> lint_example.rs:6:9
      |
    6 |         FOO => {},
      |         ^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(pointer_structural_match)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>

### Explanation

Previous versions of Rust allowed function pointers and wide raw pointers in patterns. While these work in many cases as expected by users, it is possible that due to optimizations pointers are "not equal to themselves" or pointers to different functions compare as equal during runtime. This is because LLVM optimizations can deduplicate functions if their bodies are the same, thus also making pointers to these functions point to the same location. Additionally functions may get duplicated if they are instantiated in different crates and not deduplicated again via LTO.

## private-doc-tests

The `private_doc_tests` lint detects code samples in docs of private items not documented by `rustdoc`. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## single-use-lifetimes

The `single_use_lifetimes` lint detects lifetimes that are only used once.

### Example

    #![allow(unused)]
    #![deny(single_use_lifetimes)]

    fn main() {
    fn foo<'a>(x: &'a u32) {}
    }

This will produce:

    error: lifetime parameter `'a` only used once
     --> lint_example.rs:4:8
      |
    4 | fn foo<'a>(x: &'a u32) {}
      |        ^^      -- ...is used only here
      |        |
      |        this lifetime...
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(single_use_lifetimes)]
      |         ^^^^^^^^^^^^^^^^^^^^
    help: elide the single-use lifetime
      |
    4 | fn foo(x: &u32) {}
      |      --   --

### Explanation

Specifying an explicit lifetime like `'a` in a function or `impl` should only be used to link together two things. Otherwise, you should just use `'_` to indicate that the lifetime is not linked to anything, or elide the lifetime altogether if possible.

This lint is "allow" by default because it was introduced at a time when `'_` and elided lifetimes were first being introduced, and this lint would be too noisy. Also, there are some known false positives that it produces. See RFC 2115 for historical context, and issue #44752 for more details.

## trivial-casts

The `trivial_casts` lint detects trivial casts which could be replaced with coercion, which may require type ascription or a temporary variable.

### Example

    #![allow(unused)]
    #![deny(trivial_casts)]
    fn main() {
    let x: &u32 = &42;
    let y = x as *const u32;
    }

This will produce:

    error: trivial cast: `&u32` as `*const u32`
     --> lint_example.rs:4:9
      |
    4 | let y = x as *const u32;
      |         ^^^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(trivial_casts)]
      |         ^^^^^^^^^^^^^
      = help: cast can be replaced by coercion; this might require a temporary variable

### Explanation

A trivial cast is a cast `e as T` where `e` has type `U` and `U` is a subtype of `T`. This type of cast is usually unnecessary, as it can be usually be inferred.

This lint is "allow" by default because there are situations, such as with FFI interfaces or complex type aliases, where it triggers incorrectly, or in situations where it will be more difficult to clearly express the intent. It may be possible that this will become a warning in the future, possibly with type ascription providing a convenient way to work around the current issues. See RFC 401 for historical context.

## trivial-numeric-casts

The `trivial_numeric_casts` lint detects trivial numeric casts of types which could be removed.

### Example

    #![allow(unused)]
    #![deny(trivial_numeric_casts)]
    fn main() {
    let x = 42_i32 as i32;
    }

This will produce:

    error: trivial numeric cast: `i32` as `i32`
     --> lint_example.rs:3:9
      |
    3 | let x = 42_i32 as i32;
      |         ^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(trivial_numeric_casts)]
      |         ^^^^^^^^^^^^^^^^^^^^^
      = help: cast can be replaced by coercion; this might require a temporary variable

### Explanation

A trivial numeric cast is a cast of a numeric type to the same numeric type. This type of cast is usually unnecessary.

This lint is "allow" by default because there are situations, such as with FFI interfaces or complex type aliases, where it triggers incorrectly, or in situations where it will be more difficult to clearly express the intent. It may be possible that this will become a warning in the future, possibly with type ascription providing a convenient way to work around the current issues. See RFC 401 for historical context.

## unaligned-references

The `unaligned_references` lint detects unaligned references to fields of packed structs.

### Example

    #![deny(unaligned_references)]

    #[repr(packed)]
    pub struct Foo {
        field1: u64,
        field2: u8,
    }

    fn main() {
        unsafe {
            let foo = Foo { field1: 0, field2: 0 };
            let _ = &foo.field1;
        }
    }

This will produce:

    error: reference to packed field is unaligned
      --> lint_example.rs:12:17
       |
    12 |         let _ = &foo.field1;
       |                 ^^^^^^^^^^^
       |
    note: the lint level is defined here
      --> lint_example.rs:1:9
       |
    1  | #![deny(unaligned_references)]
       |         ^^^^^^^^^^^^^^^^^^^^
       = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)

### Explanation

Creating a reference to an insufficiently aligned packed field is undefined behavior and should be disallowed.

This lint is "allow" by default because there is no stable alternative, and it is not yet certain how widespread existing code will trigger this lint.

See issue #27060 for more discussion.

## unreachable-pub

The `unreachable_pub` lint triggers for `pub` items not reachable from the crate root.

### Example

    #![allow(unused)]
    #![deny(unreachable_pub)]
    fn main() {
    mod foo {
        pub mod bar {

        }
    }
    }

This will produce:

    error: unreachable `pub` item
     --> lint_example.rs:4:5
      |
    4 |     pub mod bar {
      |     ---^^^^^^^^
      |     |
      |     help: consider restricting its visibility: `pub(crate)`
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(unreachable_pub)]
      |         ^^^^^^^^^^^^^^^
      = help: or consider exporting it for use by other crates

### Explanation

A bare `pub` visibility may be misleading if the item is not actually publicly exported from the crate. The `pub(crate)` visibility is recommended to be used instead, which more clearly expresses the intent that the item is only visible within its own crate.

This lint is "allow" by default because it will trigger for a large amount existing Rust code, and has some false-positives. Eventually it is desired for this to become warn-by-default.

## unsafe-code

The `unsafe_code` lint catches usage of `unsafe` code.

### Example

    #![deny(unsafe_code)]
    fn main() {
        unsafe {

        }
    }

This will produce:

    error: usage of an `unsafe` block
     --> lint_example.rs:3:5
      |
    3 | /     unsafe {
    4 | |
    5 | |     }
      | |_____^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(unsafe_code)]
      |         ^^^^^^^^^^^

### Explanation

This lint is intended to restrict the usage of `unsafe`, which can be difficult to use correctly.

## unsafe-op-in-unsafe-fn

The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe functions without an explicit unsafe block. This lint only works on the nightly channel with the `#![feature(unsafe_block_in_unsafe_fn)]` feature.

### Example

    #![feature(unsafe_block_in_unsafe_fn)]
    #![deny(unsafe_op_in_unsafe_fn)]

    unsafe fn foo() {}

    unsafe fn bar() {
        foo();
    }

    fn main() {}

This will produce:

    error: call to unsafe function is unsafe and requires unsafe block (error E0133)
     --> lint_example.rs:7:5
      |
    7 |     foo();
      |     ^^^^^ call to unsafe function
      |
    note: the lint level is defined here
     --> lint_example.rs:2:9
      |
    2 | #![deny(unsafe_op_in_unsafe_fn)]
      |         ^^^^^^^^^^^^^^^^^^^^^^
      = note: consult the function's documentation for information on how to avoid undefined behavior

### Explanation

Currently, an `unsafe fn` allows any unsafe operation within its body. However, this can increase the surface area of code that needs to be scrutinized for proper behavior. The `unsafe` block provides a convenient way to make it clear exactly which parts of the code are performing unsafe operations. In the future, it is desired to change it so that unsafe operations cannot be performed in an `unsafe fn` without an `unsafe` block.

The fix to this is to wrap the unsafe code in an `unsafe` block.

This lint is "allow" by default because it has not yet been stabilized, and is not yet complete. See RFC #2585 and issue #71668 for more details

## unstable-features

The `unstable_features` is deprecated and should no longer be used.

## unused-crate-dependencies

The `unused_crate_dependencies` lint detects crate dependencies that are never used.

### Example

    #![deny(unused_crate_dependencies)]

This will produce:

    error: external crate `regex` unused in `lint_example`: remove the dependency or add `use regex as _;`
      |
    note: the lint level is defined here
     --> src/lib.rs:1:9
      |
    1 | #![deny(unused_crate_dependencies)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

After removing the code that uses a dependency, this usually also requires removing the dependency from the build configuration. However, sometimes that step can be missed, which leads to time wasted building dependencies that are no longer used. This lint can be enabled to detect dependencies that are never used (more specifically, any dependency passed with the `--extern` command-line flag that is never referenced via `use`, `extern crate`, or in any path).

This lint is "allow" by default because it can provide false positives depending on how the build system is configured. For example, when using Cargo, a "package" consists of multiple crates (such as a library and a binary), but the dependencies are defined for the package as a whole. If there is a dependency that is only used in the binary, but not the library, then the lint will be incorrectly issued in the library.

## unused-extern-crates

The `unused_extern_crates` lint guards against `extern crate` items that are never used.

### Example

    #![allow(unused)]
    #![deny(unused_extern_crates)]
    fn main() {
    extern crate proc_macro;
    }

This will produce:

    error: unused extern crate
     --> lint_example.rs:3:1
      |
    3 | extern crate proc_macro;
      | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(unused_extern_crates)]
      |         ^^^^^^^^^^^^^^^^^^^^

### Explanation

`extern crate` items that are unused have no effect and should be removed. Note that there are some cases where specifying an `extern crate` is desired for the side effect of ensuring the given crate is linked, even though it is not otherwise directly referenced. The lint can be silenced by aliasing the crate to an underscore, such as `extern crate foo as _`. Also note that it is no longer idiomatic to use `extern crate` in the 2018 edition, as extern crates are now automatically added in scope.

This lint is "allow" by default because it can be noisy, and produce false-positives. If a dependency is being removed from a project, it is recommended to remove it from the build configuration (such as `Cargo.toml`) to ensure stale build entries aren't left behind.

## unused-import-braces

The `unused_import_braces` lint catches unnecessary braces around an imported item.

### Example

    #![deny(unused_import_braces)]
    use test::{A};

    pub mod test {
        pub struct A;
    }
    fn main() {}

This will produce:

    error: braces around A is unnecessary
     --> lint_example.rs:2:1
      |
    2 | use test::{A};
      | ^^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(unused_import_braces)]
      |         ^^^^^^^^^^^^^^^^^^^^

### Explanation

If there is only a single item, then remove the braces (`use test::A;` for example).

This lint is "allow" by default because it is only enforcing a stylistic choice.

## unused-lifetimes

The `unused_lifetimes` lint detects lifetime parameters that are never used.

### Example

    #![allow(unused)]
    fn main() {
    #[deny(unused_lifetimes)]

    pub fn foo<'a>() {}
    }

This will produce:

    error: lifetime parameter `'a` never used
     --> lint_example.rs:4:12
      |
    4 | pub fn foo<'a>() {}
      |           -^^- help: elide the unused lifetime
      |
    note: the lint level is defined here
     --> lint_example.rs:2:8
      |
    2 | #[deny(unused_lifetimes)]
      |        ^^^^^^^^^^^^^^^^

### Explanation

Unused lifetime parameters may signal a mistake or unfinished code. Consider removing the parameter.

## unused-qualifications

The `unused_qualifications` lint detects unnecessarily qualified names.

### Example

    #![deny(unused_qualifications)]
    mod foo {
        pub fn bar() {}
    }

    fn main() {
        use foo::bar;
        foo::bar();
    }

This will produce:

    error: unnecessary qualification
     --> lint_example.rs:8:5
      |
    8 |     foo::bar();
      |     ^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(unused_qualifications)]
      |         ^^^^^^^^^^^^^^^^^^^^^

### Explanation

If an item from another module is already brought into scope, then there is no need to qualify it in this case. You can call `bar()` directly, without the `foo::`.

This lint is "allow" by default because it is somewhat pedantic, and doesn't indicate an actual problem, but rather a stylistic choice, and can be noisy when refactoring or moving around code.

## unused-results

The `unused_results` lint checks for the unused result of an expression in a statement.

### Example

    #![deny(unused_results)]
    fn foo<T>() -> T { panic!() }

    fn main() {
        foo::<usize>();
    }

This will produce:

    error: unused result
     --> lint_example.rs:5:5
      |
    5 |     foo::<usize>();
      |     ^^^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(unused_results)]
      |         ^^^^^^^^^^^^^^

### Explanation

Ignoring the return value of a function may indicate a mistake. In cases were it is almost certain that the result should be used, it is recommended to annotate the function with the `must_use` attribute. Failure to use such a return value will trigger the `unused_must_use` lint which is warn-by-default. The `unused_results` lint is essentially the same, but triggers for all return values.

This lint is "allow" by default because it can be noisy, and may not be an actual problem. For example, calling the `remove` method of a `Vec` or `HashMap` returns the previous value, which you may not care about. Using this lint would require explicitly ignoring or discarding such values.

## variant-size-differences

The `variant_size_differences` lint detects enums with widely varying variant sizes.

### Example

    #![allow(unused)]
    #![deny(variant_size_differences)]
    fn main() {
    enum En {
        V0(u8),
        VBig([u8; 1024]),
    }
    }

This will produce:

    error: enum variant is more than three times larger (1024 bytes) than the next largest
     --> lint_example.rs:5:5
      |
    5 |     VBig([u8; 1024]),
      |     ^^^^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(variant_size_differences)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

It can be a mistake to add a variant to an enum that is much larger than the other variants, bloating the overall size required for all variants. This can impact performance and memory usage. This is triggered if one variant is more than 3 times larger than the second-largest variant.

Consider placing the large variant's contents on the heap (for example via `Box`) to keep the overall size of the enum itself down.

This lint is "allow" by default because it can be noisy, and may not be an actual problem. Decisions about this should be guided with profiling and benchmarking.

# Warn-by-default lints

These lints are all set to the 'warn' level by default.

- `array_into_iter`
- `asm_sub_register`
- `bare_trait_objects`
- `bindings_with_variant_name`
- `broken_intra_doc_links`
- `cenum_impl_drop_cast`
- `clashing_extern_declarations`
- `coherence_leak_check`
- `confusable_idents`
- `const_evaluatable_unchecked`
- `const_item_mutation`
- `dead_code`
- `deprecated`
- `drop_bounds`
- `ellipsis_inclusive_range_patterns`
- `exported_private_dependencies`
- `forbidden_lint_groups`
- `function_item_references`
- `illegal_floating_point_literal_pattern`
- `improper_ctypes`
- `improper_ctypes_definitions`
- `incomplete_features`
- `indirect_structural_match`
- `inline_no_sanitize`
- `invalid_codeblock_attributes`
- `invalid_value`
- `irrefutable_let_patterns`
- `late_bound_lifetime_arguments`
- `mixed_script_confusables`
- `mutable_borrow_reservation_conflict`
- `no_mangle_generic_items`
- `non_autolinks`
- `non_camel_case_types`
- `non_fmt_panic`
- `non_shorthand_field_patterns`
- `non_snake_case`
- `non_upper_case_globals`
- `nontrivial_structural_match`
- `overlapping_range_endpoints`
- `path_statements`
- `private_in_public`
- `private_intra_doc_links`
- `proc_macro_derive_resolution_fallback`
- `redundant_semicolons`
- `renamed_and_removed_lints`
- `safe_packed_borrows`
- `stable_features`
- `temporary_cstring_as_ptr`
- `trivial_bounds`
- `type_alias_bounds`
- `tyvar_behind_raw_pointer`
- `uncommon_codepoints`
- `unconditional_recursion`
- `uninhabited_static`
- `unknown_lints`
- `unnameable_test_items`
- `unreachable_code`
- `unreachable_patterns`
- `unstable_name_collisions`
- `unsupported_naked_functions`
- `unused_allocation`
- `unused_assignments`
- `unused_attributes`
- `unused_braces`
- `unused_comparisons`
- `unused_doc_comments`
- `unused_features`
- `unused_imports`
- `unused_labels`
- `unused_macros`
- `unused_must_use`
- `unused_mut`
- `unused_parens`
- `unused_unsafe`
- `unused_variables`
- `warnings`
- `where_clauses_object_safety`
- `while_true`

## array-into-iter

The `array_into_iter` lint detects calling `into_iter` on arrays.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    [1, 2, 3].into_iter().for_each(|n| { *n; });
    }

This will produce:

    warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
     --> lint_example.rs:3:11
      |
    3 | [1, 2, 3].into_iter().for_each(|n| { *n; });
      |           ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
      |
      = note: `#[warn(array_into_iter)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>

### Explanation

In the future, it is planned to add an `IntoIter` implementation for arrays such that it will iterate over values of the array instead of references. Due to how method resolution works, this will change existing code that uses `into_iter` on arrays. The solution to avoid this warning is to use `iter()` instead of `into_iter()`.

This is a future-incompatible lint to transition this to a hard error in the future. See issue #66145 for more details and a more thorough description of the lint.

## asm-sub-register

The `asm_sub_register` lint detects using only a subset of a register for inline asm inputs.

### Example

    #![feature(asm)]

    fn main() {
        #[cfg(target_arch="x86_64")]
        unsafe {
            asm!("mov {0}, {0}", in(reg) 0i16);
        }
    }

This will produce:

    warning: formatting may not be suitable for sub-register argument
     --> src/main.rs:6:19
      |
    6 |         asm!("mov {0}, {0}", in(reg) 0i16);
      |                   ^^^  ^^^           ---- for this argument
      |
      = note: `#[warn(asm_sub_register)]` on by default
      = help: use the `x` modifier to have the register formatted as `ax`
      = help: or use the `r` modifier to keep the default formatting of `rax`

### Explanation

Registers on some architectures can use different names to refer to a subset of the register. By default, the compiler will use the name for the full register size. To explicitly use a subset of the register, you can override the default by using a modifier on the template string operand to specify when subregister to use. This lint is issued if you pass in a value with a smaller data type than the default register size, to alert you of possibly using the incorrect width. To fix this, add the suggested modifier to the template, or cast the value to the correct size.

See register template modifiers for more details.

## bare-trait-objects

The `bare_trait_objects` lint suggests using `dyn Trait` for trait objects.

### Example

    #![allow(unused)]
    fn main() {
    trait Trait { }

    fn takes_trait_object(_: Box<Trait>) {
    }
    }

This will produce:

    warning: trait objects without an explicit `dyn` are deprecated
     --> lint_example.rs:4:30
      |
    4 | fn takes_trait_object(_: Box<Trait>) {
      |                              ^^^^^ help: use `dyn`: `dyn Trait`
      |
      = note: `#[warn(bare_trait_objects)]` on by default

### Explanation

Without the `dyn` indicator, it can be ambiguous or confusing when reading code as to whether or not you are looking at a trait object. The `dyn` keyword makes it explicit, and adds a symmetry to contrast with `impl Trait`.

## bindings-with-variant-name

The `bindings_with_variant_name` lint detects pattern bindings with the same name as one of the matched variants.

### Example

    #![allow(unused)]
    fn main() {
    pub enum Enum {
        Foo,
        Bar,
    }

    pub fn foo(x: Enum) {
        match x {
            Foo => {}
            Bar => {}
        }
    }
    }

This will produce:

    warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `Enum`
     --> lint_example.rs:9:9
      |
    9 |         Foo => {}
      |         ^^^ help: to match on the variant, qualify the path: `Enum::Foo`
      |
      = note: `#[warn(bindings_with_variant_name)]` on by default

### Explanation

It is usually a mistake to specify an enum variant name as an identifier pattern. In the example above, the `match` arms are specifying a variable name to bind the value of `x` to. The second arm is ignored because the first one matches all values. The likely intent is that the arm was intended to match on the enum variant.

Two possible solutions are:

- Specify the enum variant using a path pattern, such as `Enum::Foo`.
- Bring the enum variants into local scope, such as adding `use Enum::*;` to the beginning of the `foo` function in the example above.

## broken-intra-doc-links

The `broken_intra_doc_links` lint detects failures in resolving intra-doc link targets. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## cenum-impl-drop-cast

The `cenum_impl_drop_cast` lint detects an `as` cast of a field-less `enum` that implements `Drop`.

### Example

    #![allow(unused)]
    enum E {
        A,
    }

    impl Drop for E {
        fn drop(&mut self) {
            println!("Drop");
        }
    }

    fn main() {
        let e = E::A;
        let i = e as u32;
    }

This will produce:

    warning: cannot cast enum `E` into integer `u32` because it implements `Drop`
      --> lint_example.rs:14:13
       |
    14 |     let i = e as u32;
       |             ^^^^^^^^
       |
       = note: `#[warn(cenum_impl_drop_cast)]` on by default
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333>

### Explanation

Casting a field-less `enum` that does not implement `Copy` to an integer moves the value without calling `drop`. This can result in surprising behavior if it was expected that `drop` should be called. Calling `drop` automatically would be inconsistent with other move operations. Since neither behavior is clear or consistent, it was decided that a cast of this nature will no longer be allowed.

This is a future-incompatible lint to transition this to a hard error in the future. See issue #73333 for more details.

## clashing-extern-declarations

The `clashing_extern_declarations` lint detects when an `extern fn` has been declared with the same name but different types.

### Example

    #![allow(unused)]
    fn main() {
    mod m {
        extern "C" {
            fn foo();
        }
    }

    extern "C" {
        fn foo(_: u32);
    }
    }

This will produce:

    warning: `foo` redeclared with a different signature
     --> lint_example.rs:9:5
      |
    4 |         fn foo();
      |         --------- `foo` previously declared here
    ...
    9 |     fn foo(_: u32);
      |     ^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
      |
      = note: `#[warn(clashing_extern_declarations)]` on by default
      = note: expected `unsafe extern "C" fn()`
                 found `unsafe extern "C" fn(u32)`

### Explanation

Because two symbols of the same name cannot be resolved to two different functions at link time, and one function cannot possibly have two types, a clashing extern declaration is almost certainly a mistake. Check to make sure that the `extern` definitions are correct and equivalent, and possibly consider unifying them in one location.

This lint does not run between crates because a project may have dependencies which both rely on the same extern function, but declare it in a different (but valid) way. For example, they may both declare an opaque type for one or more of the arguments (which would end up distinct types), or use types that are valid conversions in the language the `extern fn` is defined in. In these cases, the compiler can't say that the clashing declaration is incorrect.

## coherence-leak-check

The `coherence_leak_check` lint detects conflicting implementations of a trait that are only distinguished by the old leak-check code.

### Example

    #![allow(unused)]
    fn main() {
    trait SomeTrait { }
    impl SomeTrait for for<'a> fn(&'a u8) { }
    impl<'a> SomeTrait for fn(&'a u8) { }
    }

This will produce:

    warning: conflicting implementations of trait `main::SomeTrait` for type `for<'a> fn(&'a u8)`:
     --> lint_example.rs:4:1
      |
    3 | impl SomeTrait for for<'a> fn(&'a u8) { }
      | ------------------------------------- first implementation here
    4 | impl<'a> SomeTrait for fn(&'a u8) { }
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a u8)`
      |
      = note: `#[warn(coherence_leak_check)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
      = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details

### Explanation

In the past, the compiler would accept trait implementations for identical functions that differed only in where the lifetime binder appeared. Due to a change in the borrow checker implementation to fix several bugs, this is no longer allowed. However, since this affects existing code, this is a future-incompatible lint to transition this to a hard error in the future.

Code relying on this pattern should introduce "newtypes", like `struct Foo(for<'a> fn(&'a u8))`.

See issue #56105 for more details.

## confusable-idents

The `confusable_idents` lint detects visually confusable pairs between identifiers.

### Example

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

    fn main() {
    // Latin Capital Letter E With Caron
    pub const Ě: i32 = 1;
    // Latin Capital Letter E With Breve
    pub const Ĕ: i32 = 2;
    }

This will produce:

    warning: identifier pair considered confusable between `Ě` and `Ĕ`
     --> lint_example.rs:7:11
      |
    5 | pub const Ě: i32 = 1;
      |           - this is where the previous identifier occurred
    6 | // Latin Capital Letter E With Breve
    7 | pub const Ĕ: i32 = 2;
      |           ^
      |
      = note: `#[warn(confusable_idents)]` on by default

### Explanation

With the `non_ascii_idents` nightly-only feature enabled, identifiers are allowed to use non-ASCII characters. This lint warns when different identifiers may appear visually similar, which can cause confusion.

The confusable detection algorithm is based on Unicode® Technical Standard #39 Unicode Security Mechanisms Section 4 Confusable Detection. For every distinct identifier X execute the function `skeleton(X)`. If there exist two distinct identifiers X and Y in the same crate where `skeleton(X) = skeleton(Y)` report it. The compiler uses the same mechanism to check if an identifier is too similar to a keyword.

Note that the set of confusable characters may change over time. Beware that if you "forbid" this lint that existing code may fail in the future.

## const-evaluatable-unchecked

The `const_evaluatable_unchecked` lint detects a generic constant used in a type.

### Example

    #![allow(unused)]
    fn main() {
    const fn foo<T>() -> usize {
        if std::mem::size_of::<*mut T>() < 8 { // size of *mut T does not depend on T
            4
        } else {
            8
        }
    }

    fn test<T>() {
        let _ = [0; foo::<T>()];
    }
    }

This will produce:

    warning: cannot use constants which depend on generic parameters in types
      --> lint_example.rs:11:17
       |
    11 |     let _ = [0; foo::<T>()];
       |                 ^^^^^^^^^^
       |
       = note: `#[warn(const_evaluatable_unchecked)]` on by default
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>

### Explanation

In the 1.43 release, some uses of generic parameters in array repeat expressions were accidentally allowed. This is a future-incompatible lint to transition this to a hard error in the future. See issue #76200 for a more detailed description and possible fixes.

## const-item-mutation

The `const_item_mutation` lint detects attempts to mutate a `const` item.

### Example

    const FOO: [i32; 1] = [0];

    fn main() {
        FOO[0] = 1;
        // This will print "[0]".
        println!("{:?}", FOO);
    }

This will produce:

    warning: attempting to modify a `const` item
     --> lint_example.rs:4:5
      |
    4 |     FOO[0] = 1;
      |     ^^^^^^^^^^
      |
      = note: `#[warn(const_item_mutation)]` on by default
      = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
    note: `const` item defined here
     --> lint_example.rs:1:1
      |
    1 | const FOO: [i32; 1] = [0];
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^

### Explanation

Trying to directly mutate a `const` item is almost always a mistake. What is happening in the example above is that a temporary copy of the `const` is mutated, but the original `const` is not. Each time you refer to the `const` by name (such as `FOO` in the example above), a separate copy of the value is inlined at that location.

This lint checks for writing directly to a field (`FOO.field = some_value`) or array entry (`FOO[0] = val`), or taking a mutable reference to the const item (`&mut FOO`), including through an autoderef (`FOO.some_mut_self_method()`).

There are various alternatives depending on what you are trying to accomplish:

- First, always reconsider using mutable globals, as they can be difficult to use correctly, and can make the code more difficult to use or understand.
- If you are trying to perform a one-time initialization of a global:
  - If the value can be computed at compile-time, consider using const-compatible values (see Constant Evaluation).
  - For more complex single-initialization cases, consider using a third-party crate, such as `lazy_static` or `once_cell`.
  - If you are using the nightly channel, consider the new `lazy` module in the standard library.
- If you truly need a mutable global, consider using a `static`, which has a variety of options:
  - Simple data types can be directly defined and mutated with an `atomic` type.
  - More complex types can be placed in a synchronization primitive like a `Mutex`, which can be initialized with one of the options listed above.
  - A mutable `static` is a low-level primitive, requiring unsafe. Typically This should be avoided in preference of something higher-level like one of the above.

## dead-code

The `dead_code` lint detects unused, unexported items.

### Example

    #![allow(unused)]
    fn main() {
    fn foo() {}
    }

This will produce:

    warning: function is never used: `foo`
     --> lint_example.rs:2:4
      |
    2 | fn foo() {}
      |    ^^^
      |
      = note: `#[warn(dead_code)]` on by default

### Explanation

Dead code may signal a mistake or unfinished code. To silence the warning for individual items, prefix the name with an underscore such as `_foo`. If it was intended to expose the item outside of the crate, consider adding a visibility modifier like `pub`. Otherwise consider removing the unused code.

## deprecated

The `deprecated` lint detects use of deprecated items.

### Example

    #![allow(unused)]
    fn main() {
    #[deprecated]
    fn foo() {}

    fn bar() {
        foo();
    }
    }

This will produce:

    warning: use of deprecated function `main::foo`
     --> lint_example.rs:6:5
      |
    6 |     foo();
      |     ^^^
      |
      = note: `#[warn(deprecated)]` on by default

### Explanation

Items may be marked "deprecated" with the `deprecated` attribute to indicate that they should no longer be used. Usually the attribute should include a note on what to use instead, or check the documentation.

## drop-bounds

The `drop_bounds` lint checks for generics with `std::ops::Drop` as bounds.

### Example

    #![allow(unused)]
    fn main() {
    fn foo<T: Drop>() {}
    }

This will produce:

    warning: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor
     --> lint_example.rs:2:11
      |
    2 | fn foo<T: Drop>() {}
      |           ^^^^
      |
      = note: `#[warn(drop_bounds)]` on by default

### Explanation

`Drop` bounds do not really accomplish anything. A type may have compiler-generated drop glue without implementing the `Drop` trait itself. The `Drop` trait also only has one method, `Drop::drop`, and that function is by fiat not callable in user code. So there is really no use case for using `Drop` in trait bounds.

The most likely use case of a drop bound is to distinguish between types that have destructors and types that don't. Combined with specialization, a naive coder would write an implementation that assumed a type could be trivially dropped, then write a specialization for `T: Drop` that actually calls the destructor. Except that doing so is not correct; String, for example, doesn't actually implement Drop, but because String contains a Vec, assuming it can be trivially dropped will leak memory.

## ellipsis-inclusive-range-patterns

The `ellipsis_inclusive_range_patterns` lint detects the `...` range pattern, which is deprecated.

### Example

    #![allow(unused)]
    fn main() {
    let x = 123;
    match x {
        0...100 => {}
        _ => {}
    }
    }

This will produce:

    warning: `...` range patterns are deprecated
     --> lint_example.rs:4:6
      |
    4 |     0...100 => {}
      |      ^^^ help: use `..=` for an inclusive range
      |
      = note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default

### Explanation

The `...` range pattern syntax was changed to `..=` to avoid potential confusion with the `..` range expression. Use the new form instead.

## exported-private-dependencies

The `exported_private_dependencies` lint detects private dependencies that are exposed in a public interface.

### Example

    pub fn foo() -> Option<some_private_dependency::Thing> {
        None
    }

This will produce:

    warning: type `bar::Thing` from private dependency 'bar' in public interface
     --> src/lib.rs:3:1
      |
    3 | pub fn foo() -> Option<bar::Thing> {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(exported_private_dependencies)]` on by default

### Explanation

Dependencies can be marked as "private" to indicate that they are not exposed in the public interface of a crate. This can be used by Cargo to independently resolve those dependencies because it can assume it does not need to unify them with other packages using that same dependency. This lint is an indication of a violation of that contract.

To fix this, avoid exposing the dependency in your public interface. Or, switch the dependency to a public dependency.

Note that support for this is only available on the nightly channel. See RFC 1977 for more details, as well as the Cargo documentation.

## forbidden-lint-groups

The `forbidden_lint_groups` lint detects violations of `forbid` applied to a lint group. Due to a bug in the compiler, these used to be overlooked entirely. They now generate a warning.

### Example

    #![forbid(warnings)]
    #![deny(bad_style)]

    fn main() {}

This will produce:

    warning: deny(bad_style) incompatible with previous forbid
     --> lint_example.rs:2:9
      |
    1 | #![forbid(warnings)]
      |           -------- `forbid` level set here
    2 | #![deny(bad_style)]
      |         ^^^^^^^^^ overruled by previous forbid
      |
      = note: `#[warn(forbidden_lint_groups)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>

### Recommended fix

If your crate is using `#![forbid(warnings)]`, we recommend that you change to `#![deny(warnings)]`.

### Explanation

Due to a compiler bug, applying `forbid` to lint groups previously had no effect. The bug is now fixed but instead of enforcing `forbid` we issue this future-compatibility warning to avoid breaking existing crates.

## function-item-references

The `function_item_references` lint detects function references that are formatted with `fmt::Pointer` or transmuted.

### Example

    fn foo() { }

    fn main() {
        println!("{:p}", &foo);
    }

This will produce:

    warning: taking a reference to a function item does not give a function pointer
     --> lint_example.rs:4:22
      |
    4 |     println!("{:p}", &foo);
      |                      ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn()`
      |
      = note: `#[warn(function_item_references)]` on by default

### Explanation

Taking a reference to a function may be mistaken as a way to obtain a pointer to that function. This can give unexpected results when formatting the reference as a pointer or transmuting it. This lint is issued when function references are formatted as pointers, passed as arguments bound by `fmt::Pointer` or transmuted.

## illegal-floating-point-literal-pattern

The `illegal_floating_point_literal_pattern` lint detects floating-point literals used in patterns.

### Example

    #![allow(unused)]
    fn main() {
    let x = 42.0;

    match x {
        5.0 => {}
        _ => {}
    }
    }

This will produce:

    warning: floating-point types cannot be used in patterns
     --> lint_example.rs:5:5
      |
    5 |     5.0 => {}
      |     ^^^
      |
      = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>

### Explanation

Previous versions of the compiler accepted floating-point literals in patterns, but it was later determined this was a mistake. The semantics of comparing floating-point values may not be clear in a pattern when contrasted with "structural equality". Typically you can work around this by using a match guard, such as:

    #![allow(unused)]
    fn main() {
    let x = 42.0;

    match x {
        y if y == 5.0 => {}
        _ => {}
    }
    }

This is a future-incompatible lint to transition this to a hard error in the future. See issue #41620 for more details.

## improper-ctypes

The `improper_ctypes` lint detects incorrect use of types in foreign modules.

### Example

    #![allow(unused)]
    fn main() {
    extern "C" {
        static STATIC: String;
    }
    }

This will produce:

    warning: `extern` block uses type `String`, which is not FFI-safe
     --> lint_example.rs:3:20
      |
    3 |     static STATIC: String;
      |                    ^^^^^^ not FFI-safe
      |
      = note: `#[warn(improper_ctypes)]` on by default
      = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
      = note: this struct has unspecified layout

### Explanation

The compiler has several checks to verify that types used in `extern` blocks are safe and follow certain rules to ensure proper compatibility with the foreign interfaces. This lint is issued when it detects a probable mistake in a definition. The lint usually should provide a description of the issue, along with possibly a hint on how to resolve it.

## improper-ctypes-definitions

The `improper_ctypes_definitions` lint detects incorrect use of `extern` function definitions.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    pub extern "C" fn str_type(p: &str) { }
    }

This will produce:

    warning: `extern` fn uses type `str`, which is not FFI-safe
     --> lint_example.rs:3:31
      |
    3 | pub extern "C" fn str_type(p: &str) { }
      |                               ^^^^ not FFI-safe
      |
      = note: `#[warn(improper_ctypes_definitions)]` on by default
      = help: consider using `*const u8` and a length instead
      = note: string slices have no C equivalent

### Explanation

There are many parameter and return types that may be specified in an `extern` function that are not compatible with the given ABI. This lint is an alert that these types should not be used. The lint usually should provide a description of the issue, along with possibly a hint on how to resolve it.

## incomplete-features

The `incomplete_features` lint detects unstable features enabled with the `feature` attribute that may function improperly in some or all cases.

### Example

    #![allow(unused)]
    #![feature(generic_associated_types)]
    fn main() {
    }

This will produce:

    warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
     --> lint_example.rs:1:12
      |
    1 | #![feature(generic_associated_types)]
      |            ^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(incomplete_features)]` on by default
      = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information

### Explanation

Although it is encouraged for people to experiment with unstable features, some of them are known to be incomplete or faulty. This lint is a signal that the feature has not yet been finished, and you may experience problems with it.

## indirect-structural-match

The `indirect_structural_match` lint detects a `const` in a pattern that manually implements `PartialEq` and `Eq`.

### Example

    #![deny(indirect_structural_match)]

    struct NoDerive(i32);
    impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
    impl Eq for NoDerive { }
    #[derive(PartialEq, Eq)]
    struct WrapParam<T>(T);
    const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0));
    fn main() {
        match WRAP_INDIRECT_PARAM {
            WRAP_INDIRECT_PARAM => { }
            _ => { }
        }
    }

This will produce:

    error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
      --> lint_example.rs:11:9
       |
    11 |         WRAP_INDIRECT_PARAM => { }
       |         ^^^^^^^^^^^^^^^^^^^
       |
    note: the lint level is defined here
      --> lint_example.rs:1:9
       |
    1  | #![deny(indirect_structural_match)]
       |         ^^^^^^^^^^^^^^^^^^^^^^^^^
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>

### Explanation

The compiler unintentionally accepted this form in the past. This is a future-incompatible lint to transition this to a hard error in the future. See issue #62411 for a complete description of the problem, and some possible solutions.

## inline-no-sanitize

The `inline_no_sanitize` lint detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`.

### Example

    #![feature(no_sanitize)]

    #[inline(always)]
    #[no_sanitize(address)]
    fn x() {}

    fn main() {
        x()
    }

This will produce:

    warning: `no_sanitize` will have no effect after inlining
     --> lint_example.rs:4:1
      |
    4 | #[no_sanitize(address)]
      | ^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(inline_no_sanitize)]` on by default
    note: inlining requested here
     --> lint_example.rs:3:1
      |
    3 | #[inline(always)]
      | ^^^^^^^^^^^^^^^^^

### Explanation

The use of the `#[inline(always)]` attribute prevents the the `#[no_sanitize(...)]` attribute from working. Consider temporarily removing `inline` attribute.

## invalid-codeblock-attributes

The `invalid_codeblock_attributes` lint detects code block attributes in documentation examples that have potentially mis-typed values. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## invalid-value

The `invalid_value` lint detects creating a value that is not valid, such as a NULL reference.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    unsafe {
        let x: &'static i32 = std::mem::zeroed();
    }
    }

This will produce:

    warning: the type `&i32` does not permit zero-initialization
     --> lint_example.rs:4:27
      |
    4 |     let x: &'static i32 = std::mem::zeroed();
      |                           ^^^^^^^^^^^^^^^^^^
      |                           |
      |                           this code causes undefined behavior when executed
      |                           help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
      |
      = note: `#[warn(invalid_value)]` on by default
      = note: references must be non-null

### Explanation

In some situations the compiler can detect that the code is creating an invalid value, which should be avoided.

In particular, this lint will check for improper use of `mem::zeroed`, `mem::uninitialized`, `mem::transmute`, and `MaybeUninit::assume_init` that can cause undefined behavior. The lint should provide extra information to indicate what the problem is and a possible solution.

## irrefutable-let-patterns

The `irrefutable_let_patterns` lint detects detects irrefutable patterns in if-let and while-let statements.

### Example

    #![allow(unused)]
    fn main() {
    if let _ = 123 {
        println!("always runs!");
    }
    }

This will produce:

    warning: irrefutable if-let pattern
     --> lint_example.rs:2:1
      |
    2 | / if let _ = 123 {
    3 | |     println!("always runs!");
    4 | | }
      | |_^
      |
      = note: `#[warn(irrefutable_let_patterns)]` on by default

### Explanation

There usually isn't a reason to have an irrefutable pattern in an if-let or while-let statement, because the pattern will always match successfully. A `let` or `loop` statement will suffice. However, when generating code with a macro, forbidding irrefutable patterns would require awkward workarounds in situations where the macro doesn't know if the pattern is refutable or not. This lint allows macros to accept this form, while alerting for a possibly incorrect use in normal code.

See RFC 2086 for more details.

## late-bound-lifetime-arguments

The `late_bound_lifetime_arguments` lint detects generic lifetime arguments in path segments with late bound lifetime parameters.

### Example

    struct S;

    impl S {
        fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
    }

    fn main() {
        S.late::<'static>(&0, &0);
    }

This will produce:

    warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
     --> lint_example.rs:8:14
      |
    4 |     fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {}
      |             -- the late bound lifetime parameter is introduced here
    ...
    8 |     S.late::<'static>(&0, &0);
      |              ^^^^^^^
      |
      = note: `#[warn(late_bound_lifetime_arguments)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>

### Explanation

It is not clear how to provide arguments for early-bound lifetime parameters if they are intermixed with late-bound parameters in the same list. For now, providing any explicit arguments will trigger this lint if late-bound parameters are present, so in the future a solution can be adopted without hitting backward compatibility issues. This is a future-incompatible lint to transition this to a hard error in the future. See issue #42868 for more details, along with a description of the difference between early and late-bound parameters.

## mixed-script-confusables

The `mixed_script_confusables` lint detects visually confusable characters in identifiers between different scripts.

### Example

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

    fn main() {
    // The Japanese katakana character エ can be confused with the Han character 工.
    const エ: &'static str = "アイウ";
    }

This will produce:

    warning: The usage of Script Group `Japanese, Katakana` in this crate consists solely of mixed script confusables
     --> lint_example.rs:5:7
      |
    5 | const エ: &'static str = "アイウ";
      |       ^^
      |
      = note: `#[warn(mixed_script_confusables)]` on by default
      = note: The usage includes 'エ' (U+30A8).
      = note: Please recheck to make sure their usages are indeed what you want.

### Explanation

With the `non_ascii_idents` nightly-only feature enabled, identifiers are allowed to use non-ASCII characters. This lint warns when characters between different scripts may appear visually similar, which can cause confusion.

If the crate contains other identifiers in the same script that have non-confusable characters, then this lint will not be issued. For example, if the example given above has another identifier with katakana characters (such as `let カタカナ = 123;`), then this indicates that you are intentionally using katakana, and it will not warn about it.

Note that the set of confusable characters may change over time. Beware that if you "forbid" this lint that existing code may fail in the future.

## mutable-borrow-reservation-conflict

The `mutable_borrow_reservation_conflict` lint detects the reservation of a two-phased borrow that conflicts with other shared borrows.

### Example

    #![allow(unused)]
    fn main() {
    let mut v = vec![0, 1, 2];
    let shared = &v;
    v.push(shared.len());
    }

This will produce:

    warning: cannot borrow `v` as mutable because it is also borrowed as immutable
     --> lint_example.rs:4:1
      |
    3 | let shared = &v;
      |              -- immutable borrow occurs here
    4 | v.push(shared.len());
      | ^      ------ immutable borrow later used here
      | |
      | mutable borrow occurs here
      |
      = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
      = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
      = note: for more information, see issue #59159 <https://github.com/rust-lang/rust/issues/59159>

### Explanation

This is a future-incompatible lint to transition this to a hard error in the future. See issue #59159 for a complete description of the problem, and some possible solutions.

## no-mangle-generic-items

The `no_mangle_generic_items` lint detects generic items that must be mangled.

### Example

    #![allow(unused)]
    fn main() {
    #[no_mangle]
    fn foo<T>(t: T) {

    }
    }

This will produce:

    warning: functions generic over types or consts must be mangled
     --> lint_example.rs:3:1
      |
    2 |   #[no_mangle]
      |   ------------ help: remove this attribute
    3 | / fn foo<T>(t: T) {
    4 | |
    5 | | }
      | |_^
      |
      = note: `#[warn(no_mangle_generic_items)]` on by default

### Explanation

An function with generics must have its symbol mangled to accommodate the generic parameter. The `no_mangle` attribute has no effect in this situation, and should be removed.

## non-autolinks

The `non_autolinks` lint detects when a URL could be written using only angle brackets. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## non-camel-case-types

The `non_camel_case_types` lint detects types, variants, traits and type parameters that don't have camel case names.

### Example

    #![allow(unused)]
    fn main() {
    struct my_struct;
    }

This will produce:

    warning: type `my_struct` should have an upper camel case name
     --> lint_example.rs:2:8
      |
    2 | struct my_struct;
      |        ^^^^^^^^^ help: convert the identifier to upper camel case: `MyStruct`
      |
      = note: `#[warn(non_camel_case_types)]` on by default

### Explanation

The preferred style for these identifiers is to use "camel case", such as `MyStruct`, where the first letter should not be lowercase, and should not use underscores between letters. Underscores are allowed at the beginning and end of the identifier, as well as between non-letters (such as `X86_64`).

## non-fmt-panic

The `non_fmt_panic` lint detects `panic!("..")` with `{` or `}` in the string literal when it is not used as a format string.

### Example

    #![allow(unused)]
    fn main() {
    panic!("{}");
    }

This will produce:

    warning: panic message contains an unused formatting placeholder
     --> lint_example.rs:2:9
      |
    2 | panic!("{}");
      |         ^^
      |
      = note: `#[warn(non_fmt_panic)]` on by default
      = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition
    help: add the missing argument
      |
    2 | panic!("{}", ...);
      |            ^^^^^
    help: or add a "{}" format string to use the message literally
      |
    2 | panic!("{}", "{}");
      |        ^^^^^

### Explanation

`panic!("{}")` panics with the message `"{}"`, as a `panic!()` invocation with a single argument does not use `format_args!()`. A future edition of Rust will interpret this string as format string, which would break this.

## non-shorthand-field-patterns

The `non_shorthand_field_patterns` lint detects using `Struct { x: x }` instead of `Struct { x }` in a pattern.

### Example

    struct Point {
        x: i32,
        y: i32,
    }

    fn main() {
        let p = Point {
            x: 5,
            y: 5,
        };

        match p {
            Point { x: x, y: y } => (),
        }
    }

This will produce:

    warning: the `x:` in this pattern is redundant
      --> lint_example.rs:14:17
       |
    14 |         Point { x: x, y: y } => (),
       |                 ^^^^ help: use shorthand field pattern: `x`
       |
       = note: `#[warn(non_shorthand_field_patterns)]` on by default

### Explanation

The preferred style is to avoid the repetition of specifying both the field name and the binding name if both identifiers are the same.

## non-snake-case

The `non_snake_case` lint detects variables, methods, functions, lifetime parameters and modules that don't have snake case names.

### Example

    #![allow(unused)]
    fn main() {
    let MY_VALUE = 5;
    }

This will produce:

    warning: variable `MY_VALUE` should have a snake case name
     --> lint_example.rs:2:5
      |
    2 | let MY_VALUE = 5;
      |     ^^^^^^^^ help: convert the identifier to snake case: `my_value`
      |
      = note: `#[warn(non_snake_case)]` on by default

### Explanation

The preferred style for these identifiers is to use "snake case", where all the characters are in lowercase, with words separated with a single underscore, such as `my_value`.

## non-upper-case-globals

The `non_upper_case_globals` lint detects static items that don't have uppercase identifiers.

### Example

    #![allow(unused)]
    fn main() {
    static max_points: i32 = 5;
    }

This will produce:

    warning: static variable `max_points` should have an upper case name
     --> lint_example.rs:2:8
      |
    2 | static max_points: i32 = 5;
      |        ^^^^^^^^^^ help: convert the identifier to upper case: `MAX_POINTS`
      |
      = note: `#[warn(non_upper_case_globals)]` on by default

### Explanation

The preferred style is for static item names to use all uppercase letters such as `MAX_POINTS`.

## nontrivial-structural-match

The `nontrivial_structural_match` lint detects constants that are used in patterns, whose type is not structural-match and whose initializer body actually uses values that are not structural-match. So `Option<NotStruturalMatch>` is ok if the constant is just `None`.

### Example

    #![deny(nontrivial_structural_match)]

    #[derive(Copy, Clone, Debug)]
    struct NoDerive(u32);
    impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
    impl Eq for NoDerive { }
    fn main() {
        const INDEX: Option<NoDerive> = [None, Some(NoDerive(10))][0];
        match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
    }

This will produce:

    error: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]`
     --> lint_example.rs:9:47
      |
    9 |     match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
      |                                               ^^^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(nontrivial_structural_match)]
      |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>

### Explanation

Previous versions of Rust accepted constants in patterns, even if those constants's types did not have `PartialEq` derived. Thus the compiler falls back to runtime execution of `PartialEq`, which can report that two constants are not equal even if they are bit-equivalent.

## overlapping-range-endpoints

The `overlapping_range_endpoints` lint detects `match` arms that have range patterns that overlap on their endpoints.

### Example

    #![allow(unused)]
    fn main() {
    let x = 123u8;
    match x {
        0..=100 => { println!("small"); }
        100..=255 => { println!("large"); }
    }
    }

This will produce:

    warning: multiple patterns overlap on their endpoints
     --> lint_example.rs:5:5
      |
    4 |     0..=100 => { println!("small"); }
      |     ------- this range overlaps on `100_u8`...
    5 |     100..=255 => { println!("large"); }
      |     ^^^^^^^^^ ... with this range
      |
      = note: `#[warn(overlapping_range_endpoints)]` on by default
      = note: you likely meant to write mutually exclusive ranges

### Explanation

It is likely a mistake to have range patterns in a match expression that overlap in this way. Check that the beginning and end values are what you expect, and keep in mind that with `..=` the left and right bounds are inclusive.

## path-statements

The `path_statements` lint detects path statements with no effect.

### Example

    #![allow(unused)]
    fn main() {
    let x = 42;

    x;
    }

This will produce:

    warning: path statement with no effect
     --> lint_example.rs:4:1
      |
    4 | x;
      | ^^
      |
      = note: `#[warn(path_statements)]` on by default

### Explanation

It is usually a mistake to have a statement that has no effect.

## private-in-public

The `private_in_public` lint detects private items in public interfaces not caught by the old implementation.

### Example

    #![allow(unused)]
    struct SemiPriv;

    mod m1 {
        struct Priv;
        impl super::SemiPriv {
            pub fn f(_: Priv) {}
        }
    }
    fn main() {}

This will produce:

    warning: private type `Priv` in public interface (error E0446)
     --> lint_example.rs:7:9
      |
    7 |         pub fn f(_: Priv) {}
      |         ^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(private_in_public)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>

### Explanation

The visibility rules are intended to prevent exposing private items in public interfaces. This is a future-incompatible lint to transition this to a hard error in the future. See issue #34537 for more details.

## private-intra-doc-links

This is a subset of `broken_intra_doc_links` that warns when linking from a public item to a private one. This is a `rustdoc` only lint, see the documentation in the rustdoc book.

## proc-macro-derive-resolution-fallback

The `proc_macro_derive_resolution_fallback` lint detects proc macro derives using inaccessible names from parent modules.

### Example

    // foo.rs
    #![crate_type = "proc-macro"]

    extern crate proc_macro;

    use proc_macro::*;

    #[proc_macro_derive(Foo)]
    pub fn foo1(a: TokenStream) -> TokenStream {
        drop(a);
        "mod __bar { static mut BAR: Option<Something> = None; }".parse().unwrap()
    }

    // bar.rs
    #[macro_use]
    extern crate foo;

    struct Something;

    #[derive(Foo)]
    struct Another;

    fn main() {}

This will produce:

    warning: cannot find type `Something` in this scope
     --> src/main.rs:8:10
      |
    8 | #[derive(Foo)]
      |          ^^^ names from parent modules are not accessible without an explicit import
      |
      = note: `#[warn(proc_macro_derive_resolution_fallback)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>

### Explanation

If a proc-macro generates a module, the compiler unintentionally allowed items in that module to refer to items in the crate root without importing them. This is a future-incompatible lint to transition this to a hard error in the future. See issue #50504 for more details.

## redundant-semicolons

The `redundant_semicolons` lint detects unnecessary trailing semicolons.

### Example

    #![allow(unused)]
    fn main() {
    let _ = 123;;
    }

This will produce:

    warning: unnecessary trailing semicolon
     --> lint_example.rs:2:13
      |
    2 | let _ = 123;;
      |             ^ help: remove this semicolon
      |
      = note: `#[warn(redundant_semicolons)]` on by default

### Explanation

Extra semicolons are not needed, and may be removed to avoid confusion and visual clutter.

## renamed-and-removed-lints

The `renamed_and_removed_lints` lint detects lints that have been renamed or removed.

### Example

    #![allow(unused)]
    #![deny(raw_pointer_derive)]
    fn main() {
    }

This will produce:

    warning: lint `raw_pointer_derive` has been removed: `using derive with raw pointers is ok`
     --> lint_example.rs:1:9
      |
    1 | #![deny(raw_pointer_derive)]
      |         ^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(renamed_and_removed_lints)]` on by default

### Explanation

To fix this, either remove the lint or use the new name. This can help avoid confusion about lints that are no longer valid, and help maintain consistency for renamed lints.

## safe-packed-borrows

The `safe_packed_borrows` lint detects borrowing a field in the interior of a packed structure with alignment other than 1.

### Example

    #[repr(packed)]
    pub struct Unaligned<T>(pub T);

    pub struct Foo {
        start: u8,
        data: Unaligned<u32>,
    }

    fn main() {
        let x = Foo { start: 0, data: Unaligned(1) };
        let y = &x.data.0;
    }

This will produce:

    warning: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
      --> lint_example.rs:11:13
       |
    11 |     let y = &x.data.0;
       |             ^^^^^^^^^
       |
       = note: `#[warn(safe_packed_borrows)]` on by default
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
       = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior

### Explanation

This type of borrow is unsafe and can cause errors on some platforms and violates some assumptions made by the compiler. This was previously allowed unintentionally. This is a future-incompatible lint to transition this to a hard error in the future. See issue #46043 for more details, including guidance on how to solve the problem.

## stable-features

The `stable_features` lint detects a `feature` attribute that has since been made stable.

### Example

    #![feature(test_accepted_feature)]
    fn main() {}

This will produce:

    warning: the feature `test_accepted_feature` has been stable since 1.0.0 and no longer requires an attribute to enable
     --> lint_example.rs:1:12
      |
    1 | #![feature(test_accepted_feature)]
      |            ^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(stable_features)]` on by default

### Explanation

When a feature is stabilized, it is no longer necessary to include a `#![feature]` attribute for it. To fix, simply remove the `#![feature]` attribute.

## temporary-cstring-as-ptr

The `temporary_cstring_as_ptr` lint detects getting the inner pointer of a temporary `CString`.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    use std::ffi::CString;
    let c_str = CString::new("foo").unwrap().as_ptr();
    }

This will produce:

    warning: getting the inner pointer of a temporary `CString`
     --> lint_example.rs:4:42
      |
    4 | let c_str = CString::new("foo").unwrap().as_ptr();
      |             ---------------------------- ^^^^^^ this pointer will be invalid
      |             |
      |             this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
      |
      = note: `#[warn(temporary_cstring_as_ptr)]` on by default
      = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
      = help: for more information, see https://doc.rust-lang.org/reference/destructors.html

### Explanation

The inner pointer of a `CString` lives only as long as the `CString` it points to. Getting the inner pointer of a temporary `CString` allows the `CString` to be dropped at the end of the statement, as it is not being referenced as far as the typesystem is concerned. This means outside of the statement the pointer will point to freed memory, which causes undefined behavior if the pointer is later dereferenced.

## trivial-bounds

The `trivial_bounds` lint detects trait bounds that don't depend on any type parameters.

### Example

    #![allow(unused)]
    #![feature(trivial_bounds)]
    fn main() {
    pub struct A where i32: Copy;
    }

This will produce:

    warning: Trait bound i32: Copy does not depend on any type or lifetime parameters
     --> lint_example.rs:3:25
      |
    3 | pub struct A where i32: Copy;
      |                         ^^^^
      |
      = note: `#[warn(trivial_bounds)]` on by default

### Explanation

Usually you would not write a trait bound that you know is always true, or never true. However, when using macros, the macro may not know whether or not the constraint would hold or not at the time when generating the code. Currently, the compiler does not alert you if the constraint is always true, and generates an error if it is never true. The `trivial_bounds` feature changes this to be a warning in both cases, giving macros more freedom and flexibility to generate code, while still providing a signal when writing non-macro code that something is amiss.

See RFC 2056 for more details. This feature is currently only available on the nightly channel, see tracking issue #48214.

## type-alias-bounds

The `type_alias_bounds` lint detects bounds in type aliases.

### Example

    #![allow(unused)]
    fn main() {
    type SendVec<T: Send> = Vec<T>;
    }

This will produce:

    warning: bounds on generic parameters are not enforced in type aliases
     --> lint_example.rs:2:17
      |
    2 | type SendVec<T: Send> = Vec<T>;
      |                 ^^^^
      |
      = note: `#[warn(type_alias_bounds)]` on by default
    help: the bound will not be checked when the type alias is used, and should be removed
      |
    2 | type SendVec<T> = Vec<T>;
      |              --

### Explanation

The trait bounds in a type alias are currently ignored, and should not be included to avoid confusion. This was previously allowed unintentionally; this may become a hard error in the future.

## tyvar-behind-raw-pointer

The `tyvar_behind_raw_pointer` lint detects raw pointer to an inference variable.

### Example

    #![allow(unused)]
    fn main() {
    // edition 2015
    let data = std::ptr::null();
    let _ = &data as *const *const ();

    if data.is_null() {}
    }

This will produce:

    warning: type annotations needed
     --> lint_example.rs:6:9
      |
    6 | if data.is_null() {}
      |         ^^^^^^^
      |
      = note: `#[warn(tyvar_behind_raw_pointer)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
      = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>

### Explanation

This kind of inference was previously allowed, but with the future arrival of arbitrary self types, this can introduce ambiguity. To resolve this, use an explicit type instead of relying on type inference.

This is a future-incompatible lint to transition this to a hard error in the 2018 edition. See issue #46906 for more details. This is currently a hard-error on the 2018 edition, and is "warn" by default in the 2015 edition.

## uncommon-codepoints

The `uncommon_codepoints` lint detects uncommon Unicode codepoints in identifiers.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    #![feature(non_ascii_idents)]
    const µ: f64 = 0.000001;
    }

This will produce:

    warning: identifier contains uncommon Unicode codepoints
     --> lint_example.rs:4:7
      |
    4 | const µ: f64 = 0.000001;
      |       ^
      |
      = note: `#[warn(uncommon_codepoints)]` on by default

### Explanation

With the `non_ascii_idents` nightly-only feature enabled, identifiers are allowed to use non-ASCII characters. This lint warns about using characters which are not commonly used, and may cause visual confusion.

This lint is triggered by identifiers that contain a codepoint that is not part of the set of "Allowed" codepoints as described by Unicode® Technical Standard #39 Unicode Security Mechanisms Section 3.1 General Security Profile for Identifiers.

Note that the set of uncommon codepoints may change over time. Beware that if you "forbid" this lint that existing code may fail in the future.

## unconditional-recursion

The `unconditional_recursion` lint detects functions that cannot return without calling themselves.

### Example

    #![allow(unused)]
    fn main() {
    fn foo() {
        foo();
    }
    }

This will produce:

    warning: function cannot return without recursing
     --> lint_example.rs:2:1
      |
    2 | fn foo() {
      | ^^^^^^^^ cannot return without recursing
    3 |     foo();
      |     ----- recursive call site
      |
      = note: `#[warn(unconditional_recursion)]` on by default
      = help: a `loop` may express intention better if this is on purpose

### Explanation

It is usually a mistake to have a recursive call that does not have some condition to cause it to terminate. If you really intend to have an infinite loop, using a `loop` expression is recommended.

## uninhabited-static

The `uninhabited_static` lint detects uninhabited statics.

### Example

    #![allow(unused)]
    fn main() {
    enum Void {}
    extern {
        static EXTERN: Void;
    }
    }

This will produce:

    warning: static of uninhabited type
     --> lint_example.rs:4:5
      |
    4 |     static EXTERN: Void;
      |     ^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(uninhabited_static)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
      = note: uninhabited statics cannot be initialized, and any access would be an immediate error

### Explanation

Statics with an uninhabited type can never be initialized, so they are impossible to define. However, this can be side-stepped with an `extern static`, leading to problems later in the compiler which assumes that there are no initialized uninhabited places (such as locals or statics). This was accientally allowed, but is being phased out.

## unknown-lints

The `unknown_lints` lint detects unrecognized lint attribute.

### Example

    #![allow(unused)]
    #![allow(not_a_real_lint)]
    fn main() {
    }

This will produce:

    warning: unknown lint: `not_a_real_lint`
     --> lint_example.rs:1:10
      |
    1 | #![allow(not_a_real_lint)]
      |          ^^^^^^^^^^^^^^^
      |
      = note: `#[warn(unknown_lints)]` on by default

### Explanation

It is usually a mistake to specify a lint that does not exist. Check the spelling, and check the lint listing for the correct name. Also consider if you are using an old version of the compiler, and the lint is only available in a newer version.

## unnameable-test-items

The `unnameable_test_items` lint detects `#[test]` functions that are not able to be run by the test harness because they are in a position where they are not nameable.

### Example

    fn main() {
        #[test]
        fn foo() {
            // This test will not fail because it does not run.
            assert_eq!(1, 2);
        }
    }

This will produce:

    warning: cannot test inner items
     --> lint_example.rs:2:5
      |
    2 |     #[test]
      |     ^^^^^^^
      |
      = note: `#[warn(unnameable_test_items)]` on by default
      = note: this warning originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

### Explanation

In order for the test harness to run a test, the test function must be located in a position where it can be accessed from the crate root. This generally means it must be defined in a module, and not anywhere else such as inside another function. The compiler previously allowed this without an error, so a lint was added as an alert that a test is not being used. Whether or not this should be allowed has not yet been decided, see RFC 2471 and issue #36629.

## unreachable-code

The `unreachable_code` lint detects unreachable code paths.

### Example

    #![allow(unused)]
    fn main() {
    panic!("we never go past here!");

    let x = 5;
    }

This will produce:

    warning: unreachable statement
     --> lint_example.rs:4:1
      |
    2 | panic!("we never go past here!");
      | --------------------------------- any code following this expression is unreachable
    3 |
    4 | let x = 5;
      | ^^^^^^^^^^ unreachable statement
      |
      = note: `#[warn(unreachable_code)]` on by default

### Explanation

Unreachable code may signal a mistake or unfinished code. If the code is no longer in use, consider removing it.

## unreachable-patterns

The `unreachable_patterns` lint detects unreachable patterns.

### Example

    #![allow(unused)]
    fn main() {
    let x = 5;
    match x {
        y => (),
        5 => (),
    }
    }

This will produce:

    warning: unreachable pattern
     --> lint_example.rs:5:5
      |
    4 |     y => (),
      |     - matches any value
    5 |     5 => (),
      |     ^ unreachable pattern
      |
      = note: `#[warn(unreachable_patterns)]` on by default

### Explanation

This usually indicates a mistake in how the patterns are specified or ordered. In this example, the `y` pattern will always match, so the five is impossible to reach. Remember, match arms match in order, you probably wanted to put the `5` case above the `y` case.

## unstable-name-collisions

The `unstable_name_collisions` lint detects that you have used a name that the standard library plans to add in the future.

### Example

    #![allow(unused)]
    fn main() {
    trait MyIterator : Iterator {
        // is_sorted is an unstable method that already exists on the Iterator trait
        fn is_sorted(self) -> bool where Self: Sized {true}
    }

    impl<T: ?Sized> MyIterator for T where T: Iterator { }

    let x = vec![1, 2, 3];
    let _ = x.iter().is_sorted();
    }

This will produce:

    warning: a method with this name may be added to the standard library in the future
      --> lint_example.rs:10:18
       |
    10 | let _ = x.iter().is_sorted();
       |                  ^^^^^^^^^
       |
       = note: `#[warn(unstable_name_collisions)]` on by default
       = warning: once this method is added to the standard library, the ambiguity may cause an error or change in behavior!
       = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
       = help: call with fully qualified syntax `MyIterator::is_sorted(...)` to keep using the current method
       = help: add `#![feature(is_sorted)]` to the crate attributes to enable `is_sorted`

### Explanation

When new methods are added to traits in the standard library, they are usually added in an "unstable" form which is only available on the nightly channel with a `feature` attribute. If there is any pre-existing code which extends a trait to have a method with the same name, then the names will collide. In the future, when the method is stabilized, this will cause an error due to the ambiguity. This lint is an early-warning to let you know that there may be a collision in the future. This can be avoided by adding type annotations to disambiguate which trait method you intend to call, such as `MyIterator::is_sorted(my_iter)` or renaming or removing the method.

## unsupported-naked-functions

The `unsupported_naked_functions` lint detects naked function definitions that are unsupported but were previously accepted.

### Example

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

    fn main() {
    #[naked]
    pub fn f() -> u32 {
        42
    }
    }

This will produce:

    warning: Rust ABI is unsupported in naked functions
     --> lint_example.rs:5:8
      |
    5 | pub fn f() -> u32 {
      |        ^
      |
      = note: `#[warn(unsupported_naked_functions)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>

### Explanation

The naked functions must be defined using a single inline assembly block.

The execution must never fall through past the end of the assembly code so the block must use `noreturn` option. The asm block can also use `att_syntax` option, but other options are not allowed.

The asm block must not contain any operands other than `const` and `sym`. Additionally, naked function should specify a non-Rust ABI.

While other definitions of naked functions were previously accepted, they are unsupported and might not work reliably. This is a future-incompatible lint that will transition into hard error in the future.

## unused-allocation

The `unused_allocation` lint detects unnecessary allocations that can be eliminated.

### Example

    #![feature(box_syntax)]
    fn main() {
        let a = (box [1, 2, 3]).len();
    }

This will produce:

    warning: unnecessary allocation, use `&` instead
     --> lint_example.rs:3:13
      |
    3 |     let a = (box [1, 2, 3]).len();
      |             ^^^^^^^^^^^^^^^
      |
      = note: `#[warn(unused_allocation)]` on by default

### Explanation

When a `box` expression is immediately coerced to a reference, then the allocation is unnecessary, and a reference (using `&` or `&mut`) should be used instead to avoid the allocation.

## unused-assignments

The `unused_assignments` lint detects assignments that will never be read.

### Example

    #![allow(unused)]
    fn main() {
    let mut x = 5;
    x = 6;
    }

This will produce:

    warning: value assigned to `x` is never read
     --> lint_example.rs:3:1
      |
    3 | x = 6;
      | ^
      |
      = note: `#[warn(unused_assignments)]` on by default
      = help: maybe it is overwritten before being read?

### Explanation

Unused assignments may signal a mistake or unfinished code. If the variable is never used after being assigned, then the assignment can be removed. Variables with an underscore prefix such as `_x` will not trigger this lint.

## unused-attributes

The `unused_attributes` lint detects attributes that were not used by the compiler.

### Example

    #![allow(unused)]
    #![ignore]
    fn main() {
    }

This will produce:

    warning: unused attribute
     --> lint_example.rs:1:1
      |
    1 | #![ignore]
      | ^^^^^^^^^^
      |
      = note: `#[warn(unused_attributes)]` on by default

### Explanation

Unused attributes may indicate the attribute is placed in the wrong position. Consider removing it, or placing it in the correct position. Also consider if you intended to use an inner attribute (with a `!` such as `#![allow(unused)]`) which applies to the item the attribute is within, or an outer attribute (without a `!` such as `#[allow(unsued)]`) which applies to the item following the attribute.

## unused-braces

The `unused_braces` lint detects unnecessary braces around an expression.

### Example

    #![allow(unused)]
    fn main() {
    if { true } {
        // ...
    }
    }

This will produce:

    warning: unnecessary braces around `if` condition
     --> lint_example.rs:2:4
      |
    2 | if { true } {
      |    ^^^^^^^^ help: remove these braces
      |
      = note: `#[warn(unused_braces)]` on by default

### Explanation

The braces are not needed, and should be removed. This is the preferred style for writing these expressions.

## unused-comparisons

The `unused_comparisons` lint detects comparisons made useless by limits of the types involved.

### Example

    #![allow(unused)]
    fn main() {
    fn foo(x: u8) {
        x >= 0;
    }
    }

This will produce:

    warning: comparison is useless due to type limits
     --> lint_example.rs:3:5
      |
    3 |     x >= 0;
      |     ^^^^^^
      |
      = note: `#[warn(unused_comparisons)]` on by default

### Explanation

A useless comparison may indicate a mistake, and should be fixed or removed.

## unused-doc-comments

The `unused_doc_comments` lint detects doc comments that aren't used by `rustdoc`.

### Example

    #![allow(unused)]
    fn main() {
    /// docs for x
    let x = 12;
    }

This will produce:

    warning: unused doc comment
     --> lint_example.rs:2:1
      |
    2 | /// docs for x
      | ^^^^^^^^^^^^^^
    3 | let x = 12;
      | ----------- rustdoc does not generate documentation for statements
      |
      = note: `#[warn(unused_doc_comments)]` on by default

### Explanation

`rustdoc` does not use doc comments in all positions, and so the doc comment will be ignored. Try changing it to a normal comment with `//` to avoid the warning.

## unused-features

The `unused_features` lint detects unused or unknown features found in crate-level `feature` attributes.

Note: This lint is currently not functional, see issue #44232 for more details.

## unused-imports

The `unused_imports` lint detects imports that are never used.

### Example

    #![allow(unused)]
    fn main() {
    use std::collections::HashMap;
    }

This will produce:

    warning: unused import: `std::collections::HashMap`
     --> lint_example.rs:2:5
      |
    2 | use std::collections::HashMap;
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(unused_imports)]` on by default

### Explanation

Unused imports may signal a mistake or unfinished code, and clutter the code, and should be removed. If you intended to re-export the item to make it available outside of the module, add a visibility modifier like `pub`.

## unused-labels

The `unused_labels` lint detects labels that are never used.

### Example

    #![allow(unused)]
    fn main() {
    'unused_label: loop {}
    }

This will produce:

    warning: unused label
     --> lint_example.rs:2:1
      |
    2 | 'unused_label: loop {}
      | ^^^^^^^^^^^^^
      |
      = note: `#[warn(unused_labels)]` on by default

### Explanation

Unused labels may signal a mistake or unfinished code. To silence the warning for the individual label, prefix it with an underscore such as `'_my_label:`.

## unused-macros

The `unused_macros` lint detects macros that were not used.

### Example

    macro_rules! unused {
        () => {};
    }

    fn main() {
    }

This will produce:

    warning: unused macro definition
     --> lint_example.rs:1:1
      |
    1 | / macro_rules! unused {
    2 | |     () => {};
    3 | | }
      | |_^
      |
      = note: `#[warn(unused_macros)]` on by default

### Explanation

Unused macros may signal a mistake or unfinished code. To silence the warning for the individual macro, prefix the name with an underscore such as `_my_macro`. If you intended to export the macro to make it available outside of the crate, use the `macro_export` attribute.

## unused-must-use

The `unused_must_use` lint detects unused result of a type flagged as `#[must_use]`.

### Example

    fn returns_result() -> Result<(), ()> {
        Ok(())
    }

    fn main() {
        returns_result();
    }

This will produce:

    warning: unused `std::result::Result` that must be used
     --> lint_example.rs:6:5
      |
    6 |     returns_result();
      |     ^^^^^^^^^^^^^^^^^
      |
      = note: `#[warn(unused_must_use)]` on by default
      = note: this `Result` may be an `Err` variant, which should be handled

### Explanation

The `#[must_use]` attribute is an indicator that it is a mistake to ignore the value. See the reference for more details.

## unused-mut

The `unused_mut` lint detects mut variables which don't need to be mutable.

### Example

    #![allow(unused)]
    fn main() {
    let mut x = 5;
    }

This will produce:

    warning: variable does not need to be mutable
     --> lint_example.rs:2:5
      |
    2 | let mut x = 5;
      |     ----^
      |     |
      |     help: remove this `mut`
      |
      = note: `#[warn(unused_mut)]` on by default

### Explanation

The preferred style is to only mark variables as `mut` if it is required.

## unused-parens

The `unused_parens` lint detects `if`, `match`, `while` and `return` with parentheses; they do not need them.

### Examples

    #![allow(unused)]
    fn main() {
    if(true) {}
    }

This will produce:

    warning: unnecessary parentheses around `if` condition
     --> lint_example.rs:2:3
      |
    2 | if(true) {}
      |   ^^^^^^ help: remove these parentheses
      |
      = note: `#[warn(unused_parens)]` on by default

### Explanation

The parenthesis are not needed, and should be removed. This is the preferred style for writing these expressions.

## unused-unsafe

The `unused_unsafe` lint detects unnecessary use of an `unsafe` block.

### Example

    #![allow(unused)]
    fn main() {
    unsafe {}
    }

This will produce:

    warning: unnecessary `unsafe` block
     --> lint_example.rs:2:1
      |
    2 | unsafe {}
      | ^^^^^^ unnecessary `unsafe` block
      |
      = note: `#[warn(unused_unsafe)]` on by default

### Explanation

If nothing within the block requires `unsafe`, then remove the `unsafe` marker because it is not required and may cause confusion.

## unused-variables

The `unused_variables` lint detects variables which are not used in any way.

### Example

    #![allow(unused)]
    fn main() {
    let x = 5;
    }

This will produce:

    warning: unused variable: `x`
     --> lint_example.rs:2:5
      |
    2 | let x = 5;
      |     ^ help: if this is intentional, prefix it with an underscore: `_x`
      |
      = note: `#[warn(unused_variables)]` on by default

### Explanation

Unused variables may signal a mistake or unfinished code. To silence the warning for the individual variable, prefix it with an underscore such as `_x`.

## warnings

The `warnings` lint allows you to change the level of other lints which produce warnings.

### Example

    #![allow(unused)]
    #![deny(warnings)]
    fn main() {
    fn foo() {}
    }

This will produce:

    error: function is never used: `foo`
     --> lint_example.rs:3:4
      |
    3 | fn foo() {}
      |    ^^^
      |
    note: the lint level is defined here
     --> lint_example.rs:1:9
      |
    1 | #![deny(warnings)]
      |         ^^^^^^^^
      = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`

### Explanation

The `warnings` lint is a bit special; by changing its level, you change every other warning that would produce a warning to whatever value you'd like. As such, you won't ever trigger this lint in your code directly.

## where-clauses-object-safety

The `where_clauses_object_safety` lint detects for object safety of where clauses.

### Example

    trait Trait {}

    trait X { fn foo(&self) where Self: Trait; }

    impl X for () { fn foo(&self) {} }

    impl Trait for dyn X {}

    // Segfault at opt-level 0, SIGILL otherwise.
    pub fn main() { <dyn X as X>::foo(&()); }

This will produce:

    warning: the trait `X` cannot be made into an object
     --> lint_example.rs:3:14
      |
    3 | trait X { fn foo(&self) where Self: Trait; }
      |              ^^^
      |
      = note: `#[warn(where_clauses_object_safety)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
    note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
     --> lint_example.rs:3:14
      |
    3 | trait X { fn foo(&self) where Self: Trait; }
      |       -      ^^^ ...because method `foo` references the `Self` type in its `where` clause
      |       |
      |       this trait cannot be made into an object...
      = help: consider moving `foo` to another trait

### Explanation

The compiler previously allowed these object-unsafe bounds, which was incorrect. This is a future-incompatible lint to transition this to a hard error in the future. See issue #51443 for more details.

## while-true

The `while_true` lint detects `while true { }`.

### Example

    #![allow(unused)]
    fn main() {
    while true {

    }
    }

This will produce:

    warning: denote infinite loops with `loop { ... }`
     --> lint_example.rs:2:1
      |
    2 | while true {
      | ^^^^^^^^^^ help: use `loop`
      |
      = note: `#[warn(while_true)]` on by default

### Explanation

`while true` should be replaced with `loop`. A `loop` expression is the preferred way to write an infinite loop because it more directly expresses the intent of the loop.

# Deny-by-default lints

These lints are all set to the 'deny' level by default.

- `ambiguous_associated_items`
- `arithmetic_overflow`
- `conflicting_repr_hints`
- `const_err`
- `ill_formed_attribute_input`
- `incomplete_include`
- `invalid_type_param_default`
- `macro_expanded_macro_exports_accessed_by_absolute_paths`
- `missing_fragment_specifier`
- `mutable_transmutes`
- `no_mangle_const_items`
- `order_dependent_trait_objects`
- `overflowing_literals`
- `patterns_in_fns_without_body`
- `pub_use_of_private_extern_crate`
- `soft_unstable`
- `unconditional_panic`
- `unknown_crate_types`
- `useless_deprecated`

## ambiguous-associated-items

The `ambiguous_associated_items` lint detects ambiguity between associated items and enum variants.

### Example

    #![allow(unused)]
    fn main() {
    enum E {
        V
    }

    trait Tr {
        type V;
        fn foo() -> Self::V;
    }

    impl Tr for E {
        type V = u8;
        // `Self::V` is ambiguous because it may refer to the associated type or
        // the enum variant.
        fn foo() -> Self::V { 0 }
    }
    }

This will produce:

    error: ambiguous associated item
      --> lint_example.rs:15:17
       |
    15 |     fn foo() -> Self::V { 0 }
       |                 ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V`
       |
       = note: `#[deny(ambiguous_associated_items)]` on by default
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
    note: `V` could refer to the variant defined here
      --> lint_example.rs:3:5
       |
    3  |     V
       |     ^
    note: `V` could also refer to the associated type defined here
      --> lint_example.rs:7:5
       |
    7  |     type V;
       |     ^^^^^^^

### Explanation

Previous versions of Rust did not allow accessing enum variants through type aliases. When this ability was added (see RFC 2338), this introduced some situations where it can be ambiguous what a type was referring to.

To fix this ambiguity, you should use a qualified path to explicitly state which type to use. For example, in the above example the function can be written as `fn f() -> <Self as Tr>::V { 0 }` to specifically refer to the associated type.

This is a future-incompatible lint to transition this to a hard error in the future. See issue #57644 for more details.

## arithmetic-overflow

The `arithmetic_overflow` lint detects that an arithmetic operation will overflow.

### Example

    #![allow(unused)]
    fn main() {
    1_i32 << 32;
    }

This will produce:

    error: this arithmetic operation will overflow
     --> lint_example.rs:2:1
      |
    2 | 1_i32 << 32;
      | ^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
      |
      = note: `#[deny(arithmetic_overflow)]` on by default

### Explanation

It is very likely a mistake to perform an arithmetic operation that overflows its value. If the compiler is able to detect these kinds of overflows at compile-time, it will trigger this lint. Consider adjusting the expression to avoid overflow, or use a data type that will not overflow.

## conflicting-repr-hints

The `conflicting_repr_hints` lint detects `repr` attributes with conflicting hints.

### Example

    #![allow(unused)]
    fn main() {
    #[repr(u32, u64)]
    enum Foo {
        Variant1,
    }
    }

This will produce:

    error[E0566]: conflicting representation hints
     --> lint_example.rs:2:8
      |
    2 | #[repr(u32, u64)]
      |        ^^^  ^^^
      |
      = note: `#[deny(conflicting_repr_hints)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>

### Explanation

The compiler incorrectly accepted these conflicting representations in the past. This is a future-incompatible lint to transition this to a hard error in the future. See issue #68585 for more details.

To correct the issue, remove one of the conflicting hints.

## const-err

The `const_err` lint detects an erroneous expression while doing constant evaluation.

### Example

    #![allow(unused)]
    #![allow(unconditional_panic)]
    fn main() {
    let x: &'static i32 = &(1 / 0);
    }

This will produce:

    error: reaching this expression at runtime will panic or abort
     --> lint_example.rs:3:24
      |
    3 | let x: &'static i32 = &(1 / 0);
      |                       -^^^^^^^
      |                        |
      |                        dividing by zero
      |
      = note: `#[deny(const_err)]` on by default

### Explanation

This lint detects code that is very likely incorrect. If this lint is allowed, then the code will not be evaluated at compile-time, and instead continue to generate code to evaluate at runtime, which may panic during runtime.

Note that this lint may trigger in either inside or outside of a const context. Outside of a const context, the compiler can sometimes evaluate an expression at compile-time in order to generate more efficient code. As the compiler becomes better at doing this, it needs to decide what to do when it encounters code that it knows for certain will panic or is otherwise incorrect. Making this a hard error would prevent existing code that exhibited this behavior from compiling, breaking backwards-compatibility. However, this is almost certainly incorrect code, so this is a deny-by-default lint. For more details, see RFC 1229 and issue #28238.

Note that there are several other more specific lints associated with compile-time evaluation, such as `arithmetic_overflow`, `unconditional_panic`.

## ill-formed-attribute-input

The `ill_formed_attribute_input` lint detects ill-formed attribute inputs that were previously accepted and used in practice.

### Example

    #![allow(unused)]
    fn main() {
    #[inline = "this is not valid"]
    fn foo() {}
    }

This will produce:

    error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
     --> lint_example.rs:2:1
      |
    2 | #[inline = "this is not valid"]
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[deny(ill_formed_attribute_input)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>

### Explanation

Previously, inputs for many built-in attributes weren't validated and nonsensical attribute inputs were accepted. After validation was added, it was determined that some existing projects made use of these invalid forms. This is a future-incompatible lint to transition this to a hard error in the future. See issue #57571 for more details.

Check the attribute reference for details on the valid inputs for attributes.

## incomplete-include

The `incomplete_include` lint detects the use of the `include!` macro with a file that contains more than one expression.

### Example

    fn main() {
        include!("foo.txt");
    }

where the file `foo.txt` contains:

    println!("hi!");

produces:

    error: include macro expected single expression in source
     --> foo.txt:1:14
      |
    1 | println!("1");
      |              ^
      |
      = note: `#[deny(incomplete_include)]` on by default

### Explanation

The `include!` macro is currently only intended to be used to include a single expression or multiple items. Historically it would ignore any contents after the first expression, but that can be confusing. In the example above, the `println!` expression ends just before the semicolon, making the semicolon "extra" information that is ignored. Perhaps even more surprising, if the included file had multiple print statements, the subsequent ones would be ignored!

One workaround is to place the contents in braces to create a block expression. Also consider alternatives, like using functions to encapsulate the expressions, or use proc-macros.

This is a lint instead of a hard error because existing projects were found to hit this error. To be cautious, it is a lint for now. The future semantics of the `include!` macro are also uncertain, see issue #35560.

## invalid-type-param-default

The `invalid_type_param_default` lint detects type parameter defaults erroneously allowed in an invalid location.

### Example

    #![allow(unused)]
    fn main() {
    fn foo<T=i32>(t: T) {}
    }

This will produce:

    error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions.
     --> lint_example.rs:2:8
      |
    2 | fn foo<T=i32>(t: T) {}
      |        ^
      |
      = note: `#[deny(invalid_type_param_default)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>

### Explanation

Default type parameters were only intended to be allowed in certain situations, but historically the compiler allowed them everywhere. This is a future-incompatible lint to transition this to a hard error in the future. See issue #36887 for more details.

## macro-expanded-macro-exports-accessed-by-absolute-paths

The `macro_expanded_macro_exports_accessed_by_absolute_paths` lint detects macro-expanded `macro_export` macros from the current crate that cannot be referred to by absolute paths.

### Example

    macro_rules! define_exported {
        () => {
            #[macro_export]
            macro_rules! exported {
                () => {};
            }
        };
    }

    define_exported!();

    fn main() {
        crate::exported!();
    }

This will produce:

    error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
      --> lint_example.rs:13:5
       |
    13 |     crate::exported!();
       |     ^^^^^^^^^^^^^^^
       |
       = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
       = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
       = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
    note: the macro is defined here
      --> lint_example.rs:4:9
       |
    4  | /         macro_rules! exported {
    5  | |             () => {};
    6  | |         }
       | |_________^
    ...
    10 |   define_exported!();
       |   ------------------- in this macro invocation
       = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

### Explanation

The intent is that all macros marked with the `#[macro_export]` attribute are made available in the root of the crate. However, when a `macro_rules!` definition is generated by another macro, the macro expansion is unable to uphold this rule. This is a future-incompatible lint to transition this to a hard error in the future. See issue #53495 for more details.

## missing-fragment-specifier

The `missing_fragment_specifier` lint is issued when an unused pattern in a `macro_rules!` macro definition has a meta-variable (e.g. `$e`) that is not followed by a fragment specifier (e.g. `:expr`).

This warning can always be fixed by removing the unused pattern in the `macro_rules!` macro definition.

### Example

    macro_rules! foo {
       () => {};
       ($name) => { };
    }

    fn main() {
       foo!();
    }

This will produce:

    error: missing fragment specifier
     --> lint_example.rs:3:5
      |
    3 |    ($name) => { };
      |     ^^^^^
      |
      = note: `#[deny(missing_fragment_specifier)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>

### Explanation

To fix this, remove the unused pattern from the `macro_rules!` macro definition:

    macro_rules! foo {
        () => {};
    }
    fn main() {
        foo!();
    }

## mutable-transmutes

The `mutable_transmutes` lint catches transmuting from `&T` to `&mut T` because it is undefined behavior.

### Example

    #![allow(unused)]
    fn main() {
    unsafe {
        let y = std::mem::transmute::<&i32, &mut i32>(&5);
    }
    }

This will produce:

    error: mutating transmuted &mut T from &T may cause undefined behavior, consider instead using an UnsafeCell
     --> lint_example.rs:3:13
      |
    3 |     let y = std::mem::transmute::<&i32, &mut i32>(&5);
      |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[deny(mutable_transmutes)]` on by default

### Explanation

Certain assumptions are made about aliasing of data, and this transmute violates those assumptions. Consider using `UnsafeCell` instead.

## no-mangle-const-items

The `no_mangle_const_items` lint detects any `const` items with the `no_mangle` attribute.

### Example

    #![allow(unused)]
    fn main() {
    #[no_mangle]
    const FOO: i32 = 5;
    }

This will produce:

    error: const items should never be `#[no_mangle]`
     --> lint_example.rs:3:1
      |
    3 | const FOO: i32 = 5;
      | -----^^^^^^^^^^^^^^
      | |
      | help: try a static value: `pub static`
      |
      = note: `#[deny(no_mangle_const_items)]` on by default

### Explanation

Constants do not have their symbols exported, and therefore, this probably means you meant to use a `static`, not a `const`.

## order-dependent-trait-objects

The `order_dependent_trait_objects` lint detects a trait coherency violation that would allow creating two trait impls for the same dynamic trait object involving marker traits.

### Example

    #![allow(unused)]
    fn main() {
    pub trait Trait {}

    impl Trait for dyn Send + Sync { }
    impl Trait for dyn Sync + Send { }
    }

This will produce:

    error: conflicting implementations of trait `main::Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
     --> lint_example.rs:5:1
      |
    4 | impl Trait for dyn Send + Sync { }
      | ------------------------------ first implementation here
    5 | impl Trait for dyn Sync + Send { }
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
      |
      = note: `#[deny(order_dependent_trait_objects)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

### Explanation

A previous bug caused the compiler to interpret traits with different orders (such as `Send + Sync` and `Sync + Send`) as distinct types when they were intended to be treated the same. This allowed code to define separate trait implementations when there should be a coherence error. This is a future-incompatible lint to transition this to a hard error in the future. See issue #56484 for more details.

## overflowing-literals

The `overflowing_literals` lint detects literal out of range for its type.

### Example

    #![allow(unused)]
    fn main() {
    let x: u8 = 1000;
    }

This will produce:

    error: literal out of range for `u8`
     --> lint_example.rs:2:13
      |
    2 | let x: u8 = 1000;
      |             ^^^^
      |
      = note: `#[deny(overflowing_literals)]` on by default
      = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`

### Explanation

It is usually a mistake to use a literal that overflows the type where it is used. Either use a literal that is within range, or change the type to be within the range of the literal.

## patterns-in-fns-without-body

The `patterns_in_fns_without_body` lint detects `mut` identifier patterns as a parameter in functions without a body.

### Example

    #![allow(unused)]
    fn main() {
    trait Trait {
        fn foo(mut arg: u8);
    }
    }

This will produce:

    error: patterns aren't allowed in functions without bodies
     --> lint_example.rs:3:12
      |
    3 |     fn foo(mut arg: u8);
      |            ^^^^^^^
      |
      = note: `#[deny(patterns_in_fns_without_body)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>

### Explanation

To fix this, remove `mut` from the parameter in the trait definition; it can be used in the implementation. That is, the following is OK:

    #![allow(unused)]
    fn main() {
    trait Trait {
        fn foo(arg: u8); // Removed `mut` here
    }

    impl Trait for i32 {
        fn foo(mut arg: u8) { // `mut` here is OK

        }
    }
    }

Trait definitions can define functions without a body to specify a function that implementors must define. The parameter names in the body-less functions are only allowed to be `_` or an identifier for documentation purposes (only the type is relevant). Previous versions of the compiler erroneously allowed identifier patterns with the `mut` keyword, but this was not intended to be allowed. This is a future-incompatible lint to transition this to a hard error in the future. See issue #35203 for more details.

## pub-use-of-private-extern-crate

The `pub_use_of_private_extern_crate` lint detects a specific situation of re-exporting a private `extern crate`.

### Example

    #![allow(unused)]
    fn main() {
    extern crate core;
    pub use core as reexported_core;
    }

This will produce:

    error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
     --> lint_example.rs:3:9
      |
    3 | pub use core as reexported_core;
      |         ^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: `#[deny(pub_use_of_private_extern_crate)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>

### Explanation

A public `use` declaration should not be used to publicly re-export a private `extern crate`. `pub extern crate` should be used instead.

This was historically allowed, but is not the intended behavior according to the visibility rules. This is a future-incompatible lint to transition this to a hard error in the future. See issue #34537 for more details.

## soft-unstable

The `soft_unstable` lint detects unstable features that were unintentionally allowed on stable.

### Example

    #![allow(unused)]
    fn main() {
    #[cfg(test)]
    extern crate test;

    #[bench]
    fn name(b: &mut test::Bencher) {
        b.iter(|| 123)
    }
    }

This will produce:

    error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
     --> lint_example.rs:5:3
      |
    5 | #[bench]
      |   ^^^^^
      |
      = note: `#[deny(soft_unstable)]` on by default
      = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
      = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>

### Explanation

The `bench` attribute was accidentally allowed to be specified on the stable release channel. Turning this to a hard error would have broken some projects. This lint allows those projects to continue to build correctly when `--cap-lints` is used, but otherwise signal an error that `#[bench]` should not be used on the stable channel. This is a future-incompatible lint to transition this to a hard error in the future. See issue #64266 for more details.

## unconditional-panic

The `unconditional_panic` lint detects an operation that will cause a panic at runtime.

### Example

    #![allow(unused)]
    fn main() {
    #![allow(unused)]
    let x = 1 / 0;
    }

This will produce:

    error: this operation will panic at runtime
     --> lint_example.rs:3:9
      |
    3 | let x = 1 / 0;
      |         ^^^^^ attempt to divide `1_i32` by zero
      |
      = note: `#[deny(unconditional_panic)]` on by default

### Explanation

This lint detects code that is very likely incorrect. When possible, the compiler will attempt to detect situations where code can be evaluated at compile-time to generate more efficient code. While evaluating such code, if it detects that the code will unconditionally panic, this usually indicates that it is doing something incorrectly. If this lint is allowed, then the code will not be evaluated at compile-time, and instead continue to generate code to evaluate at runtime, which may panic during runtime.

## unknown-crate-types

The `unknown_crate_types` lint detects an unknown crate type found in a `crate_type` attribute.

### Example

    #![crate_type="lol"]
    fn main() {}

This will produce:

    error: invalid `crate_type` value
     --> lint_example.rs:1:15
      |
    1 | #![crate_type="lol"]
      |               ^^^^^
      |
      = note: `#[deny(unknown_crate_types)]` on by default

### Explanation

An unknown value give to the `crate_type` attribute is almost certainly a mistake.

## useless-deprecated

The `useless_deprecated` lint detects deprecation attributes with no effect.

### Example

    #![allow(unused)]
    fn main() {
    struct X;

    #[deprecated = "message"]
    impl Default for X {
        fn default() -> Self {
            X
        }
    }
    }

This will produce:

    error: this `#[deprecated]` annotation has no effect
     --> lint_example.rs:4:1
      |
    4 | #[deprecated = "message"]
      | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the unnecessary deprecation attribute
      |
      = note: `#[deny(useless_deprecated)]` on by default

### Explanation

Deprecation attributes have no effect on trait implementations.

# Codegen options

All of these options are passed to `rustc` via the `-C` flag, short for "codegen." You can see a version of this list for your exact compiler by running `rustc -C help`.

## ar

This option is deprecated and does nothing.

## code-model

This option lets you choose which code model to use.
Code models put constraints on address ranges that the program and its symbols may use.
With smaller address ranges machine instructions may be able to use more compact addressing modes.

The specific ranges depend on target architectures and addressing modes available to them.
For x86 more detailed description of its code models can be found in System V Application Binary Interface specification.

Supported values for this option are:

- `tiny` - Tiny code model.
- `small` - Small code model. This is the default model for majority of supported targets.
- `kernel` - Kernel code model.
- `medium` - Medium code model.
- `large` - Large code model.

Supported values can also be discovered by running `rustc --print code-models`.

## codegen-units

This flag controls how many code generation units the crate is split into. It takes an integer greater than 0.

When a crate is split into multiple codegen units, LLVM is able to process them in parallel. Increasing parallelism may speed up compile times, but may also produce slower code. Setting this to 1 may improve the performance of generated code, but may be slower to compile.

The default value, if not specified, is 16 for non-incremental builds. For incremental builds the default is 256 which allows caching to be more granular.

## control-flow-guard

This flag controls whether LLVM enables the Windows Control Flow Guard platform security feature. This flag is currently ignored for non-Windows targets. It takes one of the following values:

- `y`, `yes`, `on`, `checks`, or no value: enable Control Flow Guard.
- `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this should only be used for testing purposes as it does not provide security enforcement).
- `n`, `no`, `off`: do not enable Control Flow Guard (the default).

## debug-assertions

This flag lets you turn `cfg(debug_assertions)` conditional compilation on or off. It takes one of the following values:

- `y`, `yes`, `on`, or no value: enable debug-assertions.
- `n`, `no`, or `off`: disable debug-assertions.

If not specified, debug assertions are automatically enabled only if the opt-level is 0.

## debuginfo

This flag controls the generation of debug information. It takes one of the following values:

- `0`: no debug info at all (the default).
- `1`: line tables only.
- `2`: full debug info.

Note: The `-g` flag is an alias for `-C debuginfo=2`.

## default-linker-libraries

This flag controls whether or not the linker includes its default libraries. It takes one of the following values:

- `y`, `yes`, `on`, or no value: include default libraries (the default).
- `n`, `no`, or `off`: exclude default libraries.

For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to the linker.

## embed-bitcode

This flag controls whether or not the compiler embeds LLVM bitcode into object files. It takes one of the following values:

- `y`, `yes`, `on`, or no value: put bitcode in rlibs (the default).
- `n`, `no`, or `off`: omit bitcode from rlibs.

LLVM bitcode is required when rustc is performing link-time optimization (LTO). It is also required on some targets like iOS ones where vendors look for LLVM bitcode. Embedded bitcode will appear in rustc-generated object files inside of a section whose name is defined by the target platform. Most of the time this is `.llvmbc`.

The use of `-C embed-bitcode=no` can significantly improve compile times and reduce generated file sizes if your compilation does not actually need bitcode (e.g. if you're not compiling for iOS or you're not performing LTO). For these reasons, Cargo uses `-C embed-bitcode=no` whenever possible. Likewise, if you are building directly with `rustc` we recommend using `-C embed-bitcode=no` whenever you are not using LTO.

If combined with `-C lto`, `-C embed-bitcode=no` will cause `rustc` to abort at start-up, because the combination is invalid.

> Note: if you're building Rust code with LTO then you probably don't even need the `embed-bitcode` option turned on. You'll likely want to use `-Clinker-plugin-lto` instead which skips generating object files entirely and simply replaces object files with LLVM bitcode. The only purpose for `-Cembed-bitcode` is when you're generating an rlib that is both being used with and without LTO. For example Rust's standard library ships with embedded bitcode since users link to it both with and without LTO.

> This also may make you wonder why the default is `yes` for this option. The reason for that is that it's how it was for rustc 1.44 and prior. In 1.45 this option was added to turn off what had always been the default.

## extra-filename

This option allows you to put extra data in each output filename. It takes a string to add as a suffix to the filename. See the `--emit` flag for more information.

## force-frame-pointers

This flag forces the use of frame pointers. It takes one of the following values:

- `y`, `yes`, `on`, or no value: force-enable frame pointers.
- `n`, `no`, or `off`: do not force-enable frame pointers. This does not necessarily mean frame pointers will be removed.

The default behaviour, if frame pointers are not force-enabled, depends on the target.

## force-unwind-tables

This flag forces the generation of unwind tables. It takes one of the following values:

- `y`, `yes`, `on`, or no value: Unwind tables are forced to be generated.
- `n`, `no`, or `off`: Unwind tables are not forced to be generated. If unwind tables are required by the target or `-C panic=unwind`, an error will be emitted.

The default if not specified depends on the target.

## incremental

This flag allows you to enable incremental compilation, which allows `rustc` to save information after compiling a crate to be reused when recompiling the crate, improving re-compile times. This takes a path to a directory where incremental files will be stored.

## inline-threshold

This option lets you set the default threshold for inlining a function. It takes an unsigned integer as a value. Inlining is based on a cost model, where a higher threshold will allow more inlining.

The default depends on the opt-level:

opt-level | Threshold
--- | ---
0 | N/A, only inlines always-inline functions
1 | N/A, only inlines always-inline functions and LLVM lifetime intrinsics
2 | 225
3 | 275
s | 75
z | 25

## link-arg

This flag lets you append a single extra argument to the linker invocation.

"Append" is significant; you can pass this flag multiple times to add multiple arguments.

## link-args

This flag lets you append multiple extra arguments to the linker invocation. The options should be separated by spaces.

## link-dead-code

This flag controls whether the linker will keep dead code. It takes one of the following values:

- `y`, `yes`, `on`, or no value: keep dead code.
- `n`, `no`, or `off`: remove dead code (the default).

An example of when this flag might be useful is when trying to construct code coverage metrics.

## link-self-contained

On targets that support it this flag controls whether the linker will use libraries and objects shipped with Rust instead or those in the system. It takes one of the following values:

- no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
- `y`, `yes`, `on`: use only libraries/objects shipped with Rust.
- `n`, `no`, or `off`: rely on the user or the linker to provide non-Rust libraries/objects.

This allows overriding cases when detection fails or user wants to use shipped libraries.

## linker

This flag controls which linker `rustc` invokes to link your code. It takes a path to the linker executable. If this flag is not specified, the linker will be inferred based on the target. See also the linker-flavor flag for another way to specify the linker.

## linker-flavor

This flag controls the linker flavor used by `rustc`. If a linker is given with the `-C linker` flag, then the linker flavor is inferred from the value provided. If no linker is given then the linker flavor is used to determine the linker to use. Every `rustc` target defaults to some linker flavor. Valid options are:

- `em`: use Emscripten `emcc`.
- `gcc`: use the `cc` executable, which is typically gcc or clang on many systems.
- `ld`: use the `ld` executable.
- `msvc`: use the `link.exe` executable from Microsoft Visual Studio MSVC.
- `ptx-linker`: use `rust-ptx-linker` for Nvidia NVPTX GPGPU support.
- `wasm-ld`: use the `wasm-ld` executable, a port of LLVM `lld` for WebAssembly.
- `ld64.lld`: use the LLVM `lld` executable with the `-flavor darwin` flag for Apple's `ld`.
- `ld.lld`: use the LLVM `lld` executable with the `-flavor gnu` flag for GNU binutils' `ld`.
- `lld-link`: use the LLVM `lld` executable with the `-flavor link` flag for Microsoft's `link.exe`.

## linker-plugin-lto

This flag defers LTO optimizations to the linker. See linker-plugin-LTO for more details. It takes one of the following values:

- `y`, `yes`, `on`, or no value: enable linker plugin LTO.
- `n`, `no`, or `off`: disable linker plugin LTO (the default).
- A path to the linker plugin.

More specifically this flag will cause the compiler to replace its typical object file output with LLVM bitcode files. For example an rlib produced with `-Clinker-plugin-lto` will still have `*.o` files in it, but they'll all be LLVM bitcode instead of actual machine code. It is expected that the native platform linker is capable of loading these LLVM bitcode files and generating code at link time (typically after performing optimizations).

Note that rustc can also read its own object files produced with `-Clinker-plugin-lto`. If an rlib is only ever going to get used later with a `-Clto` compilation then you can pass `-Clinker-plugin-lto` to speed up compilation and avoid generating object files that aren't used.

## llvm-args

This flag can be used to pass a list of arguments directly to LLVM.

The list must be separated by spaces.

Pass `--help` to see a list of options.

## lto

This flag controls whether LLVM uses link time optimizations to produce better optimized code, using whole-program analysis, at the cost of longer linking time. It takes one of the following values:

- `y`, `yes`, `on`, `fat`, or no value: perform "fat" LTO which attempts to perform optimizations across all crates within the dependency graph.
- `n`, `no`, `off`: disables LTO.
- `thin`: perform "thin" LTO. This is similar to "fat", but takes substantially less time to run while still achieving performance gains similar to "fat".

If `-C lto` is not specified, then the compiler will attempt to perform "thin local LTO" which performs "thin" LTO on the local crate only across its codegen units. When `-C lto` is not specified, LTO is disabled if codegen units is 1 or optimizations are disabled (`-C opt-level=0`). That is:

- When `-C lto` is not specified:
  - `codegen-units=1`: disable LTO.
  - `opt-level=0`: disable LTO.
- When `-C lto=true`:
  - `lto=true`: 16 codegen units, perform fat LTO across crates.
  - `codegen-units=1` + `lto=true`: 1 codegen unit, fat LTO across crates.

See also linker-plugin-lto for cross-language LTO.

## metadata

This option allows you to control the metadata used for symbol mangling. This takes a space-separated list of strings. Mangled symbols will incorporate a hash of the metadata. This may be used, for example, to differentiate symbols between two different versions of the same crate being linked.

## no-prepopulate-passes

This flag tells the pass manager to use an empty list of passes, instead of the usual pre-populated list of passes.

## no-redzone

This flag allows you to disable the red zone. It takes one of the following values:

- `y`, `yes`, `on`, or no value: disable the red zone.
- `n`, `no`, or `off`: enable the red zone.

The default behaviour, if the flag is not specified, depends on the target.

## no-stack-check

This option is deprecated and does nothing.

## no-vectorize-loops

This flag disables loop vectorization.

## no-vectorize-slp

This flag disables vectorization using superword-level parallelism.

## opt-level

This flag controls the optimization level.

- `0`: no optimizations, also turns on `cfg(debug_assertions)` (the default).
- `1`: basic optimizations.
- `2`: some optimizations.
- `3`: all optimizations.
- `s`: optimize for binary size.
- `z`: optimize for binary size, but also turn off loop vectorization.

Note: The `-O` flag is an alias for `-C opt-level=2`.

The default is `0`.

## overflow-checks

This flag allows you to control the behavior of runtime integer overflow. When overflow-checks are enabled, a panic will occur on overflow. This flag takes one of the following values:

- `y`, `yes`, `on`, or no value: enable overflow checks.
- `n`, `no`, or `off`: disable overflow checks.

If not specified, overflow checks are enabled if debug-assertions are enabled, disabled otherwise.

## panic

This option lets you control what happens when the code panics.

- `abort`: terminate the process upon panic
- `unwind`: unwind the stack upon panic

If not specified, the default depends on the target.

## passes

This flag can be used to add extra LLVM passes to the compilation.

The list must be separated by spaces.

See also the `no-prepopulate-passes` flag.

## prefer-dynamic

By default, `rustc` prefers to statically link dependencies. This option will indicate that dynamic linking should be used if possible if both a static and dynamic versions of a library are available. There is an internal algorithm for determining whether or not it is possible to statically or dynamically link with a dependency. For example, `cdylib` crate types may only use static linkage. This flag takes one of the following values:

- `y`, `yes`, `on`, or no value: use dynamic linking.
- `n`, `no`, or `off`: use static linking (the default).

## profile-generate

This flag allows for creating instrumented binaries that will collect profiling data for use with profile-guided optimization (PGO). The flag takes an optional argument which is the path to a directory into which the instrumented binary will emit the collected data. See the chapter on profile-guided optimization for more information.

## profile-use

This flag specifies the profiling data file to be used for profile-guided optimization (PGO). The flag takes a mandatory argument which is the path to a valid `.profdata` file. See the chapter on profile-guided optimization for more information.

## relocation-model

This option controls generation of position-independent code (PIC).

Supported values for this option are:

#### Primary relocation models

- `static` - non-relocatable code, machine instructions may use absolute addressing modes.

- `pic` - fully relocatable position independent code, machine instructions need to use relative addressing modes.
  Equivalent to the "uppercase" `-fPIC` or `-fPIE` options in other compilers, depending on the produced crate types.
  This is the default model for majority of supported targets.

#### Special relocation models

- `dynamic-no-pic` - relocatable external references, non-relocatable code.
  Only makes sense on Darwin and is rarely used.
  If StackOverflow tells you to use this as an opt-out of PIC or PIE, don't believe it, use `-C relocation-model=static` instead.
- `ropi`, `rwpi` and `ropi-rwpi` - relocatable code and read-only data, relocatable read-write data, and combination of both, respectively.
  Only makes sense for certain embedded ARM targets.
- `default` - relocation model default to the current target.
  Only makes sense as an override for some other explicitly specified relocation model previously set on the command line.

Supported values can also be discovered by running `rustc --print relocation-models`.

#### Linking effects

In addition to codegen effects, `relocation-model` has effects during linking.

If the relocation model is `pic` and the current target supports position-independent executables (PIE), the linker will be instructed (`-pie`) to produce one.
If the target doesn't support both position-independent and statically linked executables, then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`, and the linker is instructed (`-static`) to produce a statically linked but not position-independent executable.

## remark

This flag lets you print remarks for optimization passes.

The list of passes should be separated by spaces.

`all` will remark on every pass.

## rpath

This flag controls whether `rpath` is enabled. It takes one of the following values:

- `y`, `yes`, `on`, or no value: enable rpath.
- `n`, `no`, or `off`: disable rpath (the default).

## save-temps

This flag controls whether temporary files generated during compilation are deleted once compilation finishes. It takes one of the following values:

- `y`, `yes`, `on`, or no value: save temporary files.
- `n`, `no`, or `off`: delete temporary files (the default).

## soft-float

This option controls whether `rustc` generates code that emulates floating point instructions in software. It takes one of the following values:

- `y`, `yes`, `on`, or no value: use soft floats.
- `n`, `no`, or `off`: use hardware floats (the default).

## target-cpu

This instructs `rustc` to generate code specifically for a particular processor.

You can run `rustc --print target-cpus` to see the valid options to pass here. Each target has a default base CPU. Special values include:

- `native` can be passed to use the processor of the host machine.
- `generic` refers to an LLVM target with minimal features but modern tuning.

## target-feature

Individual targets will support different features; this flag lets you control enabling or disabling a feature. Each feature should be prefixed with a `+` to enable it or `-` to disable it.

Features from multiple `-C target-feature` options are combined.
Multiple features can be specified in a single option by separating them with commas - `-C target-feature=+x,-y`.
If some feature is specified more than once with both `+` and `-`, then values passed later override values passed earlier.
For example, `-C target-feature=+x,-y,+z -Ctarget-feature=-x,+y` is equivalent to `-C target-feature=-x,+y,+z`.

To see the valid options and an example of use, run `rustc --print target-features`.

Using this flag is unsafe and might result in undefined runtime behavior.

See also the `target_feature` attribute for controlling features per-function.

This also supports the feature `+crt-static` and `-crt-static` to control static C runtime linkage.

Each target and `target-cpu` has a default set of enabled features.

## tune-cpu

This instructs `rustc` to schedule code specifically for a particular processor. This does not affect the compatibility (instruction sets or ABI), but should make your code slightly more efficient on the selected CPU.

The valid options are the same as those for `target-cpu`. The default is `None`, which LLVM translates as the `target-cpu`.

This is an unstable option. Use `-Z tune-cpu=machine` to specify a value.

Due to limitations in LLVM (12.0.0-git9218f92), this option is currently effective only for x86 targets.

# JSON Output

This chapter documents the JSON structures emitted by `rustc`. JSON may be enabled with the `--error-format=json` flag. Additional options may be specified with the `--json` flag which can change which messages are generated, and the format of the messages.

JSON messages are emitted one per line to stderr.

If parsing the output with Rust, the `cargo_metadata` crate provides some support for parsing the messages.

When parsing, care should be taken to be forwards-compatible with future changes to the format. Optional values may be `null`. New fields may be added. Enumerated fields like "level" or "suggestion_applicability" may add new values.

## Diagnostics

Diagnostic messages provide errors or possible concerns generated during compilation. `rustc` provides detailed information about where the diagnostic originates, along with hints and suggestions.

Diagnostics are arranged in a parent/child relationship where the parent diagnostic value is the core of the diagnostic, and the attached children provide additional context, help, and information.

Diagnostics have the following format:

    {
        /* The primary message. */
        "message": "unused variable: `x`",
        /* The diagnostic code.
           Some messages may set this value to null.
        */
        "code": {
            /* A unique string identifying which diagnostic triggered. */
            "code": "unused_variables",
            /* An optional string explaining more detail about the diagnostic code. */
            "explanation": null
        },
        /* The severity of the diagnostic.
           Values may be:
           - "error": A fatal error that prevents compilation.
           - "warning": A possible error or concern.
           - "note": Additional information or context about the diagnostic.
           - "help": A suggestion on how to resolve the diagnostic.
           - "failure-note": A note attached to the message for further information.
           - "error: internal compiler error": Indicates a bug within the compiler.
        */
        "level": "warning",
        /* An array of source code locations to point out specific details about
           where the diagnostic originates from. This may be empty, for example
           for some global messages, or child messages attached to a parent.

           Character offsets are offsets of Unicode Scalar Values.
        */
        "spans": [
            {
                /* The file where the span is located.
                   Note that this path may not exist. For example, if the path
                   points to the standard library, and the rust src is not
                   available in the sysroot, then it may point to a non-existent
                   file. Beware that this may also point to the source of an
                   external crate.
                */
                "file_name": "lib.rs",
                /* The byte offset where the span starts (0-based, inclusive). */
                "byte_start": 21,
                /* The byte offset where the span ends (0-based, exclusive). */
                "byte_end": 22,
                /* The first line number of the span (1-based, inclusive). */
                "line_start": 2,
                /* The last line number of the span (1-based, inclusive). */
                "line_end": 2,
                /* The first character offset of the line_start (1-based, inclusive). */
                "column_start": 9,
                /* The last character offset of the line_end (1-based, exclusive). */
                "column_end": 10,
                /* Whether or not this is the "primary" span.

                   This indicates that this span is the focal point of the
                   diagnostic.

                   There are rare cases where multiple spans may be marked as
                   primary. For example, "immutable borrow occurs here" and
                   "mutable borrow ends here" can be two separate primary spans.

                   The top (parent) message should always have at least one
                   primary span, unless it has zero spans. Child messages may have
                   zero or more primary spans.
                */
                "is_primary": true,
                /* An array of objects showing the original source code for this
                   span. This shows the entire lines of text where the span is
                   located. A span across multiple lines will have a separate
                   value for each line.
                */
                "text": [
                    {
                        /* The entire line of the original source code. */
                        "text": "    let x = 123;",
                        /* The first character offset of the line of
                           where the span covers this line (1-based, inclusive). */
                        "highlight_start": 9,
                        /* The last character offset of the line of
                           where the span covers this line (1-based, exclusive). */
                        "highlight_end": 10
                    }
                ],
                /* An optional message to display at this span location.
                   This is typically null for primary spans.
                */
                "label": null,
                /* An optional string of a suggested replacement for this span to
                   solve the issue. Tools may try to replace the contents of the
                   span with this text.
                */
                "suggested_replacement": null,
                /* An optional string that indicates the confidence of the
                   "suggested_replacement". Tools may use this value to determine
                   whether or not suggestions should be automatically applied.

                   Possible values may be:
                   - "MachineApplicable": The suggestion is definitely what the
                     user intended. This suggestion should be automatically
                     applied.
                   - "MaybeIncorrect": The suggestion may be what the user
                     intended, but it is uncertain. The suggestion should result
                     in valid Rust code if it is applied.
                   - "HasPlaceholders": The suggestion contains placeholders like
                     `(...)`. The suggestion cannot be applied automatically
                     because it will not result in valid Rust code. The user will
                     need to fill in the placeholders.
                   - "Unspecified": The applicability of the suggestion is unknown.
                */
                "suggestion_applicability": null,
                /* An optional object indicating the expansion of a macro within
                   this span.

                   If a message occurs within a macro invocation, this object will
                   provide details of where within the macro expansion the message
                   is located.
                */
                "expansion": {
                    /* The span of the macro invocation.
                       Uses the same span definition as the "spans" array.
                    */
                    "span": {/*...*/}
                    /* Name of the macro, such as "foo!" or "#[derive(Eq)]". */
                    "macro_decl_name": "some_macro!",
                    /* Optional span where the relevant part of the macro is
                      defined. */
                    "def_site_span": {/*...*/},
                }
            }
        ],
        /* Array of attached diagnostic messages.
           This is an array of objects using the same format as the parent
           message. Children are not nested (children do not themselves
           contain "children" definitions).
        */
        "children": [
            {
                "message": "`#[warn(unused_variables)]` on by default",
                "code": null,
                "level": "note",
                "spans": [],
                "children": [],
                "rendered": null
            },
            {
                "message": "if this is intentional, prefix it with an underscore",
                "code": null,
                "level": "help",
                "spans": [
                    {
                        "file_name": "lib.rs",
                        "byte_start": 21,
                        "byte_end": 22,
                        "line_start": 2,
                        "line_end": 2,
                        "column_start": 9,
                        "column_end": 10,
                        "is_primary": true,
                        "text": [
                            {
                                "text": "    let x = 123;",
                                "highlight_start": 9,
                                "highlight_end": 10
                            }
                        ],
                        "label": null,
                        "suggested_replacement": "_x",
                        "suggestion_applicability": "MachineApplicable",
                        "expansion": null
                    }
                ],
                "children": [],
                "rendered": null
            }
        ],
        /* Optional string of the rendered version of the diagnostic as displayed
           by rustc. Note that this may be influenced by the `--json` flag.
        */
        "rendered": "warning: unused variable: `x`\n --> lib.rs:2:9\n  |\n2 |     let x = 123;\n  |         ^ help: if this is intentional, prefix it with an underscore: `_x`\n  |\n  = note: `#[warn(unused_variables)]` on by default\n\n"
    }

## Artifact notifications

Artifact notifications are emitted when the `--json=artifacts` flag is used. They indicate that a file artifact has been saved to disk. More information about emit kinds may be found in the `--emit` flag documentation.

    {
        /* The filename that was generated. */
        "artifact": "libfoo.rlib",
        /* The kind of artifact that was generated. Possible values:
           - "link": The generated crate as specified by the crate-type.
           - "dep-info": The `.d` file with dependency information in a Makefile-like syntax.
           - "metadata": The Rust `.rmeta` file containing metadata about the crate.
           - "save-analysis": A JSON file emitted by the `-Zsave-analysis` feature.
        */
        "emit": "link"
    }

# Platform Support

Support for different platforms are organized into three tiers, each with a different set of guarantees.

Platforms are identified by their "target triple" which is the string to inform the compiler what kind of output should be produced. The columns in the tables below have the following meanings:

- std:
  - ✓ indicates the full standard library is available.
  - * indicates the target only supports `no_std` development.
  - ? indicates the standard library support is unknown or a work-in-progress.
- host: A ✓ indicates that `rustc` and `cargo` can run on the host platform.

## Tier 1

Tier 1 platforms can be thought of as "guaranteed to work". Specifically they will each satisfy the following requirements:

- Official binary releases are provided for the platform.
- Automated testing is set up to run tests for the platform.
- Landing changes to the `rust-lang/rust` repository's master branch is gated on tests passing.
- Documentation for how to use and how to build the platform is available.

target | std | host | notes
--- | --- | --- | ---
`aarch64-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (kernel 4.2, glibc 2.17+) 1
`i686-pc-windows-gnu` | ✓ | ✓ | 32-bit MinGW (Windows 7+)
`i686-pc-windows-msvc` | ✓ | ✓ | 32-bit MSVC (Windows 7+)
`i686-unknown-linux-gnu` | ✓ | ✓ | 32-bit Linux (kernel 2.6.32+, glibc 2.11+)
`x86_64-apple-darwin` | ✓ | ✓ | 64-bit macOS (10.7+, Lion+)
`x86_64-pc-windows-gnu` | ✓ | ✓ | 64-bit MinGW (Windows 7+)
`x86_64-pc-windows-msvc` | ✓ | ✓ | 64-bit MSVC (Windows 7+)
`x86_64-unknown-linux-gnu` | ✓ | ✓ | 64-bit Linux (kernel 2.6.32+, glibc 2.11+)

1

Stack probes support is missing on `aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near future. The implementation is tracked on issue #77071.

## Tier 2

Tier 2 platforms can be thought of as "guaranteed to build". Automated tests are not run so it's not guaranteed to produce a working build, but platforms often work to quite a good degree and patches are always welcome! Specifically, these platforms are required to have each of the following:

- Official binary releases are provided for the platform.
- Automated building is set up, but may not be running tests.
- Landing changes to the `rust-lang/rust` repository's master branch is gated on platforms building. For some platforms only the standard library is compiled, but for others `rustc` and `cargo` are too.

target | std | host | notes
--- | --- | --- | ---
`aarch64-apple-darwin` | ✓ | ✓ | ARM64 macOS (11.0+, Big Sur+)
`aarch64-apple-ios` | ✓ |  | ARM64 iOS
`aarch64-fuchsia` | ✓ |  | ARM64 Fuchsia
`aarch64-linux-android` | ✓ |  | ARM64 Android
`aarch64-pc-windows-msvc` | ✓ | ✓ | ARM64 Windows MSVC
`aarch64-unknown-linux-musl` | ✓ | ✓ | ARM64 Linux with MUSL
`aarch64-unknown-none` | * |  | Bare ARM64, hardfloat
`aarch64-unknown-none-softfloat` | * |  | Bare ARM64, softfloat
`arm-linux-androideabi` | ✓ |  | ARMv7 Android
`arm-unknown-linux-gnueabi` | ✓ | ✓ | ARMv6 Linux (kernel 3.2, glibc 2.17)
`arm-unknown-linux-gnueabihf` | ✓ | ✓ | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
`arm-unknown-linux-musleabi` | ✓ |  | ARMv6 Linux with MUSL
`arm-unknown-linux-musleabihf` | ✓ |  | ARMv6 Linux with MUSL, hardfloat
`armebv7r-none-eabi` | * |  | Bare ARMv7-R, Big Endian
`armebv7r-none-eabihf` | * |  | Bare ARMv7-R, Big Endian, hardfloat
`armv5te-unknown-linux-gnueabi` | ✓ |  | ARMv5TE Linux (kernel 4.4, glibc 2.23)
`armv5te-unknown-linux-musleabi` | ✓ |  | ARMv5TE Linux with MUSL
`armv7-linux-androideabi` | ✓ |  | ARMv7a Android
`armv7a-none-eabi` | * |  | Bare ARMv7-A
`armv7r-none-eabi` | * |  | Bare ARMv7-R
`armv7r-none-eabihf` | * |  | Bare ARMv7-R, hardfloat
`armv7-unknown-linux-gnueabi` | ✓ |  | ARMv7 Linux (kernel 4.15, glibc 2.27)
`armv7-unknown-linux-gnueabihf` | ✓ | ✓ | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
`armv7-unknown-linux-musleabi` | ✓ |  | ARMv7 Linux, MUSL
`armv7-unknown-linux-musleabihf` | ✓ |  | ARMv7 Linux with MUSL
`asmjs-unknown-emscripten` | ✓ |  | asm.js via Emscripten
`i586-pc-windows-msvc` | ✓ |  | 32-bit Windows w/o SSE
`i586-unknown-linux-gnu` | ✓ |  | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
`i586-unknown-linux-musl` | ✓ |  | 32-bit Linux w/o SSE, MUSL
`i686-linux-android` | ✓ |  | 32-bit x86 Android
`i686-unknown-freebsd` | ✓ |  | 32-bit FreeBSD
`i686-unknown-linux-musl` | ✓ |  | 32-bit Linux with MUSL
`mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
`mips-unknown-linux-musl` | ✓ |  | MIPS Linux with MUSL
`mips64-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23)
`mips64-unknown-linux-muslabi64` | ✓ |  | MIPS64 Linux, n64 ABI, MUSL
`mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23)
`mips64el-unknown-linux-muslabi64` | ✓ |  | MIPS64 (LE) Linux, n64 ABI, MUSL
`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (LE) Linux (kernel 4.4, glibc 2.23)
`mipsel-unknown-linux-musl` | ✓ |  | MIPS (LE) Linux with MUSL
`nvptx64-nvidia-cuda` | ✓ |  | --emit=asm generates PTX code that runs on NVIDIA GPUs
`powerpc-unknown-linux-gnu` | ✓ | ✓ | PowerPC Linux (kernel 2.6.32, glibc 2.11)
`powerpc64-unknown-linux-gnu` | ✓ | ✓ | PPC64 Linux (kernel 2.6.32, glibc 2.11)
`powerpc64le-unknown-linux-gnu` | ✓ | ✓ | PPC64LE Linux (kernel 3.10, glibc 2.17)
`riscv32i-unknown-none-elf` | * |  | Bare RISC-V (RV32I ISA)
`riscv32imac-unknown-none-elf` | * |  | Bare RISC-V (RV32IMAC ISA)
`riscv32imc-unknown-none-elf` | * |  | Bare RISC-V (RV32IMC ISA)
`riscv64gc-unknown-linux-gnu` | ✓ | ✓ | RISC-V Linux (kernel 4.20, glibc 2.29)
`riscv64gc-unknown-none-elf` | * |  | Bare RISC-V (RV64IMAFDC ISA)
`riscv64imac-unknown-none-elf` | * |  | Bare RISC-V (RV64IMAC ISA)
`s390x-unknown-linux-gnu` | ✓ | ✓ | S390x Linux (kernel 2.6.32, glibc 2.11)
`sparc64-unknown-linux-gnu` | ✓ |  | SPARC Linux (kernel 4.4, glibc 2.23)
`sparcv9-sun-solaris` | ✓ |  | SPARC Solaris 10/11, illumos
`thumbv6m-none-eabi` | * |  | Bare Cortex-M0, M0+, M1
`thumbv7em-none-eabi` | * |  | Bare Cortex-M4, M7
`thumbv7em-none-eabihf` | * |  | Bare Cortex-M4F, M7F, FPU, hardfloat
`thumbv7m-none-eabi` | * |  | Bare Cortex-M3
`thumbv7neon-linux-androideabi` | ✓ |  | Thumb2-mode ARMv7a Android with NEON
`thumbv7neon-unknown-linux-gnueabihf` | ✓ |  | Thumb2-mode ARMv7a Linux with NEON (kernel 4.4, glibc 2.23)
`thumbv8m.base-none-eabi` | * |  | ARMv8-M Baseline
`thumbv8m.main-none-eabi` | * |  | ARMv8-M Mainline
`thumbv8m.main-none-eabihf` | * |  | ARMv8-M Mainline, hardfloat
`wasm32-unknown-emscripten` | ✓ |  | WebAssembly via Emscripten
`wasm32-unknown-unknown` | ✓ |  | WebAssembly
`wasm32-wasi` | ✓ |  | WebAssembly with WASI
`x86_64-apple-ios` | ✓ |  | 64-bit x86 iOS
`x86_64-fortanix-unknown-sgx` | ✓ |  | Fortanix ABI for 64-bit Intel SGX
`x86_64-fuchsia` | ✓ |  | 64-bit Fuchsia
`x86_64-linux-android` | ✓ |  | 64-bit x86 Android
`x86_64-rumprun-netbsd` | ✓ |  | 64-bit NetBSD Rump Kernel
`x86_64-sun-solaris` | ✓ |  | 64-bit Solaris 10/11, illumos
`x86_64-unknown-freebsd` | ✓ | ✓ | 64-bit FreeBSD
`x86_64-unknown-illumos` | ✓ | ✓ | illumos
`x86_64-unknown-linux-gnux32` | ✓ |  | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
`x86_64-unknown-linux-musl` | ✓ | ✓ | 64-bit Linux with MUSL
`x86_64-unknown-netbsd` | ✓ | ✓ | NetBSD/amd64
`x86_64-unknown-redox` | ✓ |  | Redox OS

## Tier 3

Tier 3 platforms are those which the Rust codebase has support for, but which are not built or tested automatically, and may not work. Official builds are not available.

target | std | host | notes
--- | --- | --- | ---
`aarch64-apple-ios-macabi` | ? |  | Apple Catalyst on ARM64
`aarch64-apple-tvos` | * |  | ARM64 tvOS
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
`aarch64-unknown-hermit` | ? |  |
`aarch64-unknown-netbsd` | ✓ | ✓ |
`aarch64-unknown-openbsd` | ✓ | ✓ | ARM64 OpenBSD
`aarch64-unknown-redox` | ? |  | ARM64 Redox OS
`aarch64-uwp-windows-msvc` | ? |  |
`aarch64-wrs-vxworks` | ? |  |
`armv4t-unknown-linux-gnueabi` | ? |  |
`armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
`armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
`armv6-unknown-netbsd-eabihf` | ? |  |
`armv7-apple-ios` | ✓ |  | ARMv7 iOS, Cortex-a8
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
`armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
`armv7-wrs-vxworks-eabihf` | ? |  |
`armv7a-none-eabihf` | * |  | ARM Cortex-A, hardfloat
`armv7s-apple-ios` | ✓ |  |
`avr-unknown-gnu-atmega328` | ✗ |  | AVR. Requires `-Z build-std=core`
`hexagon-unknown-linux-musl` | ? |  |
`i386-apple-ios` | ✓ |  | 32-bit x86 iOS
`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+)
`i686-pc-windows-msvc` | ✓ |  | 32-bit Windows XP support
`i686-unknown-uefi` | ? |  | 32-bit UEFI
`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
`i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2
`i686-unknown-openbsd` | ✓ | ✓ | 32-bit OpenBSD
`i686-uwp-windows-gnu` | ? |  |
`i686-uwp-windows-msvc` | ? |  |
`i686-wrs-vxworks` | ? |  |
`mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
`mipsel-unknown-linux-uclibc` | ✓ |  | MIPS (LE) Linux with uClibc
`mipsel-unknown-none` | * |  | Bare MIPS (LE) softfloat
`mipsel-sony-psp` | * |  | MIPS (LE) Sony PlayStation Portable (PSP)
`mipsisa32r6-unknown-linux-gnu` | ? |  |
`mipsisa32r6el-unknown-linux-gnu` | ? |  |
`mipsisa64r6-unknown-linux-gnuabi64` | ? |  |
`mipsisa64r6el-unknown-linux-gnuabi64` | ? |  |
`msp430-none-elf` | * |  | 16-bit MSP430 microcontrollers
`powerpc-unknown-linux-gnuspe` | ✓ |  | PowerPC SPE Linux
`powerpc-unknown-linux-musl` | ? |  |
`powerpc-unknown-netbsd` | ✓ | ✓ |
`powerpc-wrs-vxworks` | ? |  |
`powerpc-wrs-vxworks-spe` | ? |  |
`powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
`powerpc64-unknown-linux-musl` | ? |  |
`powerpc64-wrs-vxworks` | ? |  |
`powerpc64le-unknown-linux-musl` | ? |  |
`riscv32gc-unknown-linux-gnu` |  |  | RISC-V Linux (kernel 5.4, glibc 2.33)
`sparc-unknown-linux-gnu` | ✓ |  | 32-bit SPARC Linux
`sparc64-unknown-netbsd` | ✓ | ✓ | NetBSD/sparc64
`sparc64-unknown-openbsd` | ? |  |
`thumbv7a-pc-windows-msvc` | ? |  |
`thumbv7a-uwp-windows-msvc` | ✓ |  |
`thumbv7neon-unknown-linux-musleabihf` | ? |  | Thumb2-mode ARMv7a Linux with NEON, MUSL
`thumbv4t-none-eabi` | * |  | ARMv4T T32
`x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
`x86_64-apple-tvos` | * |  | x86 64-bit tvOS
`x86_64-linux-kernel` | * |  | Linux kernel modules
`x86_64-pc-solaris` | ? |  |
`x86_64-pc-windows-msvc` | ✓ |  | 64-bit Windows XP support
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
`x86_64-unknown-hermit` | ? |  |
`x86_64-unknown-hermit-kernel` | ? |  | HermitCore kernel
`x86_64-unknown-l4re-uclibc` | ? |  |
`x86_64-unknown-openbsd` | ✓ | ✓ | 64-bit OpenBSD
`x86_64-unknown-uefi` | ? |  |
`x86_64-uwp-windows-gnu` | ✓ |  |
`x86_64-uwp-windows-msvc` | ✓ |  |
`x86_64-wrs-vxworks` | ? |  |

# Targets

`rustc` is a cross-compiler by default. This means that you can use any compiler to build for any architecture. The list of targets are the possible architectures that you can build for.

To see all the options that you can set with a target, see the docs here.

To compile to a particular target, use the `--target` flag:

    $ rustc src/main.rs --target=wasm32-unknown-unknown

## Target Features

`x86`, and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`).

Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag.

Please note, that this flag is generally considered as unsafe. More details can be found in this section.

# Built-in Targets

`rustc` ships with the ability to compile to many targets automatically, we call these "built-in" targets, and they generally correspond to targets that the team is supporting directly. To see the list of built-in targets, you can run `rustc --print target-list`.

Typically, a target needs a compiled copy of the Rust standard library to work. If using rustup, then check out the documentation on Cross-compilation on how to download a pre-built standard library built by the official Rust distributions. Most targets will need a system linker, and possibly other things.

# Custom Targets

If you'd like to build for a target that is not yet supported by `rustc`, you can use a "custom target specification" to define a target. These target specification files are JSON. To see the JSON for the host target, you can run:

    $ rustc +nightly -Z unstable-options --print target-spec-json

To see it for a different target, add the `--target` flag:

    $ rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json

To use a custom target, see the (unstable) `build-std` feature of `cargo`.

# Known Issues

This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to contribute to this guide.

## Target Features

Most target-feature problems arise, when mixing code that have the target-feature enabled with code that have it disabled. If you want to avoid undefined behavior, it is recommended to build all code (including the standard library and imported crates) with a common set of target-features.

By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe.

Examples:

Target-Feature | Issue | Seen on | Description | Details
--- | --- | --- | --- | ---
`+soft-float` and `-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches. Attempting to compile with disabled SSE causes the same error, too. | #63466

# Profile Guided Optimization

`rustc` supports doing profile-guided optimization (PGO). This chapter describes what PGO is, what it is good for, and how it can be used.

## What Is Profiled-Guided Optimization?

The basic concept of PGO is to collect data about the typical execution of a program (e.g. which branches it is likely to take) and then use this data to inform optimizations such as inlining, machine-code layout, register allocation, etc.

There are different ways of collecting data about a program's execution. One is to run the program inside a profiler (such as `perf`) and another is to create an instrumented binary, that is, a binary that has data collection built into it, and run that. The latter usually provides more accurate data and it is also what is supported by `rustc`.

## Usage

Generating a PGO-optimized program involves following a workflow with four steps:

1. Compile the program with instrumentation enabled (e.g. `rustc -Cprofile-generate=/tmp/pgo-data main.rs`)
2. Run the instrumented program (e.g. `./main`) which generates a `default_<id>.profraw` file
3. Convert the `.profraw` file into a `.profdata` file using LLVM's `llvm-profdata` tool
4. Compile the program again, this time making use of the profiling data (for example `rustc -Cprofile-use=merged.profdata main.rs`)

An instrumented program will create one or more `.profraw` files, one for each instrumented binary. E.g. an instrumented executable that loads two instrumented dynamic libraries at runtime will generate three `.profraw` files. Running an instrumented binary multiple times, on the other hand, will re-use the respective `.profraw` files, updating them in place.

These `.profraw` files have to be post-processed before they can be fed back into the compiler. This is done by the `llvm-profdata` tool. This tool is most easily installed via

    rustup component add llvm-tools-preview

Note that installing the `llvm-tools-preview` component won't add `llvm-profdata` to the `PATH`. Rather, the tool can be found in:

    ~/.rustup/toolchains/<toolchain>/lib/rustlib/<target-triple>/bin/

Alternatively, an `llvm-profdata` coming with a recent LLVM or Clang version usually works too.

The `llvm-profdata` tool merges multiple `.profraw` files into a single `.profdata` file that can then be fed back into the compiler via `-Cprofile-use`:

    # STEP 1: Compile the binary with instrumentation
    rustc -Cprofile-generate=/tmp/pgo-data -O ./main.rs

    # STEP 2: Run the binary a few times, maybe with common sets of args.
    #         Each run will create or update `.profraw` files in /tmp/pgo-data
    ./main mydata1.csv
    ./main mydata2.csv
    ./main mydata3.csv

    # STEP 3: Merge and post-process all the `.profraw` files in /tmp/pgo-data
    llvm-profdata merge -o ./merged.profdata /tmp/pgo-data

    # STEP 4: Use the merged `.profdata` file during optimization. All `rustc`
    #         flags have to be the same.
    rustc -Cprofile-use=./merged.profdata -O ./main.rs

### A Complete Cargo Workflow

Using this feature with Cargo works very similar to using it with `rustc` directly. Again, we generate an instrumented binary, run it to produce data, merge the data, and feed it back into the compiler. Some things of note:

- We use the `RUSTFLAGS` environment variable in order to pass the PGO compiler flags to the compilation of all crates in the program.

- We pass the `--target` flag to Cargo, which prevents the `RUSTFLAGS` arguments to be passed to Cargo build scripts. We don't want the build scripts to generate a bunch of `.profraw` files.

- We pass `--release` to Cargo because that's where PGO makes the most sense. In theory, PGO can also be done on debug builds but there is little reason to do so.

- It is recommended to use absolute paths for the argument of `-Cprofile-generate` and `-Cprofile-use`. Cargo can invoke `rustc` with varying working directories, meaning that `rustc` will not be able to find the supplied `.profdata` file. With absolute paths this is not an issue.

- It is good practice to make sure that there is no left-over profiling data from previous compilation sessions. Just deleting the directory is a simple way of doing so (see `STEP 0` below).

This is what the entire workflow looks like:

    # STEP 0: Make sure there is no left-over profiling data from previous runs
    rm -rf /tmp/pgo-data

    # STEP 1: Build the instrumented binaries
    RUSTFLAGS="-Cprofile-generate=/tmp/pgo-data" \
        cargo build --release --target=x86_64-unknown-linux-gnu

    # STEP 2: Run the instrumented binaries with some typical data
    ./target/x86_64-unknown-linux-gnu/release/myprogram mydata1.csv
    ./target/x86_64-unknown-linux-gnu/release/myprogram mydata2.csv
    ./target/x86_64-unknown-linux-gnu/release/myprogram mydata3.csv

    # STEP 3: Merge the `.profraw` files into a `.profdata` file
    llvm-profdata merge -o /tmp/pgo-data/merged.profdata /tmp/pgo-data

    # STEP 4: Use the `.profdata` file for guiding optimizations
    RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" \
        cargo build --release --target=x86_64-unknown-linux-gnu

### Troubleshooting

- It is recommended to pass `-Cllvm-args=-pgo-warn-missing-function` during the `-Cprofile-use` phase. LLVM by default does not warn if it cannot find profiling data for a given function. Enabling this warning will make it easier to spot errors in your setup.

- There is a known issue in Cargo prior to version 1.39 that will prevent PGO from working correctly. Be sure to use Cargo 1.39 or newer when doing PGO.

## Further Reading

`rustc`'s PGO support relies entirely on LLVM's implementation of the feature and is equivalent to what Clang offers via the `-fprofile-generate` / `-fprofile-use` flags. The Profile Guided Optimization section in Clang's documentation is therefore an interesting read for anyone who wants to use PGO with Rust.

# Linker-plugin-LTO

The `-C linker-plugin-lto` flag allows for deferring the LTO optimization to the actual linking step, which in turn allows for performing interprocedural optimizations across programming language boundaries if all the object files being linked were created by LLVM based toolchains. The prime example here would be linking Rust code together with Clang-compiled C/C++ code.

## Usage

There are two main cases how linker plugin based LTO can be used:

- compiling a Rust `staticlib` that is used as a C ABI dependency
- compiling a Rust binary where `rustc` invokes the linker

In both cases the Rust code has to be compiled with `-C linker-plugin-lto` and the C/C++ code with `-flto` or `-flto=thin` so that object files are emitted as LLVM bitcode.

### Rust `staticlib` as dependency in C/C++ program

In this case the Rust compiler just has to make sure that the object files in the `staticlib` are in the right format. For linking, a linker with the LLVM plugin must be used (e.g. LLD).

Using `rustc` directly:

    # Compile the Rust staticlib
    rustc --crate-type=staticlib -Clinker-plugin-lto -Copt-level=2 ./lib.rs
    # Compile the C code with `-flto=thin`
    clang -c -O2 -flto=thin -o main.o ./main.c
    # Link everything, making sure that we use an appropriate linker
    clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o

Using `cargo`:

    # Compile the Rust staticlib
    RUSTFLAGS="-Clinker-plugin-lto" cargo build --release
    # Compile the C code with `-flto=thin`
    clang -c -O2 -flto=thin -o main.o ./main.c
    # Link everything, making sure that we use an appropriate linker
    clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o

### C/C++ code as a dependency in Rust

In this case the linker will be invoked by `rustc`. We again have to make sure that an appropriate linker is used.

Using `rustc` directly:

    # Compile C code with `-flto`
    clang ./clib.c -flto=thin -c -o ./clib.o -O2
    # Create a static library from the C code
    ar crus ./libxyz.a ./clib.o

    # Invoke `rustc` with the additional arguments
    rustc -Clinker-plugin-lto -L. -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs

Using `cargo` directly:

    # Compile C code with `-flto`
    clang ./clib.c -flto=thin -c -o ./clib.o -O2
    # Create a static library from the C code
    ar crus ./libxyz.a ./clib.o

    # Set the linking arguments via RUSTFLAGS
    RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build --release

### Explicitly specifying the linker plugin to be used by `rustc`

If one wants to use a linker other than LLD, the LLVM linker plugin has to be specified explicitly. Otherwise the linker cannot read the object files. The path to the plugin is passed as an argument to the `-Clinker-plugin-lto` option:

    rustc -Clinker-plugin-lto="/path/to/LLVMgold.so" -L. -Copt-level=2 ./main.rs

## Toolchain Compatibility

In order for this kind of LTO to work, the LLVM linker plugin must be able to handle the LLVM bitcode produced by both `rustc` and `clang`.

Best results are achieved by using a `rustc` and `clang` that are based on the exact same version of LLVM. One can use `rustc -vV` in order to view the LLVM used by a given `rustc` version. Note that the version number given here is only an approximation as Rust sometimes uses unstable revisions of LLVM. However, the approximation is usually reliable.

The following table shows known good combinations of toolchain versions.

Rust Version | Clang Version
--- | ---
Rust 1.34 | Clang 8
Rust 1.35 | Clang 8
Rust 1.36 | Clang 8
Rust 1.37 | Clang 8
Rust 1.38 | Clang 9
Rust 1.39 | Clang 9
Rust 1.40 | Clang 9
Rust 1.41 | Clang 9
Rust 1.42 | Clang 9
Rust 1.43 | Clang 9
Rust 1.44 | Clang 9
Rust 1.45 | Clang 10
Rust 1.46 | Clang 10

Note that the compatibility policy for this feature might change in the future.

# Exploit Mitigations

This chapter documents the exploit mitigations supported by the Rust compiler, and is by no means an extensive survey of the Rust programming language’s security features.

This chapter is for software engineers working with the Rust programming language, and assumes prior knowledge of the Rust programming language and its toolchain.

## Introduction

The Rust programming language provides memory[1] and thread[2] safety guarantees via its ownership[3], references and borrowing[4], and slice types[5] features. However, Unsafe Rust[6] introduces unsafe blocks, unsafe functions and methods, unsafe traits, and new types that are not subject to the borrowing rules.

Parts of the Rust standard library are implemented as safe abstractions over unsafe code (and historically have been vulnerable to memory corruption[7]). Furthermore, the Rust code and documentation encourage creating safe abstractions over unsafe code. This can cause a false sense of security if unsafe code is not properly reviewed and tested.

Unsafe Rust introduces features that do not provide the same memory and thread safety guarantees. This causes programs or libraries to be susceptible to memory corruption (CWE-119)[8] and concurrency issues (CWE-557)[9]. Modern C and C++ compilers provide exploit mitigations to increase the difficulty to exploit vulnerabilities resulting from these issues. Therefore, the Rust compiler must also support these exploit mitigations in order to mitigate vulnerabilities resulting from the use of Unsafe Rust. This chapter documents these exploit mitigations and how they apply to Rust.

This chapter does not discuss the effectiveness of these exploit mitigations as they vary greatly depending on several factors besides their design and implementation, but rather describe what they do, so their effectiveness can be understood within a given context.

## Exploit mitigations

This section documents the exploit mitigations applicable to the Rust compiler when building programs for the Linux operating system on the AMD64 architecture and equivalent.1

The Rust Programming Language currently has no specification. The Rust compiler (i.e., rustc) is the language reference implementation. All references to “the Rust compiler” in this chapter refer to the language reference implementation.

Table I
Summary of exploit mitigations supported by the Rust compiler when building programs for the Linux operating system on the AMD64 architecture and equivalent.

Exploit mitigation | Supported and enabled by default | Since
Position-independent executable | Yes | 0.12.0 (2014-10-09)
Integer overflow checks | Yes (enabled when debug assertions are enabled, and disabled when debug assertions are disabled) | 1.1.0 (2015-06-25)
Non-executable memory regions | Yes | 1.8.0 (2016-04-14)
Stack clashing protection | Yes | 1.20.0 (2017-08-31)
Read-only relocations and immediate binding | Yes | 1.21.0 (2017-10-12)
Heap corruption protection | Yes | 1.32.0 (2019-01-17) (via operating system default or specified allocator)
Stack smashing protection | No |
Forward-edge control flow protection | No |
Backward-edge control flow protection (e.g., shadow and safe stack) | No |

1. See https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec for a list of targets and their default options. ↩

### Position-independent executable

Position-independent executable increases the difficulty of the use of code reuse exploitation techniques, such as return-oriented programming (ROP) and variants, by generating position-independent code for the executable, and instructing the dynamic linker to load it similarly to a shared object at a random load address, thus also benefiting from address-space layout randomization (ASLR). This is also referred to as “full ASLR”.

The Rust compiler supports position-independent executable, and enables it by default since version 0.12.0 (2014-10-09)[10]–[13].

    $ readelf -h target/release/hello-rust | grep Type:
      Type:                              DYN (Shared object file)

Fig. 1. Checking if an executable is a position-independent executable.

An executable with an object type of `ET_DYN` (i.e., shared object) and not `ET_EXEC` (i.e., executable) is a position-independent executable (see Fig. 1).

### Integer overflow checks

Integer overflow checks protects programs from undefined and unintended behavior (which may cause vulnerabilities) by checking for results of signed and unsigned integer computations that cannot be represented in their type, resulting in an overflow or wraparound.

The Rust compiler supports integer overflow checks, and enables it when debug assertions are enabled since version 1.1.0 (2015-06-25)[14]–[20].

    fn main() {
        let u: u8 = 255;
        println!("u: {}", u + 1);
    }

Fig. 2. hello-rust-integer program.

    $ cargo run
       Compiling hello-rust-integer v0.1.0 (/home/rcvalle/hello-rust-integer)
        Finished dev [unoptimized + debuginfo] target(s) in 0.23s
         Running `target/debug/hello-rust-integer`
    thread 'main' panicked at 'attempt to add with overflow', src/main.rs:3:23
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

Fig. 3. Build and execution of hello-rust-integer with debug assertions enabled.

    $ cargo run --release
       Compiling hello-rust-integer v0.1.0 (/home/rcvalle/hello-rust-integer)
        Finished release [optimized] target(s) in 0.23s
         Running `target/release/hello-rust-integer`
    u: 0

Fig. 4. Build and execution of hello-rust-integer with debug assertions disabled.

Integer overflow checks are enabled when debug assertions are enabled (see Fig. 3), and disabled when debug assertions are disabled (see Fig. 4). To enable integer overflow checks independently, use the option to control integer overflow checks, scoped attributes, or explicit checking methods such as `checked_add`2.

It is recommended that explicit wrapping methods such as `wrapping_add` be used when wrapping semantics are intended, and that explicit checking and wrapping methods always be used when using Unsafe Rust.

2. See https://doc.rust-lang.org/std/primitive.u32.html for more information on the checked, overflowing, saturating, and wrapping methods (using u32 as an example). ↩

### Non-executable memory regions

Non-executable memory regions increase the difficulty of exploitation by limiting the memory regions that can be used to execute arbitrary code. Most modern processors provide support for the operating system to mark memory regions as non executable, but it was previously emulated by software, such as in grsecurity/PaX's PAGEEXEC and SEGMEXEC, on processors that did not provide support for it. This is also known as “No Execute (NX) Bit”, “Execute Disable (XD) Bit”, “Execute Never (XN) Bit”, and others.

The Rust compiler supports non-executable memory regions, and enables it by default since its initial release, version 0.1 (2012-01-20)[21], [22], but has regressed since then[23]–[25], and enforced by default since version 1.8.0 (2016-04-14)[25].

    $ readelf -l target/release/hello-rust | grep -A 1 GNU_STACK
      GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000  RW     0x10

Fig. 5. Checking if non-executable memory regions are enabled for a given binary.

The presence of an element of type `PT_GNU_STACK` in the program header table with the `PF_X` (i.e., executable) flag unset indicates non-executable memory regions3 are enabled for a given binary (see Fig. 5). Conversely, the presence of an element of type `PT_GNU_STACK` in the program header table with the `PF_X` flag set or the absence of an element of type `PT_GNU_STACK` in the program header table indicates non-executable memory regions are not enabled for a given binary.

3. See the Appendix section for more information on why it affects other memory regions besides the stack. ↩

### Stack clashing protection

Stack clashing protection protects the stack from overlapping with another memory region—allowing arbitrary data in both to be overwritten using each other—by reading from the stack pages as the stack grows to cause a page fault when attempting to read from the guard page/region. This is also referred to as “stack probes” or “stack probing”.

The Rust compiler supports stack clashing protection via stack probing, and enables it by default since version 1.20.0 (2017-08-31)[26]–[29].

Fig. 6. IDA Pro listing cross references to `__rust_probestack` in hello-rust.

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

    fn main() {
        let _: [u64; 1024] = [0; 1024];
        hello();
    }

Fig 7. Modified hello-rust.

Fig. 8. IDA Pro listing cross references to `__rust_probestack` in modified hello-rust.

To check if stack clashing protection is enabled for a given binary, search for cross references to `__rust_probestack`. The `__rust_probestack` is called in the prologue of functions whose stack size is larger than a page size (see Fig. 6), and can be forced for illustration purposes by modifying the hello-rust example as seen in Fig. 7 and Fig. 8.

### Read-only relocations and immediate binding

Read-only relocations protect segments containing relocations and relocation information (i.e., `.init_array`, `.fini_array`, `.dynamic`, and `.got`) from being overwritten by marking these segments read only. This is also referred to as “partial RELRO”.

The Rust compiler supports read-only relocations, and enables it by default since version 1.21.0 (2017-10-12)[30], [31].

    $ readelf -l target/release/hello-rust | grep GNU_RELRO
      GNU_RELRO      0x000000000002ee00 0x000000000002fe00 0x000000000002fe00

Fig. 9. Checking if read-only relocations is enabled for a given binary.

The presence of an element of type `PT_GNU_RELRO` in the program header table indicates read-only relocations are enabled for a given binary (see Fig. 9). Conversely, the absence of an element of type `PT_GNU_RELRO` in the program header table indicates read-only relocations are not enabled for a given binary.

Immediate binding protects additional segments containing relocations (i.e., `.got.plt`) from being overwritten by instructing the dynamic linker to perform all relocations before transferring control to the program during startup, so all segments containing relocations can be marked read only (when combined with read-only relocations). This is also referred to as “full RELRO”.

The Rust compiler supports immediate binding, and enables it by default since version 1.21.0 (2017-10-12)[30], [31].

    $ readelf -d target/release/hello-rust | grep BIND_NOW
     0x000000000000001e (FLAGS)              BIND_NOW

Fig. 10. Checking if immediate binding is enabled for a given binary.

The presence of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` flag4 in the dynamic section indicates immediate binding is enabled for a given binary (see Fig. 10). Conversely, the absence of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` flag in the dynamic section indicates immediate binding is not enabled for a given binary.

The presence of both an element of type `PT_GNU_RELRO` in the program header table and of an element with the `DT_BIND_NOW` tag and the `DF_BIND_NOW` flag in the dynamic section indicates full RELRO is enabled for a given binary (see Fig. 9 and Fig. 10).

4. And the `DF_1_NOW` flag for some link editors. ↩

### Heap corruption protection

Heap corruption protection protects memory allocated dynamically by performing several checks, such as checks for corrupted links between list elements, invalid pointers, invalid sizes, double/multiple “frees” of the same memory allocated, and many corner cases of these. These checks are implementation specific, and vary per allocator.

ARM Memory Tagging Extension (MTE), when available, will provide hardware assistance for a probabilistic mitigation to detect memory safety violations by tagging memory allocations, and automatically checking that the correct tag is used on every memory access.

Rust’s default allocator has historically been jemalloc, and it has long been the cause of issues and the subject of much discussion[32]–[38]. Consequently, it has been removed as the default allocator in favor of the operating system’s standard C library default allocator5 since version 1.32.0 (2019-01-17)[39].

    fn main() {
        let mut x = Box::new([0; 1024]);

        for i in 0..1026 {
            unsafe {
                let elem = x.get_unchecked_mut(i);
                *elem = 0x4141414141414141u64;
            }
        }
    }

Fig. 11. hello-rust-heap program.

    $ cargo run
       Compiling hello-rust-heap v0.1.0 (/home/rcvalle/hello-rust-heap)
        Finished dev [unoptimized + debuginfo] target(s) in 0.25s
         Running `target/debug/hello-rust-heap`
    free(): invalid next size (normal)
    Aborted

Fig. 12. Build and execution of hello-rust-heap with debug assertions enabled.

    $ cargo run --release
       Compiling hello-rust-heap v0.1.0 (/home/rcvalle/hello-rust-heap)
        Finished release [optimized] target(s) in 0.25s
         Running `target/release/hello-rust-heap`
    free(): invalid next size (normal)
    Aborted

Fig. 13. Build and execution of hello-rust-heap with debug assertions disabled.

Heap corruption checks are being performed when using the default allocator (i.e., the GNU Allocator) as seen in Fig. 12 and Fig. 13.

5. Linux's standard C library default allocator is the GNU Allocator, which is derived from ptmalloc (pthreads malloc) by Wolfram Gloger, which in turn is derived from dlmalloc (Doug Lea malloc) by Doug Lea. ↩

### Stack smashing protection

Stack smashing protection protects programs from stack-based buffer overflows by inserting a random guard value between local variables and the saved return instruction pointer, and checking if this value has changed when returning from a function. This is also known as “Stack Protector” or “Stack Smashing Protector (SSP)”.

The Rust compiler does not support stack smashing protection. However, more comprehensive alternatives to stack smashing protection exist, such as shadow and safe stack (see backward-edge control flow protection).

Fig. 14. IDA Pro listing cross references to `__stack_chk_fail` in hello-rust.

To check if stack smashing protection is enabled for a given binary, search for cross references to `__stack_chk_fail`. The only cross references to `__stack_chk_fail` in hello-rust are from the statically-linked libbacktrace library (see Fig. 14).

### Forward-edge control flow protection

Forward-edge control flow protection protects programs from having its control flow changed/hijacked by performing checks to ensure that destinations of indirect branches are one of their valid destinations in the control flow graph. The comprehensiveness of these checks vary per implementation. This is also known as “forward-edge control flow integrity (CFI)”.

Newer processors provide hardware assistance for forward-edge control flow protection, such as ARM Branch Target Identification (BTI), ARM Pointer Authentication, and Intel Indirect Branch Tracking (IBT) as part of Intel Control-flow Enforcement Technology (CET). However, ARM BTI and Intel IBT -based implementations are less comprehensive than software-based implementations such as LLVM ControlFlowIntegrity (CFI), and the commercially available grsecurity/PaX Reuse Attack Protector (RAP).

The Rust compiler does not support forward-edge control flow protection on Linux6. There is work currently ongoing to add support for the sanitizers[40], which may or may not include support for LLVM CFI.

    $ readelf -s target/release/hello-rust | grep __cfi_init

Fig. 15. Checking if LLVM CFI is enabled for a given binary.

The presence of the `__cfi_init` symbol (and references to `__cfi_check`) indicates that LLVM CFI (i.e., forward-edge control flow protection) is enabled for a given binary. Conversely, the absence of the `__cfi_init` symbol (and references to `__cfi_check`) indicates that LLVM CFI is not enabled for a given binary (see Fig. 15).

6. It supports Control Flow Guard (CFG) on Windows (see https://github.com/rust-lang/rust/issues/68793). ↩

### Backward-edge control flow protection

Shadow stack protects saved return instruction pointers from being overwritten by storing a copy of them on a separate (shadow) stack, and using these copies as authoritative values when returning from functions. This is also known as “ShadowCallStack” and “Return Flow Guard”, and is considered an implementation of backward-edge control flow protection (or “backward-edge CFI”).

Safe stack protects not only the saved return instruction pointers, but also register spills and some local variables from being overwritten by storing unsafe variables, such as large arrays, on a separate (unsafe) stack, and using these unsafe variables on the separate stack instead. This is also known as “SafeStack”, and is also considered an implementation of backward-edge control flow protection.

Both shadow and safe stack are intended to be a more comprehensive alternatives to stack smashing protection as they protect the saved return instruction pointers (and other data in the case of safe stack) from arbitrary writes and non-linear out-of-bounds writes.

Newer processors provide hardware assistance for backward-edge control flow protection, such as ARM Pointer Authentication, and Intel Shadow Stack as part of Intel CET.

The Rust compiler does not support shadow or safe stack. There is work currently ongoing to add support for the sanitizers[40], which may or may not include support for safe stack7.

    $ readelf -s target/release/hello-rust | grep __safestack_init

Fig. 16. Checking if LLVM SafeStack is enabled for a given binary.

The presence of the `__safestack_init` symbol indicates that LLVM SafeStack is enabled for a given binary. Conversely, the absence of the `__safestack_init` symbol indicates that LLVM SafeStack is not enabled for a given binary (see Fig. 16).

7. The shadow stack implementation for the AMD64 architecture and equivalent in LLVM was removed due to performance and security issues. ↩

## Appendix

As of the latest version of the Linux Standard Base (LSB) Core Specification, the `PT_GNU_STACK` program header indicates whether the stack should be executable, and the absence of this header indicates that the stack should be executable. However, the Linux kernel currently sets the `READ_IMPLIES_EXEC` personality upon loading any executable with the `PT_GNU_STACK` program header and the `PF_X` flag set or with the absence of this header, resulting in not only the stack, but also all readable virtual memory mappings being executable.

An attempt to fix this was made in 2012, and another was made in 2020. The former never landed, and the latter partially fixed it, but introduced other issues—the absence of the `PT_GNU_STACK` program header still causes not only the stack, but also all readable virtual memory mappings to be executable in some architectures, such as IA-32 and equivalent (or causes the stack to be non-executable in some architectures, such as AMD64 and equivalent, contradicting the LSB).

The `READ_IMPLIES_EXEC` personality needs to be completely separated from the `PT_GNU_STACK` program header by having a separate option for it (or setarch -X could just be used whenever `READ_IMPLIES_EXEC` is needed), and the absence of the `PT_GNU_STACK` program header needs to have more secure defaults (unrelated to `READ_IMPLIES_EXEC`).

## References

1. D. Hosfelt. “Fearless security: memory safety.” Mozilla Hacks. https://hacks.mozilla.org/2019/01/fearless-security-memory-safety/.

2. D. Hosfelt. “Fearless security: thread safety.” Mozilla Hacks. https://hacks.mozilla.org/2019/02/fearless-security-thread-safety/.

3. S. Klabnik and C. Nichols. “What Is Ownership?.” The Rust Programming Language. https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html.

4. S. Klabnik and C. Nichols. “References and Borrowing.” The Rust Programming Language. https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html.

5. S. Klabnik and C. Nichols. “The Slice Type.” The Rust Programming Language. https://doc.rust-lang.org/book/ch04-03-slices.html.

6. S. Klabnik and C. Nichols. “Unsafe Rust.” The Rust Programming Language. https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html.

7. S. Davidoff. “How Rust’s standard library was vulnerable for years and nobody noticed.” Medium. https://medium.com/@shnatsel/how-rusts-standard-library-was-vulnerable-for-years-and-nobody-noticed-aebf0503c3d6.

8. “Improper restriction of operations within the bounds of a memory buffer (CWE-119).” MITRE CWE List. https://cwe.mitre.org/data/definitions/119.html.

9. “Concurrency issues (CWE-557).” MITRE CWE List. https://cwe.mitre.org/data/definitions/557.html.

10. K. McAllister. “Memory exploit mitigations #15179.” GitHub. https://github.com/rust-lang/rust/issues/15179.

11. K. McAllister. “RFC: Memory exploit mitigation #145.” GitHub. https://github.com/rust-lang/rfcs/pull/145.

12. K. McAllister. “RFC: Memory exploit mitigation.” GitHub. https://github.com/kmcallister/rfcs/blob/hardening/active/0000-memory-exploit-mitigation.md.

13. D. Micay. “Enable PIE by default on Linux for full ASLR #16340.” GitHub. https://github.com/rust-lang/rust/pull/16340.

14. N. Matsakis. “Integer overflow #560.” GitHub. https://github.com/rust-lang/rfcs/pull/560.

15. G. Lehel and N. Matsakis. “Integer overflow.” GitHub. https://rust-lang.github.io/rfcs/0560-integer-overflow.html.

16. A. Turon. “Tracking issue for integer overflow (RFC 560) #22020.” GitHub. https://github.com/rust-lang/rust/issues/22020.

17. H. Wilson. “Myths and legends about integer overflow in Rust.” Huon on the Internet. http://huonw.github.io/blog/2016/04/myths-and-legends-about-integer-overflow-in-rust/.

18. B. Anderson. “Stabilize -C overflow-checks #1535.” GitHub. https://github.com/rust-lang/rfcs/pull/1535.

19. B. Anderson. “Stable overflow checks.” GitHub. https://github.com/brson/rfcs/blob/overflow/text/0000-stable-overflow-checks.md.

20. N. Froyd. “Add -C overflow-checks option #40037.” GitHub. https://github.com/rust-lang/rust/pull/40037.

21. R. Á. de Espíndola. “rustc requires executable stack #798.” GitHub. https://github.com/rust-lang/rust/issues/798.

22. A. Seipp. “Make sure librustrt.so is linked with a non-executable stack. #1066.” GitHub. https://github.com/rust-lang/rust/pull/1066.

23. D. Micay. “Rust binaries should not have an executable stack #5643.” GitHub. https://github.com/rust-lang/rust/issues/5643.

24. D. Micay. “Mark the assembly object stacks as non-executable #5647.” GitHub. https://github.com/rust-lang/rust/pull/5647.

25. A. Clark. “Explicitly disable stack execution on linux and bsd #30859.” GitHub. https://github.com/rust-lang/rust/pull/30859.

26. “Replace stack overflow checking with stack probes #16012.” GitHub. https://github.com/rust-lang/rust/issues/16012.

27. B. Striegel. “Extend stack probe support to non-tier-1 platforms, and clarify policy for mitigating LLVM-dependent unsafety #43241.” GitHub. https://github.com/rust-lang/rust/issues/43241.

28. A. Crichton. “rustc: Implement stack probes for x86 #42816.” GitHub. https://github.com/rust-lang/rust/pull/42816.

29. A. Crichton. “Add __rust_probestack intrinsic #175.” GitHub. https://github.com/rust-lang/compiler-builtins/pull/175.

30. B. Anderson. “Consider applying -Wl,-z,relro or -Wl,-z,relro,-z,now by default #29877.” GitHub. https://github.com/rust-lang/rust/issues/29877.

31. J. Löthberg. “Add support for full RELRO #43170.” GitHub. https://github.com/rust-lang/rust/pull/43170.

32. N. Matsakis. “Allocators in Rust.” Baby Steps. http://smallcultfollowing.com/babysteps/blog/2014/11/14/allocators-in-rust/.

33. A. Crichton. “RFC: Allow changing the default allocator #1183.” GitHub. https://github.com/rust-lang/rfcs/pull/1183.

34. A. Crichton. “RFC: Swap out jemalloc.” GitHub. https://rust-lang.github.io/rfcs/1183-swap-out-jemalloc.html.

35. A. Crichton. “Tracking issue for changing the global, default allocator (RFC 1974) #27389.” GitHub. https://github.com/rust-lang/rust/issues/27389.

36. S. Fackler. “Prepare global allocators for stabilization #1974.” GitHub. https://github.com/rust-lang/rfcs/pull/1974.

37. A. Crichton. “RFC: Global allocators.” GitHub. https://rust-lang.github.io/rfcs/1974-global-allocators.html.

38. B. Anderson. “Switch the default global allocator to System, remove alloc_jemalloc, use jemallocator in rustc #36963.” GitHub. https://github.com/rust-lang/rust/issues/36963.

39. A. Crichton. “Remove the alloc_jemalloc crate #55238.” GitHub. https://github.com/rust-lang/rust/pull/55238.

40. J. Aparicio. 2017. “Tracking issue for sanitizer support #39699.” https://github.com/rust-lang/rust/issues/39699.

# Contributing to rustc

We'd love to have your help improving `rustc`! To that end, we've written a whole book on its internals, how it works, and how to get started working on it. To learn more, you'll want to check that out.

If you would like to contribute to this book, you can find its source in the rustc source at src/doc/rustc.