Allowed-by-default lints - The rustc book

# 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.