默认拒绝的 Lint

这些 lint 默认设置为“拒绝”级别。

ambiguous-associated-items

ambiguous_associated_items lint 会检测关联项枚举变量之间的歧义。

示例

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`
   |
   = 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;
   |     ^^^^^^
   = note: `#[deny(ambiguous_associated_items)]` on by default

解释

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

要解决这种歧义,您应该使用限定路径来明确说明要使用的类型。例如,在上面的示例中,函数可以写成fn f() -> <Self as Tr>::V { 0 },以专门引用关联类型。

这是一个未来不兼容的 lint,将在未来转换为硬错误。有关更多详细信息,请参阅问题 #57644

arithmetic-overflow

arithmetic_overflow lint 检测到算术运算将溢出

示例

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。请考虑调整表达式以避免溢出,或使用不会溢出的数据类型。

bindings-with-variant-name

bindings_with_variant_name lint 检测到与匹配变量之一同名的模式绑定。

示例

pub enum Enum {
    Foo,
    Bar,
}

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

这将产生

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

解释

将枚举变量名称指定为标识符模式通常是错误的。在上面的示例中,match 分支指定了一个变量名来绑定 x 的值。第二个分支被忽略,因为第一个分支匹配*所有*值。可能的意图是该分支旨在匹配枚举变量。

两种可能的解决方案是

  • 使用路径模式指定枚举变量,例如 Enum::Foo
  • 将枚举变量引入本地作用域,例如在上面示例中 foo 函数的开头添加 use Enum::*;

cenum-impl-drop-cast

cenum_impl_drop_cast lint 检测到实现Drop的无字段 enumas 强制转换。

示例

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

这将产生

error: cannot cast enum `E` into integer `u32` because it implements `Drop`
  --> lint_example.rs:14:13
   |
14 |     let i = e as u32;
   |             ^^^^^^^^
   |
   = 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>
   = note: `#[deny(cenum_impl_drop_cast)]` on by default

解释

将未实现Copy的无字段 enum 强制转换为整数会移动该值而不调用 drop。如果预期应该调用 drop,这可能会导致意外行为。自动调用 drop 将与其他移动操作不一致。由于这两种行为都不明确或不一致,因此决定不再允许这种性质的强制转换。

这是一个未来不兼容的 lint,将在未来转换为硬错误。有关更多详细信息,请参阅问题 #73333

conflicting-repr-hints

conflicting_repr_hints 检查会检测具有冲突提示的 repr 属性

示例

#[repr(u32, u64)]
enum Foo {
    Variant1,
}

这将产生

error[E0566]: conflicting representation hints
 --> lint_example.rs:2:8
  |
2 | #[repr(u32, u64)]
  |        ^^^  ^^^
  |
  = 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>
  = note: `#[deny(conflicting_repr_hints)]` on by default

解释

编译器过去错误地接受了这些冲突的表示。这是一个 未来不兼容 的 lint,以便将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #68585

要解决此问题,请删除其中一个冲突的提示。

deprecated-cfg-attr-crate-type-name

deprecated_cfg_attr_crate_type_name 检查会检测在源代码中使用 #![cfg_attr(..., crate_type = "...")]#![cfg_attr(..., crate_name = "...")] 属性来有条件地指定 crate 类型和名称。

示例

#![cfg_attr(debug_assertions, crate_type = "lib")]

这将产生

error: `crate_type` within an `#![cfg_attr] attribute is deprecated`
 --> lint_example.rs:1:31
  |
1 | #![cfg_attr(debug_assertions, crate_type = "lib")]
  |                               ^^^^^^^^^^^^^^^^^^
  |
  = 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 #91632 <https://github.com/rust-lang/rust/issues/91632>
  = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` on by default

解释

#![crate_type]#![crate_name] 属性需要在编译器中进行 hack,以便能够在宏扩展后更改使用的 crate 类型和 crate 名称。这两个属性都不能与 Cargo 一起使用,因为它在命令行上显式传递了 --crate-type--crate-name。这些值必须与源代码中使用的值匹配,以防止出现错误。

要修复此警告,请在运行 rustc 时在命令行上使用 --crate-type 而不是 #![cfg_attr(..., crate_type = "...")],并使用 --crate-name 而不是 #![cfg_attr(..., crate_name = "...")]

enum-intrinsics-non-enums

enum_intrinsics_non-enums 检查会检测对需要枚举的内部函数的调用(core::mem::discriminantcore::mem::variant_count),但使用非枚举类型调用。

示例

#![deny(enum_intrinsics_non_enums)]
core::mem::discriminant::<i32>(&123);

这将产生

error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
 --> lint_example.rs:3:1
  |
3 | core::mem::discriminant::<i32>(&123);
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum.
 --> lint_example.rs:3:32
  |
3 | core::mem::discriminant::<i32>(&123);
  |                                ^^^^
note: the lint level is defined here
 --> lint_example.rs:1:9
  |
1 | #![deny(enum_intrinsics_non_enums)]
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^

解释

为了接受任何枚举,mem::discriminantmem::variant_count 函数对类型 T 是泛型的。这在技术上使 T 可能是非枚举,在这种情况下,返回值是未指定的。

此 lint 可防止此类函数的错误使用。

exceeding-bitshifts

lint exceeding-bitshifts 已重命名为 arithmetic-overflow

ill-formed-attribute-input

ill_formed_attribute_input 检查会检测以前接受并在实践中使用的格式错误的属性输入。

示例

#[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"]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = 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>
  = note: `#[deny(ill_formed_attribute_input)]` on by default

解释

以前,许多内置属性的输入都没有经过验证,并且接受了无意义的属性输入。添加验证后,确定一些现有项目使用了这些无效形式。这是一个 未来不兼容 的 lint,以便将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #57571

有关属性的有效输入的详细信息,请查看 属性参考

incomplete-include

incomplete_include 检查会检测到使用包含多个表达式的文件的 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! 表达式在分号之前结束,这使得分号成为被忽略的“额外”信息。也许更令人惊讶的是,如果包含的文件有多个打印语句,则后续语句将被忽略!

一种解决方法是将内容放在大括号中以创建 块表达式。还可以考虑其他方法,例如使用函数来封装表达式,或使用 proc-macros

这是一个 lint 而不是硬错误,因为发现现有项目遇到了此错误。为了谨慎起见,现在它是一个 lint。include! 宏的未来语义也不确定,请参阅 问题 #35560

ineffective-unstable-trait-impl

ineffective_unstable_trait_impl 检查会检测未使用的 #[unstable] 属性。

示例

#![feature(staged_api)]

#[derive(Clone)]
#[stable(feature = "x", since = "1")]
struct S {}

#[unstable(feature = "y", issue = "none")]
impl Copy for S {}

这将产生

error: an `#[unstable]` annotation here has no effect
 --> lint_example.rs:8:1
  |
8 | #[unstable(feature = "y", issue = "none")]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
  = note: `#[deny(ineffective_unstable_trait_impl)]` on by default

解释

staged_api 当前不支持在 impl 块上使用稳定性属性。如果类型和特征都是稳定的,则 impl 始终是稳定的,否则始终是不稳定的。

invalid-atomic-ordering

invalid_atomic_ordering 检查会检测到将不支持的 Ordering 传递给原子操作。

示例

use core::sync::atomic::{AtomicU8, Ordering};
let atom = AtomicU8::new(0);
let value = atom.load(Ordering::Release);
let _ = value;

这将产生

error: atomic loads cannot have `Release` or `AcqRel` ordering
 --> lint_example.rs:4:23
  |
4 | let value = atom.load(Ordering::Release);
  |                       ^^^^^^^^^^^^^^^^^
  |
  = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
  = note: `#[deny(invalid_atomic_ordering)]` on by default

解释

某些原子操作仅支持 atomic::Ordering 变体的子集。传递不受支持的变体将导致运行时无条件恐慌,此 lint 会检测到这种情况。

此 lint 将在以下情况下触发:(其中 AtomicTypecore::sync::atomic 中的原子类型,例如 AtomicBoolAtomicPtrAtomicUsize 或任何其他整数原子)。

  • Ordering::AcquireOrdering::AcqRel 传递给 AtomicType::store

  • Ordering::ReleaseOrdering::AcqRel 传递给 AtomicType::load

  • Ordering::Relaxed 传递给 core::sync::atomic::fencecore::sync::atomic::compiler_fence

  • Ordering::ReleaseOrdering::AcqRel 作为失败排序传递给 AtomicType::compare_exchangeAtomicType::compare_exchange_weakAtomicType::fetch_update 中的任何一个。

invalid-doc-attributes

invalid_doc_attributes 检查会检测 #[doc(...)] 的错误使用。

示例

#![deny(warnings)]

pub mod submodule {
    #![doc(test(no_crate_inject))]
}

这将产生

error: this attribute can only be applied at the crate level
 --> lint_example.rs:5:12
  |
5 |     #![doc(test(no_crate_inject))]
  |            ^^^^^^^^^^^^^^^^^^^^^
  |
  = note: read <https://doc.rust-lang.net.cn/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
  = note: `#[deny(invalid_doc_attributes)]` on by default

解释

以前,#[doc(..)] 属性的错误使用没有得到验证。通常,这些应该作为硬错误被拒绝,但是引入了此 lint 以避免破坏包含它们的任何现有 crate。

invalid-from-utf8-unchecked

invalid_from_utf8_unchecked 检查会检查使用已知的无效 UTF-8 值调用 std::str::from_utf8_uncheckedstd::str::from_utf8_unchecked_mut

示例

#[allow(unused)]
unsafe {
    std::str::from_utf8_unchecked(b"Ru\x82st");
}

这将产生

error: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior
 --> lint_example.rs:4:5
  |
4 |     std::str::from_utf8_unchecked(b"Ru\x82st");
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^
  |                                   |
  |                                   the literal was valid UTF-8 up to the 2 bytes
  |
  = note: `#[deny(invalid_from_utf8_unchecked)]` on by default

解释

根据 std::str::from_utf8_uncheckedstd::str::from_utf8_unchecked_mut 的文档,创建这样的 str 将导致未定义的行为。

invalid-reference-casting

invalid_reference_casting 检查会检查在不使用内部可变性的情况下将 &T 强制转换为 &mut T

示例

fn x(r: &i32) {
    unsafe {
        *(r as *const i32 as *mut i32) += 1;
    }
}

这将产生

error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
 --> lint_example.rs:4:9
  |
4 |         *(r as *const i32 as *mut i32) += 1;
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: for more information, visit <https://doc.rust-lang.net.cn/book/ch15-05-interior-mutability.html>
  = note: `#[deny(invalid_reference_casting)]` on by default

解释

在不使用内部可变性的情况下将 &T 强制转换为 &mut T 是未定义的行为,因为它违反了 Rust 引用别名规则。

UnsafeCell 是获取被视为可变的别名数据的唯一方法。

invalid-type-param-default

invalid_type_param_default 检查会检测到在无效位置错误允许的类型参数默认值。

示例

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) {}
  |        ^^^^^
  |
  = 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>
  = note: `#[deny(invalid_type_param_default)]` on by default

解释

默认类型参数原本只允许在某些情况下使用,但从历史上看,编译器允许在任何地方使用它们。这是一个 未来不兼容 的 lint,以便将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #36887

let-underscore-lock

let_underscore_lock 检查会检查未将互斥锁绑定到任何内容的语句,导致锁立即释放而不是在作用域结束时释放,这通常是不正确的。

示例

use std::sync::{Arc, Mutex};
use std::thread;
let data = Arc::new(Mutex::new(0));

thread::spawn(move || {
    // The lock is immediately released instead of at the end of the
    // scope, which is probably not intended.
    let _ = data.lock().unwrap();
    println!("doing some work");
    let mut lock = data.lock().unwrap();
    *lock += 1;
});

这将产生

error: non-binding let on a synchronization lock
 --> lint_example.rs:9:9
  |
9 |     let _ = data.lock().unwrap();
  |         ^ this lock is not assigned to a binding and is immediately dropped
  |
  = note: `#[deny(let_underscore_lock)]` on by default
help: consider binding to an unused variable to avoid immediately dropping the value
  |
9 |     let _unused = data.lock().unwrap();
  |         ~~~~~~~
help: consider immediately dropping the value
  |
9 |     drop(data.lock().unwrap());
  |     ~~~~~                    +

解释

将表达式赋给下划线的语句会导致表达式立即删除,而不是将表达式的生存期延长到作用域的末尾。这通常是无意的,特别是对于 MutexGuard 之类的类型,它们通常用于在整个作用域期间锁定互斥锁。

如果要将表达式的生存期延长到作用域的末尾,请为表达式分配一个以下划线为前缀的名称(例如 _foo)。如果确实要立即删除表达式,则对表达式调用 std::mem::drop 更清晰,并且有助于传达意图。

long-running-const-eval

当 const eval 运行时间过长时,会发出 long_running_const_eval lint,以确保即使您不小心编写了无限循环,rustc 也会终止。

示例

const FOO: () = loop {};

这将产生

error: constant evaluation is taking a long time
 --> lint_example.rs:2:17
  |
2 | const FOO: () = loop {};
  |                 ^^^^^^^
  |
  = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
          If your compilation actually takes a long time, you can safely allow the lint.
help: the constant being evaluated
 --> lint_example.rs:2:1
  |
2 | const FOO: () = loop {};
  | ^^^^^^^^^^^^^
  = note: `#[deny(long_running_const_eval)]` on by default

解释

循环允许 const eval 计算任意代码,但也可能导致无限循环或运行时间非常长的计算。用户可以通过允许对单个常量或整个 crate 进行 lint 来启用长时间运行的计算。

无条件警告

请注意,无论是否允许或设置为警告 lint,如果常量求值的运行时间明显超过此 lint 的限制,编译器都将发出警告。这些警告也会显示给来自 crates.io 或类似注册表的 downstream 用户。如果您超过了 lint 的限制,则您和 downstream 用户都可能会收到这些警告。它们也可能出现在编译器更新中,因为编译器对复杂性的衡量方式进行了细微更改:保持在限制以下可确保有足够的空间,并且鉴于对使用您的依赖项的人禁用了 lint,这意味着您将是唯一收到警告的人,并且可以自行发布更新。

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

macro_expanded_macro_exports_accessed_by_absolute_paths 检查会检测当前 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!();
   |     ^^^^^^^^^^^^^^^
   |
   = 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: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
   = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info)

解释

其目的是使所有标有 #[macro_export] 属性的宏在 crate 的根目录下可用。但是,当 macro_rules! 定义由另一个宏生成时,宏展开无法遵守此规则。这是一个 未来不兼容 的 lint,用于在将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #53495

missing-fragment-specifier

macro_rules! 宏定义中未使用的模式具有未跟随片段说明符(例如 :expr)的元变量(例如 $e)时,将发出 missing_fragment_specifier lint。

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

示例

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

fn main() {
   foo!();
}

这将产生

error: missing fragment specifier
 --> lint_example.rs:3:5
  |
3 |    ($name) => { };
  |     ^^^^^
  |
  = 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>
  = note: `#[deny(missing_fragment_specifier)]` on by default

解释

要解决此问题,请从 macro_rules! 宏定义中删除未使用的模式

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

mutable-transmutes

mutable_transmutes lint 会捕获从 &T&mut T 的转换,因为这是 未定义行为

示例

unsafe {
    let y = std::mem::transmute::<&i32, &mut i32>(&5);
}

这将产生

error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, 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

named-asm-labels

named_asm_labels lint 会检测内联 asm! 宏中是否使用了命名标签。

示例

#![feature(asm_experimental_arch)]
use std::arch::asm;

fn main() {
    unsafe {
        asm!("foo: bar");
    }
}

这将产生

error: avoid using named labels in inline assembly
 --> lint_example.rs:6:15
  |
6 |         asm!("foo: bar");
  |               ^^^
  |
  = help: only local labels of the form `<number>:` should be used in inline asm
  = note: see the asm section of Rust By Example <https://doc.rust-lang.net.cn/nightly/rust-by-example/unsafe/asm.html#labels> for more information
  = note: `#[deny(named_asm_labels)]` on by default

解释

LLVM 允许出于任何原因复制内联汇编块,例如当它在被内联的函数中时。因此,必须使用 GNU 汇编程序 本地标签 而不是带有名称的标签。使用命名标签可能会导致汇编程序或链接器错误。

有关更多详细信息,请参阅 Rust 示例 中的说明。

no-mangle-const-items

no_mangle_const_items lint 会检测具有 no_mangle 属性 的任何 const 项。

示例

#[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 会检测到特征一致性冲突,该冲突将允许为涉及标记特征的相同动态特征对象创建两个特征实现。

示例

pub trait Trait {}

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

这将产生

error: conflicting implementations of trait `Trait` for type `(dyn Send + 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 Send + Sync + 'static)`
  |
  = 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>
  = note: `#[deny(order_dependent_trait_objects)]` on by default

解释

先前的错误导致编译器将具有不同顺序的特征(例如 Send + SyncSync + Send)解释为不同类型,而它们原本应该被视为相同类型。这允许代码在应该出现一致性错误时定义单独的特征实现。这是一个 未来不兼容 的 lint,用于在将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #56484

overflowing-literals

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

示例

let x: u8 = 1000;

这将产生

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

解释

使用超出其使用类型范围的字面量通常是一个错误。请使用范围内的字面量,或更改类型以使其在字面量的范围内。

patterns-in-fns-without-body

patterns_in_fns_without_body lint 会将没有主体的函数中的 mut 标识符模式检测为参数。

示例

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);
  |            ^^^^^^^ help: remove `mut` from the parameter: `arg`
  |
  = 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>
  = note: `#[deny(patterns_in_fns_without_body)]` on by default

解释

要解决此问题,请从特征定义中的参数中删除 mut;它可以在实现中使用。也就是说,以下是正确的

trait Trait {
    fn foo(arg: u8); // Removed `mut` here
}

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

    }
}

特征定义可以定义没有主体的函数,以指定实现者必须定义的函数。无主体的函数中的参数名称只能是 _ 或用于文档目的的 标识符(只有类型是相关的)。以前版本的编译器错误地允许使用带有 mut 关键字的 标识符模式,但这并非预期允许的。这是一个 未来不兼容 的 lint,用于在将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #35203

proc-macro-back-compat

proc_macro_back_compat lint 会检测对某些 proc-macro crate 的旧版本的使用,这些版本在编译器中具有硬编码的解决方法。

示例


use time_macros_impl::impl_macros;
struct Foo;
impl_macros!(Foo);

这将产生

warning: using an old version of `time-macros-impl`
  ::: $DIR/group-compat-hack.rs:27:5
   |
LL |     impl_macros!(Foo);
   |     ------------------ in this macro invocation
   |
   = note: `#[warn(proc_macro_back_compat)]` 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 #83125 <https://github.com/rust-lang/rust/issues/83125>
   = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage
   = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

解释

最终,编译器中存在的向后兼容性技巧将被删除,导致某些 crate 的旧版本停止编译。这是一个 未来不兼容 的 lint,用于简化向错误的过渡。有关更多详细信息,请参阅 问题 #83125

proc-macro-derive-resolution-fallback

proc_macro_derive_resolution_fallback lint 会检测使用来自父模块的不可访问名称的 proc 宏派生。

示例

// 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() {}

这将产生

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>

解释

如果 proc-macro 生成一个模块,编译器会无意中允许该模块中的项引用 crate 根目录中的项,而无需导入它们。这是一个 未来不兼容 的 lint,用于在将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #50504

pub-use-of-private-extern-crate

pub_use_of_private_extern_crate lint 会检测重新导出私有 extern crate 的特定情况。

示例

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;
  |         ^^^^^^^^^^^^^^^^^^^^^^^
  |
  = 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>
  = note: `#[deny(pub_use_of_private_extern_crate)]` on by default

解释

公共 use 声明不应用于公开重新导出私有 extern crate。应该改用 pub extern crate

这在历史上是允许的,但根据可见性规则,这不是预期的行为。这是一个 未来不兼容 的 lint,用于在将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #34537

soft-unstable

soft_unstable lint 会检测在稳定版上无意中允许的不稳定功能。

示例

#[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]
  |   ^^^^^
  |
  = 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>
  = note: `#[deny(soft_unstable)]` on by default

解释

bench 属性 被意外允许在 稳定版发布渠道 上指定。将其转换为硬错误会破坏某些项目。当使用 --cap-lints 时,此 lint 允许这些项目继续正确构建,但在其他情况下会发出 #[bench] 不应在稳定版渠道上使用的错误信号。这是一个 未来不兼容 的 lint,用于在将来将其转换为硬错误。有关更多详细信息,请参阅 问题 #64266

test-unstable-lint

test_unstable_lint lint 测试不稳定的 lint,并且是永久不稳定的。

示例

#![allow(test_unstable_lint)]

这将产生

warning: unknown lint: `test_unstable_lint`
 --> lint_example.rs:1:1
  |
1 | #![allow(test_unstable_lint)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: the `test_unstable_lint` lint is unstable
  = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
  = note: this compiler was built on 2024-06-10; consider upgrading it if it is out of date
  = note: `#[warn(unknown_lints)]` on by default

解释

为了测试不稳定 lint 的行为,需要一个永久不稳定的 lint。此 lint 可用于触发与不稳定 lint 相关的编译器警告和错误。

text-direction-codepoint-in-comment

text_direction_codepoint_in_comment lint 会检测注释中以与内存中表示形式不符的方式更改屏幕上文本视觉表示的 Unicode 代码点。

示例

#![deny(text_direction_codepoint_in_comment)]
fn main() {
    println!("{:?}"); // '‮');
}

这将产生

error: unicode codepoint changing visible direction of text present in comment
 --> lint_example.rs:3:23
  |
3 |     println!("{:?}"); // '');
  |                       ^^^^-^^
  |                       |   |
  |                       |   '\u{202e}'
  |                       this comment contains an invisible unicode text flow control codepoint
  |
  = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
note: the lint level is defined here
 --> lint_example.rs:1:9
  |
1 | #![deny(text_direction_codepoint_in_comment)]
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = help: if their presence wasn't intentional, you can remove them

解释

Unicode 允许更改屏幕上文本的视觉流程,以支持从右到左书写的脚本,但经过特殊设计的注释可以使要编译的代码看起来像是注释的一部分,具体取决于用于读取代码的软件。为了避免潜在的问题或混淆,例如 CVE-2021-42574,默认情况下,我们拒绝使用它们。

text-direction-codepoint-in-literal

text_direction_codepoint_in_literal lint 会检测以与内存中表示形式不符的方式更改屏幕上文本视觉表示的 Unicode 代码点。

解释

Unicode 字符 \u{202A}\u{202B}\u{202D}\u{202E}\u{2066}\u{2067}\u{2068}\u{202C}\u{2069} 会使屏幕上文本的流程在其支持这些代码点的软件上改变其方向。这使得文本“abc”在屏幕上显示为“cba”。通过利用支持这些代码点的软件,人们可以编写经过特殊设计的文字,使周围的代码看起来像是在执行一个动作,而实际上是在执行另一个动作。因此,我们主动地对其存在进行 lint 检查,以避免出现意外。

示例

#![deny(text_direction_codepoint_in_literal)]
fn main() {
    println!("{:?}", '‮');
}

这将产生

error: unicode codepoint changing visible direction of text present in literal
 --> lint_example.rs:3:22
  |
3 |     println!("{:?}", '');
  |                      ^-
  |                      ||
  |                      |'\u{202e}'
  |                      this literal contains an invisible unicode text flow control codepoint
  |
  = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
note: the lint level is defined here
 --> lint_example.rs:1:9
  |
1 | #![deny(text_direction_codepoint_in_literal)]
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = help: if their presence wasn't intentional, you can remove them
help: if you want to keep them but make them visible in your source code, you can escape them
  |
3 |     println!("{:?}", '\u{202e}');
  |                       ~~~~~~~~

unconditional-panic

unconditional_panic lint 会检测在运行时会导致 panic 的操作。

示例

#![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,例如除以零和数组越界访问。如果这是一个错误,请考虑调整您的代码,或者在 panic 是预期的情况下使用 panic!unreachable! 宏。

undropped-manually-drops

undropped_manually_drops lint 检查对 std::mem::drop 的调用,该调用使用不删除的 std::mem::ManuallyDrop 值。

示例

struct S;
drop(std::mem::ManuallyDrop::new(S));

这将产生

error: calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
 --> lint_example.rs:3:1
  |
3 | drop(std::mem::ManuallyDrop::new(S));
  | ^^^^^------------------------------^
  |      |
  |      argument has type `ManuallyDrop<S>`
  |
  = note: `#[deny(undropped_manually_drops)]` on by default
help: use `std::mem::ManuallyDrop::into_inner` to get the inner value
  |
3 | drop(std::mem::ManuallyDrop::into_inner(std::mem::ManuallyDrop::new(S)));
  |      +++++++++++++++++++++++++++++++++++                              +

解释

ManuallyDrop 不会删除其内部值,因此调用 std::mem::drop 也不会删除 ManuallyDrop 的内部值。

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 会检测无效的弃用属性。

示例

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

解释

弃用属性对特征实现没有影响。