默认拒绝 Lint
这些 lint 默认都设置为 'deny' 级别。
ambiguous_associated_items
arithmetic_overflow
binary_asm_labels
bindings_with_variant_name
cenum_impl_drop_cast
conflicting_repr_hints
default_overrides_default_fields
elided_lifetimes_in_associated_constant
enum_intrinsics_non_enums
exceeding-bitshifts
explicit_builtin_cfgs_in_flags
ill_formed_attribute_input
incomplete_include
ineffective_unstable_trait_impl
invalid_atomic_ordering
invalid_doc_attributes
invalid_from_utf8_unchecked
invalid_reference_casting
invalid_type_param_default
let_underscore_lock
long_running_const_eval
macro_expanded_macro_exports_accessed_by_absolute_paths
missing_fragment_specifier
mutable_transmutes
named_asm_labels
no_mangle_const_items
order_dependent_trait_objects
overflowing_literals
patterns_in_fns_without_body
proc_macro_derive_resolution_fallback
pub_use_of_private_extern_crate
soft_unstable
test_unstable_lint
text_direction_codepoint_in_comment
text_direction_codepoint_in_literal
unconditional_panic
undropped_manually_drops
unknown_crate_types
useless_deprecated
wasm_c_abi
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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #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。考虑调整表达式以避免溢出,或使用不会溢出的数据类型。
binary-asm-labels
binary_asm_labels
lint 检测在内联 asm!
宏中使用仅包含二进制数字的数字标签。
示例
#![cfg(target_arch = "x86_64")]
use std::arch::asm;
fn main() {
unsafe {
asm!("0: jmp 0b");
}
}
这将产生
error: avoid using labels containing only the digits `0` and `1` in inline assembly
--> <source>:7:15
|
7 | asm!("0: jmp 0b");
| ^ use a different label that doesn't start with `0` or `1`
|
= help: start numbering with `2` instead
= note: an LLVM bug makes these labels ambiguous with a binary literal number on x86
= note: see <https://github.com/llvm/llvm-project/issues/99547> for more information
= note: `#[deny(binary_asm_labels)]` on by default
解释
一个 LLVM 错误 导致此代码编译失败,因为它将 0b
解释为二进制字面量,而不是对先前本地标签 0
的引用。要解决此错误,请不要使用可能与二进制字面量混淆的标签。
此行为特定于 x86 和 x86-64 平台。
有关更多详细信息,请参见 Rust By Example 中的解释。
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
的无字段 enum
的 as
转换。
示例
#![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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #73333。
conflicting-repr-hints
conflicting_repr_hints
lint 检测具有冲突提示的 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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #68585。
要纠正此问题,请删除其中一个冲突的提示。
default-overrides-default-fields
default_overrides_default_fields
lint 检查具有默认字段值的类型的 Default
trait 的手动 impl
块。
示例
#![feature(default_field_values)]
struct Foo {
x: i32 = 101,
y: NonDefault,
}
struct NonDefault;
#[deny(default_overrides_default_fields)]
impl Default for Foo {
fn default() -> Foo {
Foo { x: 100, y: NonDefault }
}
}
这将产生
error: `Default` impl doesn't use the declared default field values
--> lint_example.rs:11:1
|
11 | / impl Default for Foo {
12 | | fn default() -> Foo {
13 | | Foo { x: 100, y: NonDefault }
| | --- this field has a default value
14 | | }
15 | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> lint_example.rs:10:8
|
10 | #[deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
解释
为具有默认字段值的类型手动编写 Default
实现会带来 Type { .. }
和 <Type as Default>::default()
之间行为差异的风险,这对于期望它们等效的该类型用户来说将是一个陷阱。如果由于某些字段没有 Default
实现而无法派生 Default
,我们鼓励对具有默认字段值的字段使用 ..
。
elided-lifetimes-in-associated-constant
当作用域中存在其他生命周期时,elided_lifetimes_in_associated_constant
lint 检测关联常量中省略的生命周期。这在意外情况下得到了支持,并且此 lint 后来被放宽,以允许在作用域中没有生命周期时将生命周期省略为 'static
。
示例
#![deny(elided_lifetimes_in_associated_constant)]
struct Foo<'a>(&'a ());
impl<'a> Foo<'a> {
const STR: &str = "hello, world";
}
这将产生
error: `&` without an explicit lifetime name cannot be used here
--> lint_example.rs:7:16
|
7 | const STR: &str = "hello, world";
| ^
|
= 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 #115010 <https://github.com/rust-lang/rust/issues/115010>
note: cannot automatically infer `'static` because of other lifetimes in scope
--> lint_example.rs:6:6
|
6 | impl<'a> Foo<'a> {
| ^^
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(elided_lifetimes_in_associated_constant)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use the `'static` lifetime
|
7 | const STR: &'static str = "hello, world";
| +++++++
解释
Rust 的早期版本
由于歧义,关联常量被 反对 隐式 static-in-const 行为。但是,这已退化,并且编译器错误地将关联常量中省略的生命周期视为 impl 上的生命周期参数。
这是一个 未来不兼容 的 lint,以便将来过渡为硬错误。
enum-intrinsics-non-enums
enum_intrinsics_non_enums
lint 检测对需要枚举的内在函数(core::mem::discriminant
,core::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::discriminant
和 mem::variant_count
函数是类型 T
的泛型。这使得 T
在技术上可能成为非枚举,在这种情况下,返回值是未指定的。
此 lint 阻止了这些函数的不正确使用。
exceeding-bitshifts
lint exceeding-bitshifts
已重命名为 arithmetic-overflow
。
explicit-builtin-cfgs-in-flags
explicit_builtin_cfgs_in_flags
lint 检测通过 --cfg
标志设置的内置 cfgs。
示例
rustc --cfg unix
fn main() {}
这将产生
error: unexpected `--cfg unix` flag
|
= note: config `unix` is only supposed to be controlled by `--target`
= note: manually setting a built-in cfg can and does create incoherent behaviors
= note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
解释
设置内置 cfgs 可能会并且确实会产生不连贯的行为,最好使用控制配置的适当 rustc
标志。例如,在基于 Linux 的目标上设置 windows
cfg。
ill-formed-attribute-input
ill_formed_attribute_input
lint 检测先前被接受并在实践中使用的格式错误的属性输入。
示例
#[inline = "this is not valid"]
fn foo() {}
这将产生
error: valid forms for the attribute are `#[inline]` and `#[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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #57571。
有关属性的有效输入的详细信息,请查看 属性参考。
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!
表达式在分号之前结束,使分号成为被忽略的“额外”信息。更令人惊讶的是,如果包含的文件有多个打印语句,则后续的打印语句将被忽略!
一种解决方法是将内容放在花括号中以创建 块表达式。还可以考虑其他替代方案,例如使用函数封装表达式,或使用 proc-macros。
这是一个 lint 而不是硬错误,因为发现现有项目遇到了此错误。为了谨慎起见,目前它是一个 lint。include!
宏的未来语义也不确定,请参见 issue #35560。
ineffective-unstable-trait-impl
ineffective_unstable_trait_impl
lint 检测未使用的 #[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
块上使用稳定性属性。如果类型和 trait 都稳定,则 impl
始终是稳定的;否则,始终是不稳定的。
invalid-atomic-ordering
invalid_atomic_ordering
lint 检测到将 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
变体的子集。传递不受支持的变体将导致运行时无条件 panic,此 lint 会检测到这种情况。
在以下情况下,此 lint 将触发:(其中 AtomicType
是 core::sync::atomic
中的原子类型,例如 AtomicBool
、AtomicPtr
、AtomicUsize
或任何其他整数原子类型)。
-
将
Ordering::Acquire
或Ordering::AcqRel
传递给AtomicType::store
。 -
将
Ordering::Release
或Ordering::AcqRel
传递给AtomicType::load
。 -
将
Ordering::Relaxed
传递给core::sync::atomic::fence
或core::sync::atomic::compiler_fence
。 -
将
Ordering::Release
或Ordering::AcqRel
作为任何AtomicType::compare_exchange
、AtomicType::compare_exchange_weak
或AtomicType::fetch_update
的失败排序传递。
invalid-doc-attributes
invalid_doc_attributes
lint 检测到何时错误使用 #[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 <http://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
lint 检查是否使用已知的无效 UTF-8 值调用 std::str::from_utf8_unchecked
和 std::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_unchecked
和 std::str::from_utf8_unchecked_mut
的文档,创建这样的 str
将导致未定义的行为。
invalid-reference-casting
invalid_reference_casting
lint 检查是否在不使用内部可变性的情况下将 &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 <http://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
lint 检测到在无效位置错误地允许的类型参数默认值。
示例
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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #36887。
let-underscore-lock
let_underscore_lock
lint 检查未将互斥锁绑定到任何内容的语句,这会导致锁立即释放而不是在作用域结束时释放,这通常是不正确的。
示例
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());
| ~~~~~ +
解释
将表达式分配给下划线的语句会导致表达式立即 drop,而不是将表达式的生命周期扩展到作用域的末尾。这通常是无意的,特别是对于像 MutexGuard
这样的类型,这些类型通常用于在整个作用域内锁定互斥锁。
如果要将表达式的生命周期扩展到作用域的末尾,请将以下划线为前缀的名称(例如 _foo
)分配给该表达式。如果确实要立即 drop 表达式,则在表达式上调用 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 求值计算任意代码,但也可能导致无限循环或只是运行时间很长的计算。用户可以通过允许单个常量或整个 crate 上的 lint 来启用长时间运行的计算。
无条件警告
请注意,无论 lint 是允许还是设置为警告,如果常量求值运行时间明显长于此 lint 的限制,编译器都会发出警告。这些警告也从 crates.io 或类似注册表中向下游用户显示。如果您高于 lint 的限制,您和下游用户都可能暴露于这些警告。它们也可能出现在编译器更新中,因为编译器对复杂性的衡量方式进行了细微的更改:保持在限制以下可确保有足够的空间,并且考虑到对于使用您的依赖项的人员禁用了 lint,这意味着您将是唯一收到警告的人,并且可以在您自己的时间发布更新。
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!();
| ^^^^^^^^^^^^^^^
|
= 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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #53495。
missing-fragment-specifier
当 macro_rules!
宏定义中的未使用模式具有元变量(例如 $e
)但未后跟片段说明符(例如 :expr
)时,会发出 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
的 transmute,因为它是 未定义的行为。
示例
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
解释
对数据的别名做出了一些假设,而此 transmute 违反了这些假设。考虑改用 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 <http://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 By Example 中的解释。
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 检测到 trait 一致性违规,该违规将允许为涉及标记 trait 的同一动态 trait 对象创建两个 trait impl。
示例
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
解释
先前的错误导致编译器将具有不同顺序的 trait(例如 Send + Sync
和 Sync + Send
)解释为不同的类型,而它们本应被视为相同的类型。这允许代码在应该存在一致性错误时定义单独的 trait 实现。这是一个 未来不兼容 的 lint,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #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
解释
要修复此问题,请从 trait 定义中的参数中删除 mut
;它可以在实现中使用。也就是说,以下是可以的
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。
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,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #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[E0365]: extern crate `core` is private and cannot be re-exported
--> 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 #127909 <https://github.com/rust-lang/rust/issues/127909>
= note: `#[deny(pub_use_of_private_extern_crate)]` on by default
help: consider making the `extern crate` item publicly accessible
|
2 | pub extern crate core;
| +++
解释
公共 use
声明不应用于公开重新导出私有 extern crate
。应使用 pub extern crate
代替。
从历史上看,这是允许的,但根据可见性规则,这不是预期的行为。这是一个 未来不兼容 的 lint,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #127909。
soft-unstable
soft_unstable
lint 检测到在 stable 上意外允许的不稳定功能。
示例
#[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
属性 意外地允许在 stable 发布通道 上指定。将其转换为硬错误会破坏一些项目。当使用 --cap-lints
时,此 lint 允许这些项目继续正确构建,否则会发出错误信号,表明不应在 stable 通道上使用 #[bench]
。这是一个 未来不兼容 的 lint,以便将来过渡为硬错误。有关更多详细信息,请参见 issue #64266。
test-unstable-lint
test_unstable_lint
lint 测试不稳定的 lint,并且是永久不稳定的。
示例
#![allow(test_unstable_lint)]
这将产生
warning: unknown lint: `test_unstable_lint`
--> lint_example.rs:1:10
|
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 2025-02-17; 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,例如除以零和越界数组访问。如果这是一个 bug,请考虑调整您的代码,或者在 panic 是有意为之的情况下,使用 panic!
或 unreachable!
宏代替。
undropped-manually-drops
undropped_manually_drops
lint 检查是否使用值 std::mem::ManuallyDrop
调用 std::mem::drop
,而 std::mem::ManuallyDrop
不会 drop。
示例
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
不会 drop 其内部值,因此调用 std::mem::drop
也不会 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 检测没有效果的 deprecation 属性。
示例
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
解释
Deprecation 属性对 trait 实现没有影响。
wasm-c-abi
wasm_c_abi
lint 检测与未来版本的 Rust 不兼容的 crate 依赖项,未来版本的 Rust 将发出符合规范的 C ABI。
示例
#![deny(wasm_c_abi)]
这将产生
error: the following packages contain code that will be rejected by a future version of Rust: wasm-bindgen v0.2.87
|
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![deny(wasm_c_abi)]
| ^^^^^^^^^^
解释
Rust 从历史上看发出了不符合规范的 C ABI。这导致了其他编译器和 Wasm 目标之间的不兼容性。在未来版本的 Rust 中,这将得到修复,因此依赖于不符合规范的 C ABI 的依赖项将停止运行。