默认等级为拒绝的 lints

默认情况下,这些 lint 都设置为 'deny' 级别。

ambiguous_associated_items

ambiguous_associated_items lint 检测枚举变量和关联项之间的不确定项。

样例

#![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 }
}
}

显示如下:

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;
   |     ^^^^^^^
   

解释

早期 Rust 版本不允许通过类型别名访问枚举变量,当添加此功能时(请参阅 RFC 2338),这引入了某些情况,即类型所指的可能不明确。

要解决该歧义,应使用路径限定明确声明要使用的类型。例如,以上示例中函数可以被写作fn f() -> <Self as Tr>::V { 0 } 以明确引用关联的类型。

这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #57644

arithmetic_overflow

arithmetic_overflow lint 检测会溢出的算术运算

样例

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

显示如下:

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

解释

执行值溢出运算很可能是错误,如果编译器能够在编译时检测到这些溢出,就会触发这个 lint。请考虑调整表达式避免溢出,或者使用不会溢出的数据类型。

conflicting_repr_hints

conflicting_repr_hints lint 检测带有冲突提示的 repr 属性。

样例


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

显示如下:

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>

解释

过去编译器错误的接受了这些冲突的表示形式。这是个将来不兼容 的 lint ,将来会转化为固有错误。了解更多细节请参阅 issue #68585

想要更正该问题,请移除冲突的提示之一。

const_err

const_err lint 检测常量求值时的错误表达式。

样例

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

显示如下:

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

解释

该 lint 检测很可能错误的代码,如果将该 lint 等级变为允许,那么代码将不会在编译时进行计算,而是继续生成代码,在运行时计算,这可能会在运行时 panic 。 注意,该 lint 可以在 const 上下文内部或外部触发。在 const 上下文外部,编译器有时会在编译时对表达式求值以生成更高效的代码。如果编译器要在这方面做得更好,它需要决定当遇到肯定会panic 或是不正确的代码时应该怎么做。将此设置为固有错误(hard error)将阻止表现出此行为的现有代码编译,破坏向后兼容性。然而,这肯定是不正确的代码,因此这是一个默认等级为拒绝的 lint。更多细节请参阅 RFC 1229issue #28238。 注意还有几个其他更特定的编译时计算相关的 lint,例如:arithmetic_overflowunconditional_panic

ill_formed_attribute_input

ill_formed_attribute_input lint 检测以前被接收并且用于实践中的不良格式的属性输入。

样例

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

这会显示:

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>

解释

以前,许多内置属性的输入没有经过验证,无意义的属性输入被接收。在添加了验证之后,明确了一些现有的项目使用了这些无效的格式。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #57571 。 有关有效输入的属性,更多细节请参阅 attribute reference

incomplete_include

incomplete_include lint 检测一个文件包含多于一个表达式的 include! 宏。

样例

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

foo.txt文件包含以下内容:

println!("hi!");

显示如下:

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

解释

include! 宏当前仅打算用于单个表达式或多个。从以前看,它会忽略第一个表达式之后的任何内容,但这可能会令人困惑。在上例中,println! 表达式( println! expression )刚好在分号之前结束,从而使分号成为多余的信息而被忽略,更令人惊讶的是,如果包含的文件有多个打印语句,后续的语句将被忽略! 一个解决办法是将内容放在大括号中创建块表达式。还可以考虑其他办法,例如函数封装表达式或者使用过程宏。 这是个 lint 而不是固有错误是因为现有项目已经发现并报过错。谨慎起见,它现在还是个 lint 。include! 宏的未来语义还不确定,请参阅 issue #35560

invalid_type_param_default

invalid_type_param_default lint 检测在无效位置中错误地允许 (allowed) 使用类型参数默认值。

样例

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

显示如下:

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>

解释

默认类型参数仅在某些情况下才允许使用,但是以前编译器在任何地方都允许使用。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #36887

macro_expanded_macro_exports_accessed_by_absolute_paths

macro_expanded_macro_exports_accessed_by_absolute_paths lint 检测当前 crate 中不能被绝对路径引用的 macro_export宏的宏展开。

样例

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

define_exported!();

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

显示如下:

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)

解释

我们的目的是所有使用 #[macro_export] 属性的宏在 crate 根是可用的。然而,当一个 macro_rules! 定义由另一个宏生成之时,宏展开是无法遵循该规则的。 这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #53495

missing_fragment_specifier

missing_fragment_specifier lint 当有一个未使用的模式在未跟有片段说明符 (fragment specifier) (例如::expr)的元变量(例如:$e)的 macro_rules! 宏定义中时被触发。

始终可以通过移除 macro_rules! 宏定义中未使用的模式来解决此警告。

样例

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

fn main() {
   foo!();
}

显示如下:

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>

解释

要修复此问题,从 macro_rules! 定义中移除此未使用模式:

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

mutable_transmutes

mutable_transmutes lint 捕捉从 &T&mut T 这种未定义行为 的转换。

样例

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

显示如下:

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

解释

我们对数据别名做出了一些假设,而这种转换是违反这些假设的。考虑使用 UnsafeCell

no_mangle_const_items

no_mangle_const_items lint 检测 no_mangle属性的所有 const 项。

样例

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

显示如下:

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

解释

常量没有其导出符号,因此这可能意味着你得用 static 而不是 const

order_dependent_trait_objects

order_dependent_trait_objects lint 检测一种 trait 一致性冲突,该冲突即为同一个包含标记 trait (marker traits)的 dynamic trait object 创建两个 trait 实现。

样例

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

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

显示如下:

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>

解释

以前的一个 bug 导致编译器将不同顺序的 trait (例如 Send + SyncSync + Send)解释为不同的类型,然而它们应该被认为是相同的。这允许代码在出现一致性错误的时候定义单独的 trait 实现。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #56484

overflowing_literals

overflowing_literals lint 检测超出其所属类型范围的字面量。

样例

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

显示如下:

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`

解释

使用溢出其所用类型的字面量通常是错误。要么就使用在其类型范围内的字面量,要么就更改其类型以能容纳该字面量。

patterns_in_fns_without_body

patterns_in_fns_without_body lint 检测 mut 标识符模式用于没有函数体的函数的参数。

样例

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

显示如下:

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>

解释

要想修复此问题, trait 定义中从参数移除 mut ;也可以使用默认实现。也就是说,以下两种都行:

#![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 定义中可以定义没有函数体的函数以指定实现必须实现的函数体。无函数体的函数形参名仅允许是 _ 或为了文档目的的(仅类型相关)的标识符。以前的编译器版本错误地允许标识符模式使用 mut 关键字,但这是不被允许的。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #35203

pub_use_of_private_extern_crate

pub_use_of_private_extern_crate lint 检测私有 extern crate 重导出的具体情况。

样例

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

显示如下:

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>

解释

一个公开的 use 声明不应该用于 公开性地重导出私有 extern crate。应该使用 pub extern crate。 过去是允许该行为的,但是根据可见性规则这是不符合预期的。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #34537

soft_unstable

soft_unstable lint 检测 在 stable 上无意间允许(allowed)的 unstable feature。

样例

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

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

显示如下:

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>

解释

bench 属性意外地在 stable release channel 上被指定。将此转化为固有错误会破坏一些(现有)项目。当使用 --cap-lints 时该 lint 允许项目正确地构建,否则会发出一个错误提示。#[bench] 不应该被用在 stable channel。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #64266

unconditional_panic

unconditional_panic lint 检测将在运行时引起 panic 的操作。

样例

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

显示如下:

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

解释

该 lint 检测很可能不正确的代码。如果可能,编译器将尝试检测代码能够在编译时进行计算的情况,以生成更高效的代码。在计算这类代码时,如果检测到代码会无条件地 panic ,通常表示(要执行的计算)在做一些错误的事情。如果该 lint 等级被改为允许,然后此代码将不会在编译时被计算,而是继续生成代码在运行时计算,这也可能会在运行时 panic。

unknown_crate_types

unknown_crate_types lint 检测在 crate_type属性中找到的未知 crate 类型。

样例

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

显示如下:

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

解释

crate_type 属性赋未知值可以肯定说是一个错误。

useless_deprecated

useless_deprecated lint 检测无效且弃用的属性。

样例

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

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

显示如下:

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

解释

弃用属性对 trait 实现是无影响的。