默认警告的 Lint
这些 Lint 默认都设置为 'warn' 级别。
abi_unsupported_vector_types
ambiguous_glob_imports
ambiguous_glob_reexports
ambiguous_wide_pointer_comparisons
anonymous_parameters
array_into_iter
asm_sub_register
async_fn_in_trait
bad_asm_style
bare-trait-object
bare_trait_objects
boxed_slice_into_iter
break_with_label_and_loop
clashing_extern_declarations
coherence_leak_check
confusable_idents
const_evaluatable_unchecked
const_item_mutation
dangling_pointers_from_temporaries
dead_code
dependency_on_unit_never_type_fallback
deprecated
deprecated_where_clause_location
deref_nullptr
double_negations
drop_bounds
dropping_copy_types
dropping_references
duplicate_macro_attributes
dyn_drop
elided_named_lifetimes
ellipsis_inclusive_range_patterns
exported_private_dependencies
for_loops_over_fallibles
forbidden_lint_groups
forgetting_copy_types
forgetting_references
function_item_references
hidden_glob_reexports
improper_ctypes
improper_ctypes_definitions
incomplete_features
inline_no_sanitize
internal_features
invalid_from_utf8
invalid_macro_export_arguments
invalid_nan_comparisons
invalid_value
irrefutable_let_patterns
large_assignments
late_bound_lifetime_arguments
legacy_derive_helpers
map_unit_fn
missing_abi
mixed_script_confusables
named_arguments_used_positionally
never_type_fallback_flowing_into_unsafe
no_mangle_generic_items
non-fmt-panic
non_camel_case_types
non_contiguous_range_endpoints
non_fmt_panics
non_local_definitions
non_shorthand_field_patterns
non_snake_case
non_upper_case_globals
noop_method_call
opaque_hidden_inferred_bound
out_of_scope_macro_calls
overlapping-patterns
overlapping_range_endpoints
path_statements
private_bounds
private_interfaces
private_macro_use
ptr_to_integer_transmute_in_consts
redundant-semicolon
redundant_semicolons
refining_impl_trait_internal
refining_impl_trait_reachable
renamed_and_removed_lints
repr_transparent_external_private_fields
self_constructor_from_outer_item
semicolon_in_expressions_from_macros
special_module_name
stable_features
static-mut-ref
static_mut_refs
suspicious_double_ref_op
trivial_bounds
type_alias_bounds
tyvar_behind_raw_pointer
uncommon_codepoints
unconditional_recursion
uncovered_param_in_projection
undefined_naked_function_abi
unexpected_cfgs
unfulfilled_lint_expectations
ungated_async_fn_track_caller
uninhabited_static
unknown_lints
unknown_or_malformed_diagnostic_attributes
unnameable_test_items
unpredictable_function_pointer_comparisons
unreachable_code
unreachable_patterns
unstable-name-collision
unstable_name_collisions
unstable_syntax_pre_expansion
unsupported_fn_ptr_calling_conventions
unused-doc-comment
unused-tuple-struct-fields
unused_allocation
unused_assignments
unused_associated_type_bounds
unused_attributes
unused_braces
unused_comparisons
unused_doc_comments
unused_features
unused_imports
unused_labels
unused_macros
unused_must_use
unused_mut
unused_parens
unused_unsafe
unused_variables
useless_ptr_null_checks
uses_power_alignment
warnings
wasm_c_abi
while_true
abi-unsupported-vector-types
abi_unsupported_vector_types
Lint 检测函数定义和调用,其 ABI 依赖于启用某些目标特性,但这些特性未启用。
示例
extern "C" fn missing_target_feature(_: std::arch::x86_64::__m256) {
todo!()
}
#[target_feature(enable = "avx")]
unsafe extern "C" fn with_target_feature(_: std::arch::x86_64::__m256) {
todo!()
}
fn main() {
let v = unsafe { std::mem::zeroed() };
unsafe { with_target_feature(v); }
}
这将产生
warning: ABI error: this function call uses a avx vector type, which is not enabled in the caller
--> lint_example.rs:18:12
|
| unsafe { with_target_feature(v); }
| ^^^^^^^^^^^^^^^^^^^^^^ function called here
|
= 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 #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (-C target-feature=+avx) or locally (#[target_feature(enable="avx")])
= note: `#[warn(abi_unsupported_vector_types)]` on by default
warning: ABI error: this function definition uses a avx vector type, which is not enabled
--> lint_example.rs:3:1
|
| pub extern "C" fn with_target_feature(_: std::arch::x86_64::__m256) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
= 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 #116558 <https://github.com/rust-lang/rust/issues/116558>
= help: consider enabling it globally (-C target-feature=+avx) or locally (#[target_feature(enable="avx")])
解释
__m256
的 C ABI 要求值在 AVX 寄存器中传递,这只有在启用 avx
目标特性时才可能。因此,missing_target_feature
在没有该目标特性时无法编译。当没有启用 avx
目标特性的函数调用 with_target_feature
时,会触发类似(但互补)的消息。
请注意,这个 Lint 与 gcc
/clang
中的 -Wpsabi
警告非常相似。
ambiguous-glob-imports
ambiguous_glob_imports
Lint 检测那些应该报告歧义错误,但由于 rustc 的 bug 以前没有报告的 glob 导入。
示例
#![deny(ambiguous_glob_imports)]
pub fn foo() -> u32 {
use sub::*;
C
}
mod sub {
mod mod1 { pub const C: u32 = 1; }
mod mod2 { pub const C: u32 = 2; }
pub use mod1::*;
pub use mod2::*;
}
这将产生
error: `C` is ambiguous
--> lint_example.rs:5:5
|
5 | C
| ^ ambiguous 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 #114095 <https://github.com/rust-lang/rust/issues/114095>
= note: ambiguous because of multiple glob imports of a name in the same module
note: `C` could refer to the constant imported here
--> lint_example.rs:12:13
|
12 | pub use mod1::*;
| ^^^^^^^
= help: consider adding an explicit import of `C` to disambiguate
note: `C` could also refer to the constant imported here
--> lint_example.rs:13:13
|
13 | pub use mod2::*;
| ^^^^^^^
= help: consider adding an explicit import of `C` to disambiguate
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(ambiguous_glob_imports)]
| ^^^^^^^^^^^^^^^^^^^^^^
解释
以前的 Rust 版本可以成功编译它,因为它在解析 use sub::mod2::*
时丢失了歧义错误。
这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。
ambiguous-glob-reexports
ambiguous_glob_reexports
Lint 检测通过 glob 重导出的名称发生冲突的情况。尝试使用从多个 glob 重导出的相同名称的下游用户将收到警告,指出同一名称被重复定义。
示例
#![deny(ambiguous_glob_reexports)]
pub mod foo {
pub type X = u8;
}
pub mod bar {
pub type Y = u8;
pub type X = u8;
}
pub use foo::*;
pub use bar::*;
pub fn main() {}
这将产生
error: ambiguous glob re-exports
--> lint_example.rs:11:9
|
11 | pub use foo::*;
| ^^^^^^ the name `X` in the type namespace is first re-exported here
12 | pub use bar::*;
| ------ but the name `X` in the type namespace is also re-exported here
|
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(ambiguous_glob_reexports)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
解释
这以前是被接受的,但它可能会悄悄地破坏 crate 的下游用户代码。例如,如果在 bar::X
被添加到重导出之前,foo::*
和 bar::*
被重导出,下游用户可以使用 this_crate::X
而没有问题。然而,添加 bar::X
会导致下游 crate 中的编译错误,因为 X
在 this_crate
的同一命名空间中被多次定义。
ambiguous-wide-pointer-comparisons
ambiguous_wide_pointer_comparisons
Lint 检查以 *const/*mut ?Sized
作为操作数的比较。
示例
struct A;
struct B;
trait T {}
impl T for A {}
impl T for B {}
let ab = (A, B);
let a = &ab.0 as *const dyn T;
let b = &ab.1 as *const dyn T;
let _ = a == b;
这将产生
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
--> lint_example.rs:13:9
|
13 | let _ = a == b;
| ^^^^^^
|
= note: `#[warn(ambiguous_wide_pointer_comparisons)]` on by default
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
13 - let _ = a == b;
13 + let _ = std::ptr::addr_eq(a, b);
|
解释
比较包含了可能不期望的元数据。
anonymous-parameters
anonymous_parameters
Lint 检测 trait 定义中的匿名参数。
示例
#![deny(anonymous_parameters)]
// edition 2015
pub trait Foo {
fn foo(usize);
}
fn main() {}
这将产生
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`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
= note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(anonymous_parameters)]
| ^^^^^^^^^^^^^^^^^^^^
解释
这种语法主要是历史遗留问题,通过添加 _
模式或描述性标识符可以很容易地解决。
trait Foo {
fn foo(_: usize);
}
在 2018 版中,此语法现在是硬错误。在 2015 版中,此 Lint 默认为“warn”。此 Lint 使 cargo fix
工具能够配合 --edition
标志自动将旧代码从 2015 版迁移到 2018 版。该工具将运行此 Lint 并自动应用编译器的建议修复(即为每个参数添加 _
)。这提供了一种完全自动化的方式来更新旧代码以适应新版本。有关更多详细信息,请参阅 issue #41686。
array-into-iter
array_into_iter
Lint 检测在数组上调用 into_iter
。
示例
#![allow(unused)]
[1, 2, 3].into_iter().for_each(|n| { *n; });
这将产生
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> lint_example.rs:3:11
|
3 | [1, 2, 3].into_iter().for_each(|n| { *n; });
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
= note: `#[warn(array_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3 + [1, 2, 3].iter().for_each(|n| { *n; });
|
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
|
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3 + IntoIterator::into_iter([1, 2, 3]).for_each(|n| { *n; });
|
解释
自 Rust 1.53 起,数组实现了 IntoIterator
。然而,为了避免破坏性更改,在 Rust 2015 和 2018 代码中,array.into_iter()
的行为仍然与 (&array).into_iter()
相同,返回一个引用迭代器,就像在 Rust 1.52 及更早版本中一样。这仅适用于方法调用语法 array.into_iter()
,而不适用于任何其他语法,例如 for _ in array
或 IntoIterator::into_iter(array)
。
asm-sub-register
asm_sub_register
Lint 检测仅使用寄存器子集作为内联 asm 输入的情况。
示例
#[cfg(target_arch="x86_64")]
use std::arch::asm;
fn main() {
#[cfg(target_arch="x86_64")]
unsafe {
asm!("mov {0}, {0}", in(reg) 0i16);
}
}
这将产生
warning: formatting may not be suitable for sub-register argument
--> src/main.rs:7:19
|
7 | asm!("mov {0}, {0}", in(reg) 0i16);
| ^^^ ^^^ ---- for this argument
|
= note: `#[warn(asm_sub_register)]` on by default
= help: use the `x` modifier to have the register formatted as `ax`
= help: or use the `r` modifier to keep the default formatting of `rax`
解释
某些架构上的寄存器可以使用不同的名称来指代寄存器的子集。默认情况下,编译器将使用完整寄存器大小的名称。要显式使用寄存器的子集,您可以使用模板字符串操作数上的修饰符来覆盖默认设置,以指定使用哪个子寄存器。如果您传入的值的数据类型小于默认寄存器大小,就会发出此 Lint,以提醒您可能使用了不正确的宽度。要修复此问题,请将建议的修饰符添加到模板中,或将值强制转换为正确的大小。
有关更多详细信息,请参阅参考手册中的寄存器模板修饰符。
async-fn-in-trait
async_fn_in_trait
Lint 检测在公共可访问的 trait 定义中使用 async fn
。
示例
pub trait Trait {
async fn method(&self);
}
fn main() {}
这将产生
warning: use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified
--> lint_example.rs:2:5
|
2 | async fn method(&self);
| ^^^^^
|
= note: you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future`
= note: `#[warn(async_fn_in_trait)]` on by default
help: you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change
|
2 - async fn method(&self);
2 + fn method(&self) -> impl std::future::Future<Output = ()> + Send;
|
解释
当在 trait 定义中使用 async fn
时,该 trait 不保证关联函数或方法返回的不透明 Future
会实现任何 自动 trait,例如 Send
。这可能会令人惊讶,并可能使该 trait 上的关联函数或方法不如预期有用。对于从 crate 公共导出的 trait,这可能会影响下游 crate,因为其作者无法修改 trait 定义。
例如,此代码无效
pub trait Trait {
async fn method(&self) {}
}
fn test<T: Trait>(x: T) {
fn spawn<T: Send>(_: T) {}
spawn(x.method()); // Not OK.
}
此 Lint 的目的是警告公共可访问 trait 的作者,他们可能需要考虑将 async fn
脱糖为返回不透明 impl Future<..> + Send
类型的普通 fn
。
例如,代替
pub trait Trait {
async fn method(&self) {}
}
trait 的作者可能想这样写
use core::future::Future;
pub trait Trait {
fn method(&self) -> impl Future<Output = ()> + Send { async {} }
}
这仍然允许在 trait 的实现中使用 async fn
。但是,这也意味着该 trait 永远不会与方法返回的 Future
未实现 Send
的实现兼容。
反之,如果该 trait 仅在本地使用,从未在泛型函数中使用,或者仅在不关心返回的 Future
是否实现 Send
的单线程上下文中使用,则可以抑制此 Lint。
bad-asm-style
bad_asm_style
Lint 检测使用 .intel_syntax
和 .att_syntax
指令的情况。
示例
#[cfg(target_arch="x86_64")]
use std::arch::asm;
fn main() {
#[cfg(target_arch="x86_64")]
unsafe {
asm!(
".att_syntax",
"movq %{0}, %{0}", in(reg) 0usize
);
}
}
这将产生
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> src/main.rs:8:14
|
8 | ".att_syntax",
| ^^^^^^^^^^^
|
= note: `#[warn(bad_asm_style)]` on by default
解释
在 x86 上,asm!
默认使用 intel 汇编语法。虽然可以使用 `.att_syntax` 等汇编指令进行切换,但建议改用 `att_syntax` 选项,因为它还会按 AT&T 语法要求,为寄存器占位符正确添加 `%` 前缀。
bare-trait-object
Lint bare-trait-object
已重命名为 bare-trait-objects
。
bare-trait-objects
bare_trait_objects
Lint 建议对 trait 对象使用 dyn Trait
。
示例
trait Trait { }
fn takes_trait_object(_: Box<Trait>) {
}
这将产生
warning: trait objects without an explicit `dyn` are deprecated
--> lint_example.rs:4:30
|
4 | fn takes_trait_object(_: Box<Trait>) {
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
4 | fn takes_trait_object(_: Box<dyn Trait>) {
| +++
解释
没有 dyn
指示符,阅读代码时,判断是否正在查看 trait 对象可能会变得模糊或令人困惑。dyn
关键字使其明确,并与 impl Trait
形成对比,增加了对称性。
boxed-slice-into-iter
boxed_slice_into_iter
Lint 检测在 boxed slice 上调用 into_iter
。
示例
#![allow(unused)]
vec![1, 2, 3].into_boxed_slice().into_iter().for_each(|n| { *n; });
这将产生
warning: this method call resolves to `<&Box<[T]> as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<Box<[T]> as IntoIterator>::into_iter` in Rust 2024
--> lint_example.rs:3:34
|
3 | vec![1, 2, 3].into_boxed_slice().into_iter().for_each(|n| { *n; });
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
= note: `#[warn(boxed_slice_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
3 - vec![1, 2, 3].into_boxed_slice().into_iter().for_each(|n| { *n; });
3 + vec![1, 2, 3].into_boxed_slice().iter().for_each(|n| { *n; });
|
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
|
3 - vec![1, 2, 3].into_boxed_slice().into_iter().for_each(|n| { *n; });
3 + IntoIterator::into_iter(vec![1, 2, 3].into_boxed_slice()).for_each(|n| { *n; });
|
解释
自 Rust 1.80.0 起,boxed slice 实现了 IntoIterator
。然而,为了避免破坏性更改,在 Rust 2015、2018 和 2021 代码中,boxed_slice.into_iter()
的行为仍然与 (&boxed_slice).into_iter()
相同,返回一个引用迭代器,就像在 Rust 1.79.0 及更早版本中一样。这仅适用于方法调用语法 boxed_slice.into_iter()
,而不适用于任何其他语法,例如 for _ in boxed_slice
或 IntoIterator::into_iter(boxed_slice)
。
break-with-label-and-loop
break_with_label_and_loop
Lint 检测带有无标签循环作为其值表达式的带标签 break
表达式。
示例
'label: loop {
break 'label loop { break 42; };
};
这将产生
warning: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression
--> lint_example.rs:3:5
|
3 | break 'label loop { break 42; };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(break_with_label_and_loop)]` on by default
help: wrap this expression in parentheses
|
3 | break 'label (loop { break 42; });
| + +
解释
在 Rust 中,循环可以有标签,而 break
表达式可以引用该标签跳出特定循环(不一定是内层循环)。break
表达式也可以携带一个值表达式,它可以是另一个循环。带有无标签循环作为其值表达式的带标签 break
很容易与带有带标签循环的无标签 break 混淆,因此不建议使用(但为了兼容性允许);在循环表达式周围使用括号可以抑制此警告。带有带标签循环的无标签 break
表达式会导致硬错误,也可以通过将表达式包裹在括号中来抑制。
clashing-extern-declarations
clashing_extern_declarations
Lint 检测当 extern fn
以相同名称但不同类型声明时的情况。
示例
mod m {
unsafe extern "C" {
fn foo();
}
}
unsafe extern "C" {
fn foo(_: u32);
}
这将产生
warning: `foo` redeclared with a different signature
--> lint_example.rs:9:5
|
4 | fn foo();
| --------- `foo` previously declared here
...
9 | fn foo(_: u32);
| ^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
= note: expected `unsafe extern "C" fn()`
found `unsafe extern "C" fn(u32)`
= note: `#[warn(clashing_extern_declarations)]` on by default
解释
由于在链接时,同名的两个符号无法解析为两个不同的函数,并且一个函数不可能有两种类型,因此冲突的 extern 声明几乎肯定是一个错误。检查以确保 extern
定义正确且等效,并可能考虑将它们统一在一个位置。
此 Lint 不在 crate 之间运行,因为一个项目可能有依赖项,它们都依赖于同一个 extern 函数,但以不同(但有效)的方式声明它。例如,它们都可能为一个或多个参数声明一个不透明类型(这将导致不同的类型),或使用在定义 extern fn
的语言中有效的转换类型。在这些情况下,编译器无法断定冲突的声明是不正确的。
coherence-leak-check
coherence_leak_check
Lint 检测 trait 的冲突实现,这些实现仅通过旧的 leak-check 代码区分。
示例
trait SomeTrait { }
impl SomeTrait for for<'a> fn(&'a u8) { }
impl<'a> SomeTrait for fn(&'a u8) { }
这将产生
warning: conflicting implementations of trait `SomeTrait` for type `for<'a> fn(&'a u8)`
--> lint_example.rs:4:1
|
3 | impl SomeTrait for for<'a> fn(&'a u8) { }
| ------------------------------------- first implementation here
4 | impl<'a> SomeTrait for fn(&'a u8) { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a u8)`
|
= warning: the behavior may change in a future release
= note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
= note: `#[warn(coherence_leak_check)]` on by default
解释
过去,编译器会接受仅在生命周期绑定器出现位置不同的相同函数的 trait 实现。由于借用检查器实现的变化以修复多个 bug,这不再被允许。然而,由于这会影响现有代码,这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。
依赖此模式的代码应引入“newtypes”,例如 struct Foo(for<'a> fn(&'a u8))
。
有关更多详细信息,请参阅 issue #56105。
confusable-idents
confusable_idents
Lint 检测标识符之间视觉上容易混淆的对。
示例
// Latin Capital Letter E With Caron
pub const Ě: i32 = 1;
// Latin Capital Letter E With Breve
pub const Ĕ: i32 = 2;
这将产生
warning: found both `Ě` and `Ĕ` as identifiers, which look alike
--> lint_example.rs:5:11
|
3 | pub const Ě: i32 = 1;
| - other identifier used here
4 | // Latin Capital Letter E With Breve
5 | pub const Ĕ: i32 = 2;
| ^ this identifier can be confused with `Ě`
|
= note: `#[warn(confusable_idents)]` on by default
解释
此 Lint 在不同标识符可能看起来视觉相似时发出警告,这可能导致混淆。
可混淆检测算法基于Unicode® 技术标准 #39 Unicode 安全机制 第 4 节 可混淆检测。对于每个不同的标识符 X,执行函数 skeleton(X)
。如果同一 crate 中存在两个不同的标识符 X 和 Y,并且 skeleton(X) = skeleton(Y)
,则报告。编译器使用相同的机制检查标识符是否与关键字过于相似。
请注意,可混淆字符集可能会随时间变化。请注意,如果您“禁止”此 Lint,现有代码将来可能会失败。
const-evaluatable-unchecked
const_evaluatable_unchecked
Lint 检测类型中使用的泛型常量。
示例
const fn foo<T>() -> usize {
if size_of::<*mut T>() < 8 { // size of *mut T does not depend on T
4
} else {
8
}
}
fn test<T>() {
let _ = [0; foo::<T>()];
}
这将产生
warning: cannot use constants which depend on generic parameters in types
--> lint_example.rs:11:17
|
11 | let _ = [0; foo::<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 #76200 <https://github.com/rust-lang/rust/issues/76200>
= note: `#[warn(const_evaluatable_unchecked)]` on by default
解释
在 1.43 版本中,意外地允许在数组重复表达式中使用泛型参数的某些情况。这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。有关更详细的描述和可能的修复,请参阅 issue #76200。
const-item-mutation
const_item_mutation
Lint 检测尝试修改 const
项的情况。
示例
const FOO: [i32; 1] = [0];
fn main() {
FOO[0] = 1;
// This will print "[0]".
println!("{:?}", FOO);
}
这将产生
warning: attempting to modify a `const` item
--> lint_example.rs:4:5
|
4 | FOO[0] = 1;
| ^^^^^^^^^^
|
= note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified
note: `const` item defined here
--> lint_example.rs:1:1
|
1 | const FOO: [i32; 1] = [0];
| ^^^^^^^^^^^^^^^^^^^
= note: `#[warn(const_item_mutation)]` on by default
解释
尝试直接修改 const
项几乎总是一个错误。上面示例中发生的情况是,const
的一个临时副本被修改了,但原始的 const
没有。每次您通过名称引用 const
(例如上面示例中的 FOO
),都会在该位置内联一个单独的值副本。
此 Lint 检查直接写入字段(FOO.field = some_value
)或数组条目(FOO[0] = val
),或获取 const 项的可变引用(&mut FOO
),包括通过自动解引用(FOO.some_mut_self_method()
)的情况。
根据您尝试实现的目标,有多种替代方案
- 首先,始终重新考虑使用可变全局变量,因为它们很难正确使用,并且会使代码更难以使用或理解。
- 如果您尝试进行全局变量的一次性初始化
- 如果值可以在编译时计算,请考虑使用 const 兼容的值(参阅常量求值)。
- 对于更复杂的一次性初始化情况,请考虑使用
std::sync::LazyLock
。
- 如果您确实需要可变全局变量,请考虑使用
static
,它有多种选择
dangling-pointers-from-temporaries
dangling_pointers_from_temporaries
Lint 检测获取指向即将立即被丢弃的临时数据的指针。
示例
#![allow(unused)]
unsafe fn use_data(ptr: *const u8) { }
fn gather_and_use(bytes: impl Iterator<Item = u8>) {
let x: *const u8 = bytes.collect::<Vec<u8>>().as_ptr();
unsafe { use_data(x) }
}
这将产生
warning: a dangling pointer will be produced because the temporary `Vec<u8>` will be dropped
--> lint_example.rs:5:51
|
5 | let x: *const u8 = bytes.collect::<Vec<u8>>().as_ptr();
| -------------------------- ^^^^^^ this pointer will immediately be invalid
| |
| this `Vec<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
= note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
= help: you must make sure that the variable you bind the `Vec<u8>` to lives at least as long as the pointer returned by the call to `as_ptr`
= help: in particular, if this pointer is returned from the current function, binding the `Vec<u8>` inside the function will not suffice
= help: for more information, see <https://doc.rust-lang.net.cn/reference/destructors.html>
= note: `#[warn(dangling_pointers_from_temporaries)]` on by default
解释
从临时值获取指针不会延长其生命周期,这意味着当指针仍然存在时,该值可能会被丢弃并释放分配的内存,从而使指针成为悬垂指针。就类型系统而言,这并非错误,但可能也不是用户所期望的。
如果您需要更强的保证,请考虑使用引用,因为它们由借用检查器静态验证,永远不会悬垂。
dead-code
dead_code
Lint 检测未使用、未导出的项。
示例
fn foo() {}
这将产生
warning: function `foo` is never used
--> lint_example.rs:2:4
|
2 | fn foo() {}
| ^^^
|
= note: `#[warn(dead_code)]` on by default
解释
死代码可能表示错误或未完成的代码。要抑制单个项的警告,请在其名称前加上下划线,例如 _foo
。如果打算将该项暴露在 crate 外部,请考虑添加可见性修饰符,例如 pub
。
为了保留带有未使用字段的元组结构体的编号,请将未使用字段的类型更改为 unit 类型或使用 PhantomData
。
否则,请考虑移除未使用的代码。
限制
移除仅用于副作用且从未读取的字段将导致行为改变。这方面的例子包括
- 如果字段的值在被丢弃时执行某个操作。
- 如果字段的类型没有实现自动 trait(例如
Send
,Sync
,Unpin
)。
对于丢弃字段值产生的副作用,应允许对这些字段使用此 Lint。对于包含字段类型产生的副作用,应使用 PhantomData
。
dependency-on-unit-never-type-fallback
dependency_on_unit_never_type_fallback
Lint 检测代码在 never type fallback 为 ()
时可以编译,但在 fallback 为 !
时将停止编译的情况。
示例
#![deny(dependency_on_unit_never_type_fallback)]
fn main() {
if true {
// return has type `!` which, is some cases, causes never type fallback
return
} else {
// the type produced by this call is not specified explicitly,
// so it will be inferred from the previous branch
Default::default()
};
// depending on the fallback, this may compile (because `()` implements `Default`),
// or it may not (because `!` does not implement `Default`)
}
这将产生
error: this function depends on never type fallback being `()`
--> lint_example.rs:2:1
|
2 | fn main() {
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> lint_example.rs:9:9
|
9 | Default::default()
| ^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(dependency_on_unit_never_type_fallback)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use `()` annotations to avoid fallback changes
|
9 | <() as Default>::default()
| ++++++ +
解释
由于历史原因,never type fallback 是 ()
,这意味着 !
会自发地强制转换为 ()
。计划更改这一点,但这可能会导致上述代码无法编译。与其依赖 fallback,不如明确指定类型
if true {
return
} else {
// type is explicitly specified, fallback can't hurt us no more
<() as Default>::default()
};
有关更多详细信息,请参阅 Tracking Issue for making !
fall back to !
。
deprecated
deprecated
Lint 检测已弃用项的使用。
示例
#[deprecated]
fn foo() {}
fn bar() {
foo();
}
这将产生
warning: use of deprecated function `main::foo`
--> lint_example.rs:6:5
|
6 | foo();
| ^^^
|
= note: `#[warn(deprecated)]` on by default
解释
项可以使用 deprecated
属性标记为“已弃用”,表示它们不应再使用。通常,该属性应包含一个说明,指出应使用什么替代,或查阅文档。
deprecated-where-clause-location
deprecated_where_clause_location
Lint 检测关联类型中等号前面带有 where 子句的情况。
示例
trait Trait {
type Assoc<'a> where Self: 'a;
}
impl Trait for () {
type Assoc<'a> where Self: 'a = ();
}
这将产生
warning: where clause not allowed here
--> lint_example.rs:7:18
|
7 | type Assoc<'a> where Self: 'a = ();
| ^^^^^^^^^^^^^^
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
= note: `#[warn(deprecated_where_clause_location)]` on by default
help: move it to the end of the type declaration
|
7 - type Assoc<'a> where Self: 'a = ();
7 + type Assoc<'a> = () where Self: 'a;
|
解释
关联类型上 where 子句的首选位置是在类型之后。然而,对于大多数泛型关联类型的开发,它只在等号之前被接受。为了提供过渡期并进一步评估此更改,目前两者都接受。将来某个时候,这可能会在版本边界被禁止;但这目前尚未决定。
deref-nullptr
deref_nullptr
Lint 检测解引用空指针的情况,这会导致 未定义行为。
示例
#![allow(unused)]
use std::ptr;
unsafe {
let x = &*ptr::null::<i32>();
let x = ptr::addr_of!(*ptr::null::<i32>());
let x = *(0 as *const i32);
}
这将产生
warning: dereferencing a null pointer
--> lint_example.rs:5:14
|
5 | let x = &*ptr::null::<i32>();
| ^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
|
= note: `#[warn(deref_nullptr)]` on by default
warning: dereferencing a null pointer
--> lint_example.rs:7:13
|
7 | let x = *(0 as *const i32);
| ^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed
解释
解引用空指针并在访问(从其加载或向其存储)时会导致 未定义行为。
double-negations
double_negations
Lint 检测形如 --x
的表达式。
示例
fn main() {
let x = 1;
let _b = --x;
}
这将产生
warning: use of a double negation
--> lint_example.rs:3:14
|
3 | let _b = --x;
| ^^^
|
= note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages
= note: use `-= 1` if you meant to decrement the value
= note: `#[warn(double_negations)]` on by default
help: add parentheses for clarity
|
3 | let _b = -(-x);
| + +
解释
对某物取负两次通常等于根本不取负。然而,Rust 中的双重取负很容易与许多源自 C 的语言中存在的前缀递减运算符混淆。如果您确实想对值取负两次,请使用 -(-x)
。
要递减一个值,请改用 x -= 1
。
drop-bounds
drop_bounds
Lint 检查泛型中以 std::ops::Drop
作为界限的情况。
示例
fn foo<T: Drop>() {}
这将产生
warning: bounds on `T: Drop` are most likely incorrect, consider instead using `std::mem::needs_drop` to detect whether a type can be trivially dropped
--> lint_example.rs:2:11
|
2 | fn foo<T: Drop>() {}
| ^^^^
|
= note: `#[warn(drop_bounds)]` on by default
解释
形如 T: Drop
的泛型 trait 界限很可能是误导性的,并非程序员的本意(他们可能应该改用 std::mem::needs_drop
)。
Drop
界限实际上并不表示类型是否可以轻易丢弃,因为包含 Drop
类型的复合类型本身不一定实现 Drop
。天真地,人们可能会尝试编写一个实现,该实现假设类型可以轻易丢弃,同时也为 T: Drop
提供了一个实际调用析构器的特化。然而,当 T
是 String
时,这就会失效,String
本身不实现 Drop
,但包含一个实现 Drop
的 Vec
,因此假设 T
可以轻易丢弃会导致内存泄漏。
此外,Drop
trait 仅包含一个方法 Drop::drop
,用户代码中不能显式调用它(E0040
),因此在 trait 界限中使用 Drop
实际上没有用例,除非是一些模糊的极端情况,可以使用 #[allow(drop_bounds)]
。
dropping-copy-types
dropping_copy_types
Lint 检查使用实现了 Copy trait 的值调用 std::mem::drop
的情况。
示例
let x: i32 = 42; // i32 implements Copy
std::mem::drop(x); // A copy of x is passed to the function, leaving the
// original unaffected
这将产生
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
--> lint_example.rs:3:1
|
3 | std::mem::drop(x); // A copy of x is passed to the function, leaving the
| ^^^^^^^^^^^^^^^-^
| |
| argument has type `i32`
|
= note: `#[warn(dropping_copy_types)]` on by default
help: use `let _ = ...` to ignore the expression or result
|
3 - std::mem::drop(x); // A copy of x is passed to the function, leaving the
3 + let _ = x; // A copy of x is passed to the function, leaving the
|
解释
调用 std::mem::drop
对于实现 Copy 的类型不起作用,因为值在调用时会被复制并移动到函数中。
dropping-references
dropping_references
Lint 检查使用引用而不是拥有值调用 std::mem::drop
的情况。
示例
fn operation_that_requires_mutex_to_be_unlocked() {} // just to make it compile
let mutex = std::sync::Mutex::new(1); // just to make it compile
let mut lock_guard = mutex.lock();
std::mem::drop(&lock_guard); // Should have been drop(lock_guard), mutex
// still locked
operation_that_requires_mutex_to_be_unlocked();
这将产生
warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
--> lint_example.rs:5:1
|
5 | std::mem::drop(&lock_guard); // Should have been drop(lock_guard), mutex
| ^^^^^^^^^^^^^^^-----------^
| |
| argument has type `&Result<MutexGuard<'_, i32>, PoisonError<MutexGuard<'_, i32>>>`
|
= note: `#[warn(dropping_references)]` on by default
help: use `let _ = ...` to ignore the expression or result
|
5 - std::mem::drop(&lock_guard); // Should have been drop(lock_guard), mutex
5 + let _ = &lock_guard; // Should have been drop(lock_guard), mutex
|
解释
在引用上调用 drop
只会丢弃引用本身,这是一个无操作。它不会在底层的被引用值上调用 drop
方法(来自 Drop
trait 实现),而这很可能是预期的行为。
duplicate-macro-attributes
duplicate_macro_attributes
Lint 检测当类似 #[test]
的内置宏属性在项上重复时的情况。此 Lint 可能在 bench
, cfg_eval
, test
和 test_case
上触发。
示例
#[test]
#[test]
fn foo() {}
这将产生
warning: duplicated attribute
--> src/lib.rs:2:1
|
2 | #[test]
| ^^^^^^^
|
= note: `#[warn(duplicate_macro_attributes)]` on by default
解释
重复的属性可能错误地源于复制粘贴,并且重复属性的效果可能不明显或不期望。
例如,将 #[test]
属性加倍会使测试注册运行两次,且其环境不变。
dyn-drop
dyn_drop
Lint 检查带有 std::ops::Drop
的 trait 对象。
示例
fn foo(_x: Box<dyn Drop>) {}
这将产生
warning: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped
--> lint_example.rs:2:20
|
2 | fn foo(_x: Box<dyn Drop>) {}
| ^^^^
|
= note: `#[warn(dyn_drop)]` on by default
解释
形如 dyn Drop
的 trait 对象界限很可能是误导性的,并非程序员的本意。
Drop
界限实际上并不表示类型是否可以轻易丢弃,因为包含 Drop
类型的复合类型本身不一定实现 Drop
。天真地,人们可能会尝试编写一个延迟丢弃系统,使用 dyn Drop
trait 对象将内存清理从延迟敏感的代码路径中分离出来。然而,当 T
是 String
时,这就会失效,String
不实现 Drop
,但可能应该被接受。
要编写接受任何类型的 trait 对象界限,请使用带有 blanket 实现的占位符 trait。
trait Placeholder {}
impl<T> Placeholder for T {}
fn foo(_x: Box<dyn Placeholder>) {}
elided-named-lifetimes
elided_named_lifetimes
Lint 检测当省略的生命周期最终成为命名生命周期时的情况,例如 'static
或某个生命周期参数 'a
。
示例
#![deny(elided_named_lifetimes)]
struct Foo;
impl Foo {
pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
unsafe { &mut *(x as *mut _) }
}
}
这将产生
error: elided lifetime has a name
--> lint_example.rs:5:50
|
5 | pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 {
| ^ this elided lifetime gets resolved as `'static`
|
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(elided_named_lifetimes)]
| ^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying it explicitly
|
5 | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
| +++++++
解释
生命周期省略非常有用,因为它使您无需为每个生命周期命名,但有时它会产生一些令人惊讶的解析。在安全代码中,这大多没问题,因为借用检查器阻止了任何不健全性,因此最坏的情况是在其他地方收到令人困惑的错误消息。但在 unsafe
代码中,这种意外的解析可能导致不健全代码。
ellipsis-inclusive-range-patterns
ellipsis_inclusive_range_patterns
Lint 检测已弃用的 ...
范围模式。
示例
let x = 123;
match x {
0...100 => {}
_ => {}
}
这将产生
warning: `...` range patterns are deprecated
--> lint_example.rs:4:6
|
4 | 0...100 => {}
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
解释
...
范围模式语法已更改为 ..=
,以避免与 ..
范围表达式 潜在混淆。请改用新形式。
exported-private-dependencies
exported_private_dependencies
Lint 检测在公共接口中暴露的私有依赖项。
示例
pub fn foo() -> Option<some_private_dependency::Thing> {
None
}
这将产生
warning: type `bar::Thing` from private dependency 'bar' in public interface
--> src/lib.rs:3:1
|
3 | pub fn foo() -> Option<bar::Thing> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(exported_private_dependencies)]` on by default
解释
依赖项可以标记为“私有”,表示它们未暴露在 crate 的公共接口中。Cargo 可以利用这一点独立解析这些依赖项,因为它假设无需将它们与使用同一依赖项的其他包统一。此 Lint 表示违反了该契约。
要修复此问题,请避免在公共接口中暴露该依赖项。或者,将依赖项切换为公共依赖项。
请注意,此功能仅在 nightly channel 上可用。有关更多详细信息,请参阅 RFC 1977,以及 Cargo 文档。
for-loops-over-fallibles
for_loops_over_fallibles
Lint 检查 for
循环遍历 Option
或 Result
值的情况。
示例
let opt = Some(1);
for x in opt { /* ... */}
这将产生
warning: for loop over an `Option`. This is more readably written as an `if let` statement
--> lint_example.rs:3:10
|
3 | for x in opt { /* ... */}
| ^^^
|
= note: `#[warn(for_loops_over_fallibles)]` on by default
help: to check pattern in a loop use `while let`
|
3 - for x in opt { /* ... */}
3 + while let Some(x) = opt { /* ... */}
|
help: consider using `if let` to clear intent
|
3 - for x in opt { /* ... */}
3 + if let Some(x) = opt { /* ... */}
|
解释
Option
和 Result
都实现了 IntoIterator
trait,这允许在 for
循环中使用它们。遍历 Option
或 Result
的 for
循环将迭代 0 次(如果值为 None
/Err(_)
)或 1 次(如果值为 Some(_)
/Ok(_)
)。这不是很实用,并且通过 if let
可以更清晰地表达。
for
循环也可能被错误地编写,目的是多次调用函数,而函数返回 Some(_)
,在这种情况下,应改用 while let
循环。
Option
和 Result
的 IntoIterator
实现的“预期”用途是将其传递给期望实现 IntoIterator
的泛型代码。例如,使用 .chain(option)
可选地向迭代器添加值。
forbidden-lint-groups
forbidden_lint_groups
Lint 检测应用于 Lint 组的 forbid
的违规行为。由于编译器中的一个 bug,这些以前完全被忽略了。现在它们会生成一个警告。
示例
#![forbid(warnings)]
#![warn(bad_style)]
fn main() {}
这将产生
warning: warn(bad_style) incompatible with previous forbid
--> lint_example.rs:2:9
|
1 | #![forbid(warnings)]
| -------- `forbid` level set here
2 | #![warn(bad_style)]
| ^^^^^^^^^ overruled by previous forbid
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
= note: `#[warn(forbidden_lint_groups)]` on by default
推荐的修复方法
如果您的 crate 使用 #![forbid(warnings)]
,我们建议您更改为 #![deny(warnings)]
。
解释
由于编译器 bug,以前将 forbid
应用于 Lint 组没有效果。该 bug 现已修复,但为了避免破坏现有 crate,我们没有强制执行 forbid
,而是发出了这个未来兼容性警告。
forgetting-copy-types
forgetting_copy_types
Lint 检查使用实现了 Copy trait 的值调用 std::mem::forget
的情况。
示例
let x: i32 = 42; // i32 implements Copy
std::mem::forget(x); // A copy of x is passed to the function, leaving the
// original unaffected
这将产生
warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
--> lint_example.rs:3:1
|
3 | std::mem::forget(x); // A copy of x is passed to the function, leaving the
| ^^^^^^^^^^^^^^^^^-^
| |
| argument has type `i32`
|
= note: `#[warn(forgetting_copy_types)]` on by default
help: use `let _ = ...` to ignore the expression or result
|
3 - std::mem::forget(x); // A copy of x is passed to the function, leaving the
3 + let _ = x; // A copy of x is passed to the function, leaving the
|
解释
调用 std::mem::forget
对于实现 Copy 的类型不起作用,因为值在调用时会被复制并移动到函数中。
另一种同样有效的解释是,Copy 类型不实现 Drop trait,这意味着它们没有析构器。没有析构器,std::mem::forget
就没有东西可以忽略。
forgetting-references
forgetting_references
Lint 检查使用引用而不是拥有值调用 std::mem::forget
的情况。
示例
let x = Box::new(1);
std::mem::forget(&x); // Should have been forget(x), x will still be dropped
这将产生
warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
--> lint_example.rs:3:1
|
3 | std::mem::forget(&x); // Should have been forget(x), x will still be dropped
| ^^^^^^^^^^^^^^^^^--^
| |
| argument has type `&Box<i32>`
|
= note: `#[warn(forgetting_references)]` on by default
help: use `let _ = ...` to ignore the expression or result
|
3 - std::mem::forget(&x); // Should have been forget(x), x will still be dropped
3 + let _ = &x; // Should have been forget(x), x will still be dropped
|
解释
在引用上调用 forget
只会遗忘引用本身,这是一个无操作。它不会遗忘底层的被引用值,而这很可能是预期的行为。
function-item-references
function_item_references
Lint 检测使用 fmt::Pointer
格式化或被 transmute 的函数引用。
示例
fn foo() { }
fn main() {
println!("{:p}", &foo);
}
这将产生
warning: taking a reference to a function item does not give a function pointer
--> lint_example.rs:4:22
|
4 | println!("{:p}", &foo);
| ^^^^ help: cast `foo` to obtain a function pointer: `foo as fn()`
|
= note: `#[warn(function_item_references)]` on by default
解释
获取函数的引用可能会被误认为是获取该函数指针的一种方式。这在将引用格式化为指针或 transmute 它时会产生意外结果。当函数引用被格式化为指针,作为受 fmt::Pointer
约束的参数传递,或被 transmute 时,就会发出此 Lint。
hidden-glob-reexports
hidden_glob_reexports
Lint 检测 glob 重导出项被私有项遮蔽的情况。
示例
#![deny(hidden_glob_reexports)]
pub mod upstream {
mod inner { pub struct Foo {}; pub struct Bar {}; }
pub use self::inner::*;
struct Foo {} // private item shadows `inner::Foo`
}
// mod downstream {
// fn test() {
// let _ = crate::upstream::Foo; // inaccessible
// }
// }
pub fn main() {}
这将产生
error: private item shadows public glob re-export
--> lint_example.rs:6:5
|
6 | struct Foo {} // private item shadows `inner::Foo`
| ^^^^^^^^^^^^^
|
note: the name `Foo` in the type namespace is supposed to be publicly re-exported here
--> lint_example.rs:5:13
|
5 | pub use self::inner::*;
| ^^^^^^^^^^^^^^
note: but the private item here shadows it
--> lint_example.rs:6:5
|
6 | struct Foo {} // private item shadows `inner::Foo`
| ^^^^^^^^^^^^^
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(hidden_glob_reexports)]
| ^^^^^^^^^^^^^^^^^^^^^
解释
这以前在没有任何错误或警告的情况下被接受,但这可能会悄悄地破坏 crate 的下游用户代码。如果添加了 struct Foo
,dep::inner::Foo
将会悄悄变得不可访问,并在下游使用处触发“struct
Foo is private
”可见性错误。
improper-ctypes
improper_ctypes
Lint 检测外部模块中类型使用不正确的情况。
示例
unsafe extern "C" {
static STATIC: String;
}
这将产生
warning: `extern` block uses type `String`, which is not FFI-safe
--> lint_example.rs:3:20
|
3 | static STATIC: String;
| ^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
= note: `#[warn(improper_ctypes)]` on by default
解释
编译器有几项检查来验证在 extern
块中使用的类型是安全的,并遵循某些规则以确保与外部接口的正确兼容性。当检测到定义中可能存在的错误时,就会发出此 Lint。此 Lint 通常应提供问题的描述,并可能提供如何解决问题的提示。
improper-ctypes-definitions
improper_ctypes_definitions
Lint 检测 extern
函数 定义使用不正确的情况。
示例
#![allow(unused)]
pub extern "C" fn str_type(p: &str) { }
这将产生
warning: `extern` fn uses type `str`, which is not FFI-safe
--> lint_example.rs:3:31
|
3 | pub extern "C" fn str_type(p: &str) { }
| ^^^^ not FFI-safe
|
= help: consider using `*const u8` and a length instead
= note: string slices have no C equivalent
= note: `#[warn(improper_ctypes_definitions)]` on by default
解释
在 extern
函数中可能指定许多与给定 ABI 不兼容的参数和返回类型。此 Lint 警告不应使用这些类型。此 Lint 通常应提供问题的描述,并可能提供如何解决问题的提示。
incomplete-features
incomplete_features
Lint 检测使用 feature
属性启用的不稳定特性,这些特性在某些或所有情况下可能无法正常工作。
示例
#![feature(generic_const_exprs)]
这将产生
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
--> lint_example.rs:1:12
|
1 | #![feature(generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
= note: `#[warn(incomplete_features)]` on by default
解释
尽管鼓励人们尝试不稳定特性,但已知其中一些特性是不完整的或有缺陷的。此 Lint 表明该特性尚未完成,您可能会遇到问题。
inline-no-sanitize
inline_no_sanitize
Lint 检测 #[inline(always)]
和 #[no_sanitize(...)]
的不兼容使用。
示例
#![feature(no_sanitize)]
#[inline(always)]
#[no_sanitize(address)]
fn x() {}
fn main() {
x()
}
这将产生
warning: `no_sanitize` will have no effect after inlining
--> lint_example.rs:4:1
|
4 | #[no_sanitize(address)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: inlining requested here
--> lint_example.rs:3:1
|
3 | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
= note: `#[warn(inline_no_sanitize)]` on by default
解释
使用 #[inline(always)]
属性会阻止 #[no_sanitize(...)]
属性工作。请考虑暂时移除 inline
属性。
internal-features
internal_features
Lint 检测使用 feature
属性启用的、编译器或标准库内部的不稳定特性。
示例
#![feature(rustc_attrs)]
这将产生
warning: the feature `rustc_attrs` is internal to the compiler or standard library
--> lint_example.rs:1:12
|
1 | #![feature(rustc_attrs)]
| ^^^^^^^^^^^
|
= note: using it is strongly discouraged
= note: `#[warn(internal_features)]` on by default
解释
这些特性是编译器和标准库的实现细节,不应在用户代码中使用。
invalid-from-utf8
invalid_from_utf8
Lint 检查使用已知的无效 UTF-8 值调用 std::str::from_utf8
和 std::str::from_utf8_mut
的情况。
示例
#[allow(unused)]
std::str::from_utf8(b"Ru\x82st");
这将产生
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
--> lint_example.rs:3:1
|
3 | std::str::from_utf8(b"Ru\x82st");
| ^^^^^^^^^^^^^^^^^^^^-----------^
| |
| the literal was valid UTF-8 up to the 2 bytes
|
= note: `#[warn(invalid_from_utf8)]` on by default
解释
根据 std::str::from_utf8
和 std::str::from_utf8_mut
的文档,尝试创建这样的 str
总是会返回错误。
invalid-macro-export-arguments
invalid_macro_export_arguments
Lint 检测 #[macro_export]
使用无效参数的情况。
示例
#![deny(invalid_macro_export_arguments)]
#[macro_export(invalid_parameter)]
macro_rules! myMacro {
() => {
// [...]
}
}
#[macro_export(too, many, items)]
这将产生
error: `invalid_parameter` isn't a valid `#[macro_export]` argument
--> lint_example.rs:4:16
|
4 | #[macro_export(invalid_parameter)]
| ^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(invalid_macro_export_arguments)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
解释
唯一有效的参数是 #[macro_export(local_inner_macros)]
或没有参数 (#[macro_export]
)。在 #[macro_export(..)]
中不能有多个参数,也不能提及 local_inner_macros
以外的参数。
invalid-nan-comparisons
invalid_nan_comparisons
Lint 检查与 f32::NAN
或 f64::NAN
作为操作数之一的比较。
示例
let a = 2.3f32;
if a == f32::NAN {}
这将产生
warning: incorrect NaN comparison, NaN cannot be directly compared to itself
--> lint_example.rs:3:4
|
3 | if a == f32::NAN {}
| ^^^^^^^^^^^^^
|
= note: `#[warn(invalid_nan_comparisons)]` on by default
help: use `f32::is_nan()` or `f64::is_nan()` instead
|
3 - if a == f32::NAN {}
3 + if a.is_nan() {}
|
解释
NaN 与任何东西(包括其自身)比较都没有意义,因此这些比较总是为 false。
invalid-value
invalid_value
Lint 检测创建无效值的情况,例如空引用。
示例
#![allow(unused)]
unsafe {
let x: &'static i32 = std::mem::zeroed();
}
这将产生
warning: the type `&i32` does not permit zero-initialization
--> lint_example.rs:4:27
|
4 | let x: &'static i32 = std::mem::zeroed();
| ^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= note: references must be non-null
= note: `#[warn(invalid_value)]` on by default
解释
在某些情况下,编译器可以检测到代码正在创建无效值,应避免这种情况。
特别地,此 Lint 将检查 mem::zeroed
、mem::uninitialized
、mem::transmute
和 MaybeUninit::assume_init
的不当使用,这些可能导致 未定义行为。此 Lint 应提供额外信息,指出问题所在和可能的解决方案。
irrefutable-let-patterns
irrefutable_let_patterns
Lint 检测 不可驳模式 在 if let
、while let
和 if let
守卫中的使用。
示例
if let _ = 123 {
println!("always runs!");
}
这将产生
warning: irrefutable `if let` pattern
--> lint_example.rs:2:4
|
2 | if let _ = 123 {
| ^^^^^^^^^^^
|
= note: this pattern will always match, so the `if let` is useless
= help: consider replacing the `if let` with a `let`
= note: `#[warn(irrefutable_let_patterns)]` on by default
解释
通常没有理由在 if let
或 while let
语句中使用不可驳模式,因为模式总是会成功匹配。使用 let
或 loop
语句即可。然而,在使用宏生成代码时,禁止不可驳模式需要在宏不知道模式是否可驳回的情况下进行尴尬的变通。此 Lint 允许宏接受这种形式,同时在普通代码中提醒可能的错误使用。
有关更多详细信息,请参阅 RFC 2086。
large-assignments
large_assignments
Lint 检测大型类型对象被移动的情况。
示例
let x = [0; 50000];
let y = x;
产生
warning: moving a large value
--> $DIR/move-large.rs:1:3
let y = x;
- Copied large value here
解释
在普通赋值或函数参数中使用大型类型时,惯用的代码可能效率低下。理想情况下,适当的优化会解决这个问题,但这些优化只尽力而为地完成。此 Lint 会在所有大型移动的位置触发,从而允许用户在代码中解决它们。
late-bound-lifetime-arguments
late_bound_lifetime_arguments
Lint 检测在具有后绑定生命周期参数的路径段中的泛型生命周期参数。
示例
struct S;
impl S {
fn late(self, _: &u8, _: &u8) {}
}
fn main() {
S.late::<'static>(&0, &0);
}
这将产生
warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
--> lint_example.rs:8:14
|
4 | fn late(self, _: &u8, _: &u8) {}
| - the late bound lifetime parameter is introduced here
...
8 | S.late::<'static>(&0, &0);
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
= note: `#[warn(late_bound_lifetime_arguments)]` on by default
解释
尚不清楚如何在同一列表中混合有早绑定和后绑定生命周期参数时为早绑定生命周期参数提供参数。目前,如果存在后绑定参数,提供任何显式参数都会触发此 Lint,这样将来可以采用解决方案而不会遇到向后兼容性问题。这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。有关更多详细信息以及早绑定和后绑定参数之间差异的描述,请参阅 issue #42868。
legacy-derive-helpers
legacy_derive_helpers
Lint 检测在引入之前使用的 derive 助手属性。
示例
#[serde(rename_all = "camelCase")]
#[derive(Deserialize)]
struct S { /* fields */ }
产生
warning: derive helper attribute is used before it is introduced
--> $DIR/legacy-derive-helpers.rs:1:3
|
1 | #[serde(rename_all = "camelCase")]
| ^^^^^
...
2 | #[derive(Deserialize)]
| ----------- the attribute is introduced here
解释
像这样的属性由于历史原因而有效,但属性展开通常按从左到右的顺序工作,因此,为了解析 #[serde]
,编译器必须尝试“展望未来”到尚未展开的项部分,但这种尝试并非总是可靠的。
要修复此警告,请将助手属性放在其对应的 derive 之后。
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct S { /* fields */ }
map-unit-fn
map_unit_fn
Lint 检查 Iterator::map
接收返回 ()
的可调用项的情况。
示例
fn foo(items: &mut Vec<u8>) {
items.sort();
}
fn main() {
let mut x: Vec<Vec<u8>> = vec![
vec![0, 2, 1],
vec![5, 4, 3],
];
x.iter_mut().map(foo);
}
这将产生
warning: `Iterator::map` call that discard the iterator's values
--> lint_example.rs:10:18
|
1 | fn foo(items: &mut Vec<u8>) {
| --------------------------- this function returns `()`, which is likely not what you wanted
...
10 | x.iter_mut().map(foo);
| ^^^^---^
| | |
| | called `Iterator::map` with callable that returns `()`
| after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
|
= note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
= note: `#[warn(map_unit_fn)]` on by default
help: you might have meant to use `Iterator::for_each`
|
10 - x.iter_mut().map(foo);
10 + x.iter_mut().for_each(foo);
|
解释
映射到 ()
几乎总是一个错误。
missing-abi
missing_abi
Lint 检测 extern
声明中省略 ABI 的情况。
示例
#![deny(missing_abi)]
extern fn foo() {}
这将产生
error: extern declarations without an explicit ABI are deprecated
--> lint_example.rs:4:1
|
4 | extern fn foo() {}
| ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"`
|
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(missing_abi)]
| ^^^^^^^^^^^
解释
出于历史原因,Rust 隐式选择 C
作为 extern
声明的默认 ABI。自那时以来,已经添加了 其他 ABI,如 C-unwind
和 system
,特别是随着它们的加入,容易看到 ABI 使代码审查更容易。
mixed-script-confusables
mixed_script_confusables
Lint 检测不同文字体系标识符中视觉上容易混淆的字符。
示例
// The Japanese katakana character エ can be confused with the Han character 工.
const エ: &'static str = "アイウ";
这将产生
warning: the usage of Script Group `Japanese, Katakana` in this crate consists solely of mixed script confusables
--> lint_example.rs:3:7
|
3 | const エ: &'static str = "アイウ";
| ^^
|
= note: the usage includes 'エ' (U+30A8)
= note: please recheck to make sure their usages are indeed what you want
= note: `#[warn(mixed_script_confusables)]` on by default
解释
当不同文字体系中的字符在视觉上可能看起来相似时,此 Lint 会发出警告,这可能导致混淆。
如果 crate 在同一文字体系中包含其他具有非可混淆字符的标识符,则此 Lint 不会发出。例如,如果上面给出的示例有另一个包含片假名字符的标识符(例如 let カタカナ = 123;
),则表明您有意使用片假名,并且不会对此发出警告。
请注意,可混淆字符集可能会随时间变化。请注意,如果您“禁止”此 Lint,现有代码将来可能会失败。
named-arguments-used-positionally
named_arguments_used_positionally
Lint 检测在格式字符串中命名参数仅按位置使用的情况。这种用法是有效的,但可能非常令人困惑。
示例
#![deny(named_arguments_used_positionally)]
fn main() {
let _x = 5;
println!("{}", _x = 1); // Prints 1, will trigger lint
println!("{}", _x); // Prints 5, no lint emitted
println!("{_x}", _x = _x); // Prints 5, no lint emitted
}
这将产生
error: named argument `_x` is not used by name
--> lint_example.rs:4:20
|
4 | println!("{}", _x = 1); // Prints 1, will trigger lint
| -- ^^ this named argument is referred to by position in formatting string
| |
| this formatting argument uses named argument `_x` by position
|
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(named_arguments_used_positionally)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use the named argument by name to avoid ambiguity
|
4 | println!("{_x}", _x = 1); // Prints 1, will trigger lint
| ++
解释
Rust 格式化字符串可以按位置引用命名参数,但这种用法可能令人困惑。特别是,读者可能会错误地认为命名参数的声明是一个赋值(这将产生 unit 类型)。为了向后兼容,这不是硬错误。
never-type-fallback-flowing-into-unsafe
never_type_fallback_flowing_into_unsafe
Lint 检测 never type fallback 影响 unsafe 函数调用的情况。
Never 类型回退
当编译器看到 !
类型的值时,它会隐式插入强制转换(如果可能),以允许类型检查推断出任何类型
// this
let x: u8 = panic!();
// is (essentially) turned by the compiler into
let x: u8 = absurd(panic!());
// where absurd is a function with the following signature
// (it's sound, because `!` always marks unreachable code):
fn absurd<T>(never: !) -> T { ... }
虽然在一个分支中使用非发散代码很方便(例如 if a { b } else { return }
),但这可能导致编译错误
// this
{ panic!() };
// gets turned into this
{ absurd(panic!()) }; // error: can't infer the type of `absurd`
为了防止此类错误,编译器会记住它在哪里插入了 absurd
调用,如果无法推断其类型,则将类型设置为 fallback。{ absurd::<Fallback>(panic!()) };
。这就是所谓的“never type fallback”。
示例
#![deny(never_type_fallback_flowing_into_unsafe)]
fn main() {
if true {
// return has type `!` which, is some cases, causes never type fallback
return
} else {
// `zeroed` is an unsafe function, which returns an unbounded type
unsafe { std::mem::zeroed() }
};
// depending on the fallback, `zeroed` may create `()` (which is completely sound),
// or `!` (which is instant undefined behavior)
}
这将产生
error: never type fallback affects this call to an `unsafe` function
--> lint_example.rs:8:18
|
8 | unsafe { std::mem::zeroed() }
| ^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(never_type_fallback_flowing_into_unsafe)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use `()` annotations to avoid fallback changes
|
8 | unsafe { std::mem::zeroed::<()>() }
| ++++++
解释
由于历史原因,never type fallback 是 ()
,这意味着 !
会自发地强制转换为 ()
。计划更改这一点,但这可能会导致上述代码不健全。与其依赖 fallback,不如明确指定类型
if true {
return
} else {
// type is explicitly specified, fallback can't hurt us no more
unsafe { std::mem::zeroed::<()>() }
};
有关更多详细信息,请参阅 Tracking Issue for making !
fall back to !
。
no-mangle-generic-items
no_mangle_generic_items
Lint 检测必须经过 mangling 的泛型项。
示例
#[unsafe(no_mangle)]
fn foo<T>(t: T) {}
这将产生
warning: functions generic over types or consts must be mangled
--> lint_example.rs:3:1
|
2 | #[unsafe(no_mangle)]
| -------------------- help: remove this attribute
3 | fn foo<T>(t: T) {}
| ^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(no_mangle_generic_items)]` on by default
解释
带有泛型的函数必须对其符号进行 mangling 以适应泛型参数。no_mangle
属性在这种情况下无效,应删除。
non-fmt-panic
Lint non-fmt-panic
已重命名为 non-fmt-panics
。
non-camel-case-types
non_camel_case_types
Lint 检测不使用驼峰命名法的类型、变体、trait 和类型参数。
示例
struct my_struct;
这将产生
warning: type `my_struct` should have an upper camel case name
--> lint_example.rs:2:8
|
2 | struct my_struct;
| ^^^^^^^^^ help: convert the identifier to upper camel case: `MyStruct`
|
= note: `#[warn(non_camel_case_types)]` on by default
解释
这些标识符的首选风格是使用“驼峰命名法”,例如 MyStruct
,其中首字母不应小写,且字母之间不应使用下划线。标识符的开头和结尾允许使用下划线,非字母之间也允许使用(例如 X86_64
)。
non-contiguous-range-endpoints
non_contiguous_range_endpoints
Lint 检测在使用排他性 范围模式时可能出现的差一错误。
示例
let x = 123u32;
match x {
0..100 => { println!("small"); }
101..1000 => { println!("large"); }
_ => { println!("larger"); }
}
这将产生
warning: multiple ranges are one apart
--> lint_example.rs:4:5
|
4 | 0..100 => { println!("small"); }
| ^^^^^^
| |
| this range doesn't match `100_u32` because `..` is an exclusive range
| help: use an inclusive range instead: `0_u32..=100_u32`
5 | 101..1000 => { println!("large"); }
| --------- this could appear to continue range `0_u32..100_u32`, but `100_u32` isn't matched by either of them
|
= note: `#[warn(non_contiguous_range_endpoints)]` on by default
解释
在 match 表达式中使用范围模式,并且漏掉一个数字,很可能是错误的。检查开始和结束值是否符合预期,并记住 ..=
右边界是包含的,而 ..
是排他的。
non-fmt-panics
non_fmt_panics
Lint 检测 panic!(..)
调用中第一个参数不是格式化字符串的情况。
示例
panic!("{}");
panic!(123);
这将产生
warning: panic message contains an unused formatting placeholder
--> lint_example.rs:2:9
|
2 | panic!("{}");
| ^^
|
= note: this message is not used as a format string when given without arguments, but will be in Rust 2021
= note: `#[warn(non_fmt_panics)]` on by default
help: add the missing argument
|
2 | panic!("{}", ...);
| +++++
help: or add a "{}" format string to use the message literally
|
2 | panic!("{}", "{}");
| +++++
warning: panic message is not a string literal
--> lint_example.rs:3:8
|
3 | panic!(123);
| ^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
3 | panic!("{}", 123);
| +++++
help: or use std::panic::panic_any instead
|
3 - panic!(123);
3 + std::panic::panic_any(123);
|
解释
在 Rust 2018 及更早版本中,panic!(x)
直接将 x
用作消息。这意味着 panic!("{}")
会使用消息 "{}"
触发 panic,而不是将其用作格式化字符串,而 panic!(123)
会使用 i32
作为消息触发 panic。
Rust 2021 总是将第一个参数解释为格式字符串。
non-local-definitions
non_local_definitions
Lint 检查在主体(函数、枚举判别式等)内部的 impl
块和 #[macro_export]
宏。
示例
#![warn(non_local_definitions)]
trait MyTrait {}
struct MyStruct;
fn foo() {
impl MyTrait for MyStruct {}
}
这将产生
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
--> lint_example.rs:7:5
|
6 | fn foo() {
| -------- move the `impl` block outside of this function `foo` and up 2 bodies
7 | impl MyTrait for MyStruct {}
| ^^^^^-------^^^^^--------
| | |
| | `MyStruct` is not local
| `MyTrait` is not local
|
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![warn(non_local_definitions)]
| ^^^^^^^^^^^^^^^^^^^^^
解释
创建非局部定义违背预期,并可能在工具中产生差异。应避免这种情况。在 2024 及更高版本中,它可能会默认为 deny,请参阅 tracking issue https://github.com/rust-lang/rust/issues/120363。
如果 impl
定义嵌套在某个项内部,并且类型和 trait 都不与 impl
块处于相同的嵌套级别,则它是非局部的。
所有嵌套的主体(函数、枚举判别式、数组长度、常量)(顶层模块中的 const _: Ty = { ... }
除外,这尚未决定)都会被检查。
non-shorthand-field-patterns
non_shorthand_field_patterns
Lint 检测在模式中使用 Struct { x: x }
而不是 Struct { x }
的情况。
示例
struct Point {
x: i32,
y: i32,
}
fn main() {
let p = Point {
x: 5,
y: 5,
};
match p {
Point { x: x, y: y } => (),
}
}
这将产生
warning: the `x:` in this pattern is redundant
--> lint_example.rs:14:17
|
14 | Point { x: x, y: y } => (),
| ^^^^ help: use shorthand field pattern: `x`
|
= note: `#[warn(non_shorthand_field_patterns)]` on by default
warning: the `y:` in this pattern is redundant
--> lint_example.rs:14:23
|
14 | Point { x: x, y: y } => (),
| ^^^^ help: use shorthand field pattern: `y`
解释
首选风格是,如果字段名和绑定名相同,则避免重复指定两者。
non-snake-case
non_snake_case
Lint 检测不使用蛇形命名法的变量、方法、函数、生命周期参数和模块。
示例
let MY_VALUE = 5;
这将产生
warning: variable `MY_VALUE` should have a snake case name
--> lint_example.rs:2:5
|
2 | let MY_VALUE = 5;
| ^^^^^^^^ help: convert the identifier to snake case: `my_value`
|
= note: `#[warn(non_snake_case)]` on by default
解释
这些标识符的首选风格是使用“蛇形命名法”,其中所有字符都小写,单词之间用单个下划线分隔,例如 my_value
。
non-upper-case-globals
non_upper_case_globals
Lint 检测不使用大写标识符的 static 项。
示例
static max_points: i32 = 5;
这将产生
warning: static variable `max_points` should have an upper case name
--> lint_example.rs:2:8
|
2 | static max_points: i32 = 5;
| ^^^^^^^^^^ help: convert the identifier to upper case: `MAX_POINTS`
|
= note: `#[warn(non_upper_case_globals)]` on by default
解释
static 项名称的首选风格是使用所有大写字母,例如 MAX_POINTS
。
noop-method-call
noop_method_call
Lint 检测对无操作方法的特定调用,例如在 T: !Clone
时调用 <&T as Clone>::clone
。
示例
#![allow(unused)]
struct Foo;
let foo = &Foo;
let clone: &Foo = foo.clone();
这将产生
warning: call to `.clone()` on a reference in this situation does nothing
--> lint_example.rs:5:22
|
5 | let clone: &Foo = foo.clone();
| ^^^^^^^^
|
= note: the type `Foo` does not implement `Clone`, so calling `clone` on `&Foo` copies the reference, which does not do anything and can be removed
= note: `#[warn(noop_method_call)]` on by default
help: remove this redundant call
|
5 - let clone: &Foo = foo.clone();
5 + let clone: &Foo = foo;
|
help: if you meant to clone `Foo`, implement `Clone` for it
|
3 + #[derive(Clone)]
4 | struct Foo;
|
解释
有些方法调用是无操作的,意味着它们不做任何事情。通常此类方法是由 blanket 实现产生的,这些实现恰好创建了一些最终什么也不做的方法调用。例如,Clone
在所有 &T
上实现,但在 T
未实现 clone 的 &T
上调用 clone
实际上什么也不做,因为引用是 copy 的。此 Lint 检测到这些调用并向用户发出警告。
opaque-hidden-inferred-bound
opaque_hidden_inferred_bound
Lint 检测关联类型界限中嵌套的 impl Trait
未被泛化到足以满足关联类型界限的情况。
解释
此功能在 #97346 中被移除,但随后在 #99860 中被回滚,因为它导致了回归。
我们计划将其重新引入作为硬错误,但在此期间,此 Lint 用于警告并建议依赖此行为的用例的修复方法。
示例
#![feature(type_alias_impl_trait)]
trait Duh {}
impl Duh for i32 {}
trait Trait {
type Assoc: Duh;
}
impl<F: Duh> Trait for F {
type Assoc = F;
}
type Tait = impl Sized;
#[define_opaque(Tait)]
fn test() -> impl Trait<Assoc = Tait> {
42
}
fn main() {}
这将产生
warning: opaque type `impl Trait<Assoc = Tait>` does not satisfy its associated type bounds
--> lint_example.rs:18:25
|
8 | type Assoc: Duh;
| --- this associated type bound is unsatisfied for `Tait`
...
18 | fn test() -> impl Trait<Assoc = Tait> {
| ^^^^^^^^^^^^
|
= note: `#[warn(opaque_hidden_inferred_bound)]` on by default
在此示例中,test
声明 impl Trait
的关联类型 Assoc
是 impl Sized
,这不满足关联类型上的界限 Duh
。
尽管隐藏类型 i32
确实满足此界限,但使用此 Lint,我们不认为返回类型是格式正确的。可以通过将 Tait = impl Sized
更改为 Tait = impl Sized + Duh
来修复。
out-of-scope-macro-calls
out_of_scope_macro_calls
Lint 检测在其定义上方、不在作用域内调用 macro_rules
的情况,这可能发生在键值属性中。
示例
#![doc = in_root!()]
macro_rules! in_root { () => { "" } }
fn main() {}
这将产生
warning: cannot find macro `in_root` in the current scope when looking from the crate root
--> lint_example.rs:1:10
|
1 | #![doc = in_root!()]
| ^^^^^^^ not found from the crate root
|
= 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 #124535 <https://github.com/rust-lang/rust/issues/124535>
= help: import `macro_rules` with `use` to make it callable above its definition
= note: `#[warn(out_of_scope_macro_calls)]` on by default
解释
macro_rules
项可见的作用域始于该项并向下延伸。这更类似于 let
而非其他项,其他项在其定义上方和下方都处于作用域内。由于一个 bug,macro_rules
意外地在其定义上方的一些键值属性中处于作用域内。此 Lint 捕捉到此类情况。要解决此问题,请通过 use
导入 macro_rules
,使其成为常规作用域项。
这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。
overlapping-patterns
Lint overlapping-patterns
已重命名为 overlapping-range-endpoints
。
overlapping-range-endpoints
overlapping_range_endpoints
Lint 检测 match
分支,其 范围模式 在其端点上重叠。
示例
let x = 123u8;
match x {
0..=100 => { println!("small"); }
100..=255 => { println!("large"); }
}
这将产生
warning: multiple patterns overlap on their endpoints
--> lint_example.rs:5:5
|
4 | 0..=100 => { println!("small"); }
| ------- this range overlaps on `100_u8`...
5 | 100..=255 => { println!("large"); }
| ^^^^^^^^^ ... with this range
|
= note: you likely meant to write mutually exclusive ranges
= note: `#[warn(overlapping_range_endpoints)]` on by default
解释
在 match 表达式中使用范围模式,并且以这种方式重叠,很可能是错误的。检查开始和结束值是否符合预期,并记住 ..=
左右边界都是包含的。
path-statements
path_statements
Lint 检测没有效果的路径语句。
示例
let x = 42;
x;
这将产生
warning: path statement with no effect
--> lint_example.rs:4:1
|
4 | x;
| ^^
|
= note: `#[warn(path_statements)]` on by default
解释
拥有没有效果的语句通常是一个错误。
private-bounds
private_bounds
Lint 检测项的次要接口中的类型,这些类型比项本身更私有。项的次要接口包括泛型参数的界限和 where 子句,以及 trait 项的 supertraits。
示例
#![allow(unused)]
#![deny(private_bounds)]
struct PrivTy;
pub struct S
where PrivTy:
{}
fn main() {}
这将产生
error: type `PrivTy` is more private than the item `S`
--> lint_example.rs:5:1
|
5 | pub struct S
| ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub`
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
--> lint_example.rs:4:1
|
4 | struct PrivTy;
| ^^^^^^^^^^^^^
note: the lint level is defined here
--> lint_example.rs:2:9
|
2 | #![deny(private_bounds)]
| ^^^^^^^^^^^^^^
解释
在项界限中使用私有类型或 trait 会使项实际提供的接口不那么清晰。
private-interfaces
private_interfaces
Lint 检测项的主要接口中的类型,这些类型比项本身更私有。项的主要接口是其所有接口,除了泛型参数的界限和 where 子句。
示例
#![allow(unused)]
#![deny(private_interfaces)]
struct SemiPriv;
mod m1 {
struct Priv;
impl crate::SemiPriv {
pub fn f(_: Priv) {}
}
}
fn main() {}
这将产生
error: type `Priv` is more private than the item `m1::<impl SemiPriv>::f`
--> lint_example.rs:8:9
|
8 | pub fn f(_: Priv) {}
| ^^^^^^^^^^^^^^^^^ associated function `m1::<impl SemiPriv>::f` is reachable at visibility `pub(crate)`
|
note: but type `Priv` is only usable at visibility `pub(self)`
--> lint_example.rs:6:5
|
6 | struct Priv;
| ^^^^^^^^^^^
note: the lint level is defined here
--> lint_example.rs:2:9
|
2 | #![deny(private_interfaces)]
| ^^^^^^^^^^^^^^^^^^
解释
在主要接口中包含私有内容保证了由于类型隐私,该项将无法从外部模块使用。
private-macro-use
private_macro_use
Lint 检测使用 #[macro_use]
导入的私有宏。
示例
// extern_macro.rs
macro_rules! foo_ { () => {}; }
use foo_ as foo;
// code.rs
#![deny(private_macro_use)]
#[macro_use]
extern crate extern_macro;
fn main() {
foo!();
}
这将产生
error: cannot find macro `foo` in this scope
解释
此 Lint 源于对外部 crate 中宏的可见性检查的疏忽。
这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。
ptr-to-integer-transmute-in-consts
ptr_to_integer_transmute_in_consts
Lint 检测 const 函数和关联常量中的指针到整数 transmute。
示例
const fn foo(ptr: *const u8) -> usize {
unsafe {
std::mem::transmute::<*const u8, usize>(ptr)
}
}
这将产生
warning: pointers cannot be transmuted to integers during const eval
--> lint_example.rs:4:8
|
4 | std::mem::transmute::<*const u8, usize>(ptr)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: at compile-time, pointers do not have an integer value
= note: avoiding this restriction via `union` or raw pointers leads to compile-time undefined behavior
= help: for more information, see https://doc.rust-lang.net.cn/std/mem/fn.transmute.html
= note: `#[warn(ptr_to_integer_transmute_in_consts)]` on by default
解释
在 const
上下文中将指针 transmute 为整数是未定义行为。任何使用结果整数的尝试都会中止常量求值。
但有时编译器可能不会对 const 函数和关联常量内部的指针到整数 transmute 发出错误,因为它们仅在被引用时才会被求值。因此,此 Lint 作为额外的防御层,防止任何未定义行为在没有任何警告或错误的情况下编译通过。
有关更多详细信息,请参阅参考手册中的 std::mem::transmute。
redundant-semicolon
Lint redundant-semicolon
已重命名为 redundant-semicolons
。
redundant-semicolons
redundant_semicolons
Lint 检测不必要的尾随分号。
示例
let _ = 123;;
这将产生
warning: unnecessary trailing semicolon
--> lint_example.rs:2:13
|
2 | let _ = 123;;
| ^ help: remove this semicolon
|
= note: `#[warn(redundant_semicolons)]` on by default
解释
不需要多余的分号,可以移除以避免混淆和视觉混乱。
refining-impl-trait-internal
refining_impl_trait_internal
Lint 检测方法签名中的 impl Trait
返回类型被 trait 实现精炼的情况,这意味着实现添加了 trait 中不存在的关于返回类型的信息。
示例
#![deny(refining_impl_trait)]
use std::fmt::Display;
trait AsDisplay {
fn as_display(&self) -> impl Display;
}
impl<'s> AsDisplay for &'s str {
fn as_display(&self) -> Self {
*self
}
}
fn main() {
// users can observe that the return type of
// `<&str as AsDisplay>::as_display()` is `&str`.
let _x: &str = "".as_display();
}
这将产生
error: impl trait in impl method signature does not match trait method signature
--> lint_example.rs:10:29
|
6 | fn as_display(&self) -> impl Display;
| ------------ return type from trait method defined here
...
10 | fn as_display(&self) -> Self {
| ^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[deny(refining_impl_trait_internal)]` implied by `#[deny(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
10 - fn as_display(&self) -> Self {
10 + fn as_display(&self) -> impl std::fmt::Display {
|
解释
已知实现类型的调用者能够观察到 impl 签名中编写的类型。这可能是预期行为,但也可能导致实现细节被无意中暴露。特别是,对于不希望对类型做出比 trait 签名中更强保证的库作者来说,这可能构成 semver 风险。
refining_impl_trait
是一个包含两个 Lint 的 Lint 组
refining_impl_trait_reachable
,用于在 crate 外部公共可访问的精炼,以及refining_impl_trait_internal
,用于仅在 crate 内部可见的精炼。
我们正在就这些 Lint 征求反馈意见;有关更多信息,请参阅 issue #121718。
refining-impl-trait-reachable
refining_impl_trait_reachable
Lint 检测方法签名中的 impl Trait
返回类型被公共可访问的 trait 实现精炼的情况,这意味着实现添加了 trait 中不存在的关于返回类型的信息。
示例
#![deny(refining_impl_trait)]
use std::fmt::Display;
pub trait AsDisplay {
fn as_display(&self) -> impl Display;
}
impl<'s> AsDisplay for &'s str {
fn as_display(&self) -> Self {
*self
}
}
fn main() {
// users can observe that the return type of
// `<&str as AsDisplay>::as_display()` is `&str`.
let _x: &str = "".as_display();
}
这将产生
error: impl trait in impl method signature does not match trait method signature
--> lint_example.rs:10:29
|
6 | fn as_display(&self) -> impl Display;
| ------------ return type from trait method defined here
...
10 | fn as_display(&self) -> Self {
| ^^^^
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(refining_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^
= note: `#[deny(refining_impl_trait_reachable)]` implied by `#[deny(refining_impl_trait)]`
help: replace the return type so that it matches the trait
|
10 - fn as_display(&self) -> Self {
10 + fn as_display(&self) -> impl std::fmt::Display {
|
解释
已知实现类型的调用者能够观察到 impl 签名中编写的类型。这可能是预期行为,但也可能导致实现细节被无意中暴露。特别是,对于不希望对类型做出比 trait 签名中更强保证的库作者来说,这可能构成 semver 风险。
refining_impl_trait
是一个包含两个 Lint 的 Lint 组
refining_impl_trait_reachable
,用于在 crate 外部公共可访问的精炼,以及refining_impl_trait_internal
,用于仅在 crate 内部可见的精炼。
我们正在就这些 Lint 征求反馈意见;有关更多信息,请参阅 issue #121718。
renamed-and-removed-lints
renamed_and_removed_lints
Lint 检测已重命名或移除的 Lint。
示例
#![deny(raw_pointer_derive)]
这将产生
warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
--> lint_example.rs:1:9
|
1 | #![deny(raw_pointer_derive)]
| ^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(renamed_and_removed_lints)]` on by default
解释
要修复此问题,请移除该 Lint 或使用新名称。这有助于避免对不再有效的 Lint 产生混淆,并有助于保持重命名 Lint 的一致性。
repr-transparent-external-private-fields
repr_transparent_external_private_fields
Lint 检测标记有 #[repr(transparent)]
的类型,这些类型(传递地)包含标记有 #[non_exhaustive]
或包含私有字段的外部 ZST 类型。
示例
#![deny(repr_transparent_external_private_fields)]
use foo::NonExhaustiveZst;
#[repr(transparent)]
struct Bar(u32, ([u32; 0], NonExhaustiveZst));
这将产生
error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
--> src/main.rs:5:28
|
5 | struct Bar(u32, ([u32; 0], NonExhaustiveZst));
| ^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> src/main.rs:1:9
|
1 | #![deny(repr_transparent_external_private_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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 #78586 <https://github.com/rust-lang/rust/issues/78586>
= note: this struct contains `NonExhaustiveZst`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future.
解释
以前,Rust 接受包含外部私有零大小类型的字段,尽管向该私有类型添加非零大小字段不应是破坏性更改。
这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。有关更多详细信息,请参阅 issue #78586。
self-constructor-from-outer-item
self_constructor_from_outer_item
Lint 检测解析器 bug 静默允许 Self
构造器的情况,这可能产生令人惊讶和意料之外的行为。
从未打算从外部项使用 Self
类型别名,但它被静默允许了。这已被弃用——当 Self
类型别名引用不在作用域内的泛型时,这是一个硬错误。
示例
#![deny(self_constructor_from_outer_item)]
struct S0(usize);
impl S0 {
fn foo() {
const C: S0 = Self(0);
fn bar() -> S0 {
Self(0)
}
}
}
这将产生
error: can't reference `Self` constructor from outer item
--> lint_example.rs:8:23
|
6 | impl S0 {
| ------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
7 | fn foo() {
8 | const C: S0 = Self(0);
| ^^^^ help: replace `Self` with the actual type: `S0`
|
= 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 #124186 <https://github.com/rust-lang/rust/issues/124186>
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(self_constructor_from_outer_item)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: can't reference `Self` constructor from outer item
--> lint_example.rs:10:13
|
6 | impl S0 {
| ------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
...
10 | Self(0)
| ^^^^ help: replace `Self` with the actual type: `S0`
|
= 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 #124186 <https://github.com/rust-lang/rust/issues/124186>
解释
Self
类型别名不应可访问,因为嵌套项不与父项参数的作用域相关联。
semicolon-in-expressions-from-macros
semicolon_in_expressions_from_macros
Lint 检测宏在表达式位置调用时宏体中尾随分号的情况。这以前是被接受的,但正在逐步淘汰。
示例
#![deny(semicolon_in_expressions_from_macros)]
macro_rules! foo {
() => { true; }
}
fn main() {
let val = match true {
true => false,
_ => foo!()
};
}
这将产生
error: trailing semicolon in macro used in expression position
--> lint_example.rs:3:17
|
3 | () => { true; }
| ^
...
9 | _ => foo!()
| ------ in this macro invocation
|
= 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 #79813 <https://github.com/rust-lang/rust/issues/79813>
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
解释
以前,当宏在表达式位置调用时,Rust 会忽略宏体中的尾随分号。然而,这使得语言中分号的处理不一致,并在某些情况下(例如,如果宏作者期望一个值被丢弃)可能导致意外的运行时行为。
这是一个 未来不兼容 的 Lint,用于将来将其转换为硬错误。有关更多详细信息,请参阅 issue #79813。
special-module-name
special_module_name
Lint 检测具有特殊含义的文件的模块声明。
示例
mod lib;
fn main() {
lib::run();
}
这将产生
warning: found module declaration for lib.rs
--> lint_example.rs:1:1
|
1 | mod lib;
| ^^^^^^^^
|
= note: lib.rs is the root of this crate's library target
= help: to refer to it from other targets, use the library's name as the path
= note: `#[warn(special_module_name)]` on by default
解释
Cargo 将 lib.rs
和 main.rs
识别为库或二进制 crate 的根文件,因此除非显式配置,否则将它们声明为模块将导致 crate 错误编译。
要从同一 crate 内的二进制目标访问库,请使用 your_crate_name::
作为路径,而不是 lib::
// bar/src/lib.rs
fn run() {
// ...
}
// bar/src/main.rs
fn main() {
bar::run();
}
二进制目标不能用作库,因此不允许将其声明为模块。
stable-features
stable_features
Lint 检测 feature
属性,该特性此后已稳定化。
示例
#![feature(test_accepted_feature)]
fn main() {}
这将产生
warning: the feature `test_accepted_feature` has been stable since 1.0.0 and no longer requires an attribute to enable
--> lint_example.rs:1:12
|
1 | #![feature(test_accepted_feature)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(stable_features)]` on by default
解释
当一个特性稳定后,不再需要包含 #![feature]
属性。要修复,只需删除 #![feature]
属性。
static-mut-ref
Lint static-mut-ref
已重命名为 static-mut-refs
。
static-mut-refs
static_mut_refs
Lint 检查在 unsafe
块和 unsafe
函数内部对可变 static 的共享或可变引用。
示例
fn main() {
static mut X: i32 = 23;
static mut Y: i32 = 24;
unsafe {
let y = &X;
let ref x = X;
let (x, y) = (&X, &Y);
foo(&X);
}
}
unsafe fn _foo() {
static mut X: i32 = 23;
static mut Y: i32 = 24;
let y = &X;
let ref x = X;
let (x, y) = (&X, &Y);
foo(&X);
}
fn foo<'a>(_x: &'a i32) {}
这将产生
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:6:17
|
6 | let y = &X;
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
|
6 | let y = &raw const X;
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:7:21
|
7 | let ref x = X;
| ^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:8:23
|
8 | let (x, y) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
8 | let (x, y) = (&raw const X, &Y);
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:8:27
|
8 | let (x, y) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
8 | let (x, y) = (&X, &raw const Y);
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:9:13
|
9 | foo(&X);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
9 | foo(&raw const X);
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:17:13
|
17 | let y = &X;
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
17 | let y = &raw const X;
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:18:17
|
18 | let ref x = X;
| ^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:19:19
|
19 | let (x, y) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
19 | let (x, y) = (&raw const X, &Y);
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:19:23
|
19 | let (x, y) = (&X, &Y);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
19 | let (x, y) = (&X, &raw const Y);
| +++++++++
warning: creating a shared reference to mutable static is discouraged
--> lint_example.rs:20:9
|
20 | foo(&X);
| ^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.net.cn/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
20 | foo(&raw const X);
| +++++++++
解释
对可变 static 的共享或可变引用几乎总是一个错误,并可能导致未定义行为和代码中的各种其他问题。
此 Lint 在 2021 年及更早版本中默认为“warn”,在 2024 年默认为“deny”。
suspicious-double-ref-op
suspicious_double_ref_op
Lint 检查在 T: !Deref/Borrow/Clone
时在 &&T
上使用 .clone()
/.borrow()
/.deref()
的情况,这意味着调用将返回内部的 &T
,而不是对底层的 T
执行操作,这可能会令人困惑。
示例
#![allow(unused)]
struct Foo;
let foo = &&Foo;
let clone: &Foo = foo.clone();
这将产生
warning: using `.clone()` on a double reference, which returns `&Foo` instead of cloning the inner type
--> lint_example.rs:5:22
|
5 | let clone: &Foo = foo.clone();
| ^^^^^^^^
|
= note: `#[warn(suspicious_double_ref_op)]` on by default
解释
由于 Foo
没有实现 Clone
,运行 .clone()
只会解引用双重引用,而不是克隆内部类型,而克隆内部类型才是预期的行为。
trivial-bounds
trivial_bounds
Lint 检测不依赖于任何类型参数的 trait 界限。
示例
#![feature(trivial_bounds)]
pub struct A where i32: Copy;
这将产生
warning: trait bound i32: Copy does not depend on any type or lifetime parameters
--> lint_example.rs:3:25
|
3 | pub struct A where i32: Copy;
| ^^^^
|
= note: `#[warn(trivial_bounds)]` on by default
解释
通常您不会编写您已知总是为真或从不为真的 trait 界限。然而,在使用宏时,宏在生成代码时可能不知道约束是否成立。目前,如果约束总是为真,编译器不会警告您;如果约束从不为真,则会生成错误。trivial_bounds
特性将这种情况更改为在这两种情况下都发出警告,使宏在生成代码时拥有更大的自由和灵活性,同时在编写非宏代码时仍然提供信号,表明出现了问题。
有关更多详细信息,请参阅 RFC 2056。此特性目前仅在 nightly channel 上可用,请参阅 tracking issue #48214。
type-alias-bounds
type_alias_bounds
Lint 检测类型别名中的界限。
示例
type SendVec<T: Send> = Vec<T>;
这将产生
warning: bounds on generic parameters in type aliases are not enforced
--> lint_example.rs:2:17
|
2 | type SendVec<T: Send> = Vec<T>;
| --^^^^
| | |
| | will not be checked at usage sites of the type alias
| help: remove this bound
|
= note: this is a known limitation of the type checker that may be lifted in a future edition.
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics
= note: `#[warn(type_alias_bounds)]` on by default
解释
类型别名中泛型参数和 where 子句上的 trait 和生命周期界限在类型别名的使用处不被检查。此外,在定义处也未像别名类型那样彻底检查其正确性。
这是类型检查器的一个已知限制,可能在将来的版本中解除。鉴于此,允许此类界限是无意的。
虽然这些界限可能产生次要影响,例如启用“简写”关联类型路径的使用1 以及影响传递给类型别名的 trait 对象类型的默认 trait 对象生命周期2,但在上述类型检查器限制解除之前,不应允许这样做。
强烈不建议使用此类界限,因为它们具有误导性。
即,形如 T::Assoc
的路径,其中 T
是受 trait Trait
约束的类型参数,该 trait 定义了一个名为 Assoc
的关联类型,这与完全限定路径形如 <T as Trait>::Assoc
不同。
tyvar-behind-raw-pointer
tyvar_behind_raw_pointer
Lint 检测指向推理变量的原始指针。
示例
// edition 2015
let data = std::ptr::null();
let _ = &data as *const *const ();
if data.is_null() {}
这将产生
warning: type annotations needed
--> lint_example.rs:6:9
|
6 | if data.is_null() {}
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
= note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906>
= note: `#[warn(tyvar_behind_raw_pointer)]` on by default
解释
以前允许这种推理,但随着 任意 self 类型 的未来到来,这可能引入歧义。要解决此问题,请使用显式类型而不是依赖类型推理。
这是一个 未来不兼容 的 Lint,用于在 2018 版中将其转换为硬错误。有关更多详细信息,请参阅 issue #46906。这在 2018 版中目前是硬错误,在 2015 版中默认为“warn”。
uncommon-codepoints
uncommon_codepoints
Lint 检测标识符中的不常见 Unicode 码点。
示例
#![allow(unused)]
const µ: f64 = 0.000001;
这将产生
warning: identifier contains a non normalized (NFKC) character: 'µ'
--> lint_example.rs:3:7
|
3 | const µ: f64 = 0.000001;
| ^
|
= note: this character is included in the Not_NFKC Unicode general security profile
= note: `#[warn(uncommon_codepoints)]` on by default
解释
此 Lint 警告使用不常用字符,这可能导致视觉混淆。
此 Lint 由包含不属于Unicode® 技术标准 #39 Unicode 安全机制 第 3.1 节 标识符通用安全配置文件所述的“允许”码点集的码点的标识符触发。
请注意,不常见码点集可能会随时间变化。请注意,如果您“禁止”此 Lint,现有代码将来可能会失败。
unconditional-recursion
unconditional_recursion
Lint 检测无法在不调用自身的情况下返回的函数。
示例
fn foo() {
foo();
}
这将产生
warning: function cannot return without recursing
--> lint_example.rs:2:1
|
2 | fn foo() {
| ^^^^^^^^ cannot return without recursing
3 | foo();
| ----- recursive call site
|
= help: a `loop` may express intention better if this is on purpose
= note: `#[warn(unconditional_recursion)]` on by default
解释
递归调用通常应有某种终止条件,没有终止条件的递归通常是错误的。如果您确实想要一个无限循环,建议使用 loop
表达式。
uncovered-param-in-projection
uncovered_param_in_projection
Lint 检测 Rust 的孤儿规则之一的违规行为,该规则涉及在外部 trait 实现中使用类型参数在 trait 关联类型路径(“投影”)内部,其输出可能不是被错误地认为是“覆盖”所述参数的本地类型,这是不健全的,未来的编译器版本可能会拒绝这种行为。
最初在 #99554 中报告。
示例
// dependency.rs
#![crate_type = "lib"]
pub trait Trait<T, U> {}
// dependent.rs
trait Identity {
type Output;
}
impl<T> Identity for T {
type Output = T;
}
struct Local;
impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
fn main() {}
这将产生
warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
--> dependent.rs:11:6
|
11 | impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
|
= 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 #124559 <https://github.com/rust-lang/rust/issues/124559>
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
= note: `#[warn(uncovered_param_in_projection)]` on by default
解释
FIXME(fmease): 编写解释。
undefined-naked-function-abi
undefined_naked_function_abi
Lint 检测未指定 ABI 或指定 Rust ABI 的 naked 函数定义。
示例
#![feature(asm_experimental_arch, naked_functions)]
use std::arch::naked_asm;
#[naked]
pub fn default_abi() -> u32 {
unsafe { naked_asm!(""); }
}
#[naked]
pub extern "Rust" fn rust_abi() -> u32 {
unsafe { naked_asm!(""); }
}
这将产生
warning: Rust ABI is unsupported in naked functions
--> lint_example.rs:7:1
|
7 | pub fn default_abi() -> u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(undefined_naked_function_abi)]` on by default
warning: Rust ABI is unsupported in naked functions
--> lint_example.rs:12:1
|
12 | pub extern "Rust" fn rust_abi() -> u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
解释
Rust ABI 目前未定义。因此,naked 函数应指定非 Rust ABI。
unexpected-cfgs
unexpected_cfgs
Lint 检测意外的条件编译条件。
示例
rustc --check-cfg 'cfg()'
#[cfg(widnows)]
fn foo() {}
这将产生
warning: unexpected `cfg` condition name: `widnows`
--> lint_example.rs:1:7
|
1 | #[cfg(widnows)]
| ^^^^^^^
|
= note: `#[warn(unexpected_cfgs)]` on by default
解释
此 Lint 仅在将 --check-cfg
参数传递给编译器时才处于活动状态,并在使用意外条件名称或值时触发。
有关更多详细信息,请参阅 检查条件配置 部分。
有关在 Cargo.toml
中配置此 Lint 的信息,请参阅 Cargo 特定性 部分。
unfulfilled-lint-expectations
unfulfilled_lint_expectations
Lint 检测 Lint 期望未被满足的情况。
示例
#[expect(unused_variables)]
let x = 10;
println!("{}", x);
这将产生
warning: this lint expectation is unfulfilled
--> lint_example.rs:2:10
|
2 | #[expect(unused_variables)]
| ^^^^^^^^^^^^^^^^
|
= note: `#[warn(unfulfilled_lint_expectations)]` on by default
解释
#[expect]
属性可用于创建 Lint 期望。如果在同一位置使用 #[warn]
属性会导致 Lint 发出,则该期望被满足。如果由于没有发出 Lint 而未满足期望,则此 Lint 将在该属性上发出。
ungated-async-fn-track-caller
ungated_async_fn_track_caller
Lint 警告在 async 函数上使用 #[track_caller]
属性但未启用相应不稳定特性标志的情况。
示例
#[track_caller]
async fn foo() {}
这将产生
warning: `#[track_caller]` on async functions is a no-op
--> lint_example.rs:2:1
|
2 | #[track_caller]
| ^^^^^^^^^^^^^^^
3 | async fn foo() {}
| ----------------- this function will not propagate the caller location
|
= note: see issue #110011 <https://github.com/rust-lang/rust/issues/110011> for more information
= help: add `#![feature(async_fn_track_caller)]` to the crate attributes to enable
= note: this compiler was built on 2025-05-09; consider upgrading it if it is out of date
= note: `#[warn(ungated_async_fn_track_caller)]` on by default
解释
该属性必须与 async_fn_track_caller
特性标志结合使用。否则,#[track_caller]
注解将作为无操作。
uninhabited-static
uninhabited_static
Lint 检测不可居住的 static。
示例
enum Void {}
unsafe extern {
static EXTERN: Void;
}
这将产生
warning: static of uninhabited type
--> lint_example.rs:4:5
|
4 | static EXTERN: Void;
| ^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
= note: uninhabited statics cannot be initialized, and any access would be an immediate error
= note: `#[warn(uninhabited_static)]` on by default
解释
具有不可居住类型的 static 永远无法初始化,因此无法定义。然而,这可以通过 extern static
绕过,导致编译器后期出现问题,因为编译器假设没有已初始化的不可居住位置(例如局部变量或 static)。这是意外被允许的,但正在逐步淘汰。
unknown-lints
unknown_lints
Lint 检测无法识别的 lint 属性。
示例
#![allow(not_a_real_lint)]
这将产生
warning: unknown lint: `not_a_real_lint`
--> lint_example.rs:1:10
|
1 | #![allow(not_a_real_lint)]
| ^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_lints)]` on by default
解释
指定不存在的 Lint 通常是一个错误。检查拼写,并查看 Lint 列表以获取正确的名称。此外,考虑您是否使用了旧版本的编译器,并且该 Lint 仅在新版本中可用。
unknown-or-malformed-diagnostic-attributes
unknown_or_malformed_diagnostic_attributes
Lint 检测无法识别或格式不正确的诊断属性。
示例
#![feature(diagnostic_namespace)]
#[diagnostic::does_not_exist]
struct Foo;
这将产生
warning: unknown diagnostic attribute
--> lint_example.rs:3:15
|
3 | #[diagnostic::does_not_exist]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
解释
指定不存在的诊断属性通常是一个错误。检查拼写,并查看诊断属性列表以获取正确的名称。此外,考虑您是否使用了旧版本的编译器,并且该属性仅在新版本中可用。
unnameable-test-items
unnameable_test_items
Lint 检测无法被测试工具运行的 #[test]
函数,因为它们位于不可命名的位置。
示例
fn main() {
#[test]
fn foo() {
// This test will not fail because it does not run.
assert_eq!(1, 2);
}
}
这将产生
warning: cannot test inner items
--> lint_example.rs:2:5
|
2 | #[test]
| ^^^^^^^
|
= note: `#[warn(unnameable_test_items)]` on by default
解释
为了让测试工具运行测试,测试函数必须位于可以从 crate 根访问的位置。这通常意味着它必须定义在模块中,而不是其他任何地方,例如在另一个函数内部。编译器以前允许这种情况而没有错误,因此添加了一个 Lint 来提醒测试未被使用。是否应该允许这样做尚未决定,请参阅 RFC 2471 和 issue #36629。
unpredictable-function-pointer-comparisons
unpredictable_function_pointer_comparisons
Lint 检查以函数指针作为操作数的比较。
示例
fn a() {}
fn b() {}
let f: fn() = a;
let g: fn() = b;
let _ = f == g;
这将产生
warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> lint_example.rs:8:9
|
8 | let _ = f == g;
| ^^^^^^
|
= note: the address of the same function can vary between different codegen units
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.net.cn/nightly/core/ptr/fn.fn_addr_eq.html>
= note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default
help: refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint
|
8 - let _ = f == g;
8 + let _ = std::ptr::fn_addr_eq(f, g);
|
解释
函数指针比较不会产生有意义的结果,因为它们从未保证是唯一的,并且在不同的代码生成单元之间可能有所不同。此外,不同函数在合并后可能具有相同的地址。
unreachable-code
unreachable_code
Lint 检测不可达的代码路径。
示例
panic!("we never go past here!");
let x = 5;
这将产生
warning: unreachable statement
--> lint_example.rs:4:1
|
2 | panic!("we never go past here!");
| -------------------------------- any code following this expression is unreachable
3 |
4 | let x = 5;
| ^^^^^^^^^^ unreachable statement
|
= note: `#[warn(unreachable_code)]` on by default
解释
不可达代码可能表示错误或未完成的代码。如果代码不再使用,请考虑将其移除。
unreachable-patterns
unreachable_patterns
Lint 检测不可达的模式。
示例
let x = 5;
match x {
y => (),
5 => (),
}
这将产生
warning: unreachable pattern
--> lint_example.rs:5:5
|
4 | y => (),
| - matches any value
5 | 5 => (),
| ^ no value can reach this
|
= note: `#[warn(unreachable_patterns)]` on by default
解释
这通常表明模式的指定或顺序有误。在此示例中,y
模式将始终匹配,因此五是无法达到的。记住,match 分支按顺序匹配,您可能想要将 5
的情况放在 y
的情况之上。
unstable-name-collision
Lint unstable-name-collision
已重命名为 unstable-name-collisions
。
unstable-name-collisions
unstable_name_collisions
Lint 检测您使用了标准库计划将来添加的名称。
示例
trait MyIterator : Iterator {
// is_partitioned is an unstable method that already exists on the Iterator trait
fn is_partitioned<P>(self, predicate: P) -> bool
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
{true}
}
impl<T: ?Sized> MyIterator for T where T: Iterator { }
let x = vec![1, 2, 3];
let _ = x.iter().is_partitioned(|_| true);
这将产生
warning: a method with this name may be added to the standard library in the future
--> lint_example.rs:14:18
|
14 | let _ = x.iter().is_partitioned(|_| true);
| ^^^^^^^^^^^^^^
|
= warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
= note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
= help: call with fully qualified syntax `MyIterator::is_partitioned(...)` to keep using the current method
= note: `#[warn(unstable_name_collisions)]` on by default
help: add `#![feature(iter_is_partitioned)]` to the crate attributes to enable `is_partitioned`
|
1 + #![feature(iter_is_partitioned)]
|
解释
当新方法添加到标准库中的 trait 时,它们通常以“不稳定”的形式添加,仅在带有 nightly channel 和 feature
属性的版本中可用。如果任何现有代码扩展了某个 trait 以具有同名方法,则名称会冲突。将来,当该方法稳定后,这将由于歧义而导致错误。此 Lint 是一个早期警告,让您知道将来可能发生冲突。可以通过添加类型注解来消除您打算调用哪个 trait 方法的歧义,例如 MyIterator::is_partitioned(my_iter, my_predicate)
或重命名或删除该方法,来避免这种情况。
unstable-syntax-pre-expansion
unstable_syntax_pre_expansion
Lint 检测在属性展开期间被丢弃的不稳定语法的使用。
示例
#[cfg(FALSE)]
macro foo() {}
这将产生
warning: `macro` is experimental
--> lint_example.rs:3:1
|
3 | macro foo() {}
| ^^^^^^^^^^^^^^
|
= note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
= help: add `#![feature(decl_macro)]` to the crate attributes to enable
= note: this compiler was built on 2025-05-09; consider upgrading it if it is out of date
= warning: unstable syntax can change at any point in the future, causing a hard error!
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
解释
活跃属性(如 #[cfg]
或过程宏属性)的输入必须是有效的语法。之前,编译器只在解析 #[cfg]
门控和展开过程宏之后才限制不稳定语法特性的使用。
为了避免依赖不稳定语法,请将不稳定语法的用法移到编译器不会解析语法的位置,例如函数式宏。
#![deny(unstable_syntax_pre_expansion)]
macro_rules! identity {
( $($tokens:tt)* ) => { $($tokens)* }
}
#[cfg(FALSE)]
identity! {
macro foo() {}
}
这是一个未来不兼容的 lint,旨在未来将其过渡为硬错误。有关更多详细信息,请参阅issue #65860。
unsupported-fn-ptr-calling-conventions
当在不支持特定目标调用约定的目标上使用函数指针上的目标依赖调用约定时,就会输出 unsupported_fn_ptr_calling_conventions
lint。
例如,stdcall
对于 x86_64 或更明显地对于 powerpc 代码意义不大,因为从未为这些目标指定此调用约定。
示例
fn stdcall_ptr(f: extern "stdcall" fn ()) {
f()
}
这将产生
warning: the calling convention `"stdcall"` is not supported on this target
--> $DIR/unsupported.rs:34:15
|
LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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 #130260 <https://github.com/rust-lang/rust/issues/130260>
= note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
解释
在大多数目标上,stdcall
及类似调用约定的行为根本没有定义,但之前由于编译器实现中的一个错误而被接受。
unused-doc-comment
lint unused-doc-comment
已重命名为 unused-doc-comments
。
unused-tuple-struct-fields
lint unused-tuple-struct-fields
已重命名为 dead-code
。
unused-allocation
unused_allocation
lint 检测可以消除的不必要的分配。
示例
fn main() {
let a = Box::new([1, 2, 3]).len();
}
这将产生
warning: unnecessary allocation, use `&` instead
--> lint_example.rs:2:13
|
2 | let a = Box::new([1, 2, 3]).len();
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_allocation)]` on by default
解释
当 box
表达式立即被强制转换为引用时,分配是不必要的,此时应使用引用(使用 &
或 &mut
)来代替以避免分配。
unused-assignments
unused_assignments
lint 检测永远不会被读取的赋值。
示例
let mut x = 5;
x = 6;
这将产生
warning: value assigned to `x` is never read
--> lint_example.rs:3:1
|
3 | x = 6;
| ^
|
= help: maybe it is overwritten before being read?
= note: `#[warn(unused_assignments)]` on by default
解释
未使用的赋值可能表示错误或未完成的代码。如果在赋值后从未使用过该变量,则可以删除该赋值。带有下划线前缀的变量,例如 _x
,不会触发此 lint。
unused-associated-type-bounds
当向 trait 对象添加关联类型边界,但该关联类型具有 where Self: Sized
边界,从而无论如何都无法在 trait 对象上使用时,就会发出 unused_associated_type_bounds
lint。
示例
trait Foo {
type Bar where Self: Sized;
}
type Mop = dyn Foo<Bar = ()>;
这将产生
warning: unnecessary associated type bound for dyn-incompatible associated type
--> lint_example.rs:5:20
|
5 | type Mop = dyn Foo<Bar = ()>;
| ^^^^^^^^ help: remove this bound
|
= note: this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
= note: `#[warn(unused_associated_type_bounds)]` on by default
解释
正如具有 Self: Sized
边界的方法在 trait 对象上不可用一样,关联类型也可以从 trait 对象中移除。
unused-attributes
unused_attributes
lint 检测编译器未使用的属性。
示例
#![ignore]
这将产生
warning: `#[ignore]` only has an effect on functions
--> lint_example.rs:1:1
|
1 | #![ignore]
| ^^^^^^^^^^
|
= note: `#[warn(unused_attributes)]` on by default
解释
未使用的属性可能表明属性放置位置错误。考虑删除它,或将其放在正确的位置。还要考虑您是否打算使用 内联属性(带有 !
,例如 #![allow(unused)]
),它应用于属性所在的项;或者使用 外联属性(不带 !
,例如 #[allow(unused)]
),它应用于属性 后面 的项。
unused-braces
unused_braces
lint 检测表达式周围不必要的大括号。
示例
if { true } {
// ...
}
这将产生
warning: unnecessary braces around `if` condition
--> lint_example.rs:2:4
|
2 | if { true } {
| ^^ ^^
|
= note: `#[warn(unused_braces)]` on by default
help: remove these braces
|
2 - if { true } {
2 + if true {
|
解释
大括号是不需要的,应该删除。这是编写这些表达式的首选风格。
unused-comparisons
unused_comparisons
lint 检测因所涉及类型的限制而变得无用的比较。
示例
fn foo(x: u8) {
x >= 0;
}
这将产生
warning: comparison is useless due to type limits
--> lint_example.rs:3:5
|
3 | x >= 0;
| ^^^^^^
|
= note: `#[warn(unused_comparisons)]` on by default
解释
无用的比较可能表示错误,应予以修复或删除。
unused-doc-comments
unused_doc_comments
lint 检测未被 rustdoc
使用的文档注释。
示例
/// docs for x
let x = 12;
这将产生
warning: unused doc comment
--> lint_example.rs:2:1
|
2 | /// docs for x
| ^^^^^^^^^^^^^^
3 | let x = 12;
| ----------- rustdoc does not generate documentation for statements
|
= help: use `//` for a plain comment
= note: `#[warn(unused_doc_comments)]` on by default
解释
rustdoc
并非在所有位置都使用文档注释,因此文档注释将被忽略。尝试将其更改为普通的行注释(使用 //
)以避免警告。
unused-features
unused_features
lint 检测在 crate 级别的feature
属性中发现的未使用或未知特性。
注意:此 lint 当前不工作,有关更多详细信息,请参阅issue #44232。
unused-imports
unused_imports
lint 检测从未使用过的导入。
示例
use std::collections::HashMap;
这将产生
warning: unused import: `std::collections::HashMap`
--> lint_example.rs:2:5
|
2 | use std::collections::HashMap;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
解释
未使用的导入可能表示错误或未完成的代码,并且会使代码变得混乱,应予以删除。如果您打算重新导出该项以使其在模块外部可用,请添加可见性修饰符,例如 pub
。
unused-labels
unused_labels
lint 检测从未使用过的标签。
示例
'unused_label: loop {}
这将产生
warning: unused label
--> lint_example.rs:2:1
|
2 | 'unused_label: loop {}
| ^^^^^^^^^^^^^
|
= note: `#[warn(unused_labels)]` on by default
解释
未使用的标签可能表示错误或未完成的代码。要忽略单个标签的警告,请在该标签前加上下划线,例如 '_my_label:
。
unused-macros
unused_macros
lint 检测未使用的宏。
请注意,此 lint 与 unused_macro_rules
lint 不同,后者检查在一个已使用的宏中,从未匹配从而从未展开的单个规则。
示例
macro_rules! unused {
() => {};
}
fn main() {
}
这将产生
warning: unused macro definition: `unused`
--> lint_example.rs:1:14
|
1 | macro_rules! unused {
| ^^^^^^
|
= note: `#[warn(unused_macros)]` on by default
解释
未使用的宏可能表示错误或未完成的代码。要忽略单个宏的警告,请在该宏名称前加上下划线,例如 _my_macro
。如果您打算导出该宏以使其在 crate 外部可用,请使用macro_export
属性。
unused-must-use
unused_must_use
lint 检测被标记为 #[must_use]
的类型中未使用的结果。
示例
fn returns_result() -> Result<(), ()> {
Ok(())
}
fn main() {
returns_result();
}
这将产生
warning: unused `Result` that must be used
--> lint_example.rs:6:5
|
6 | returns_result();
| ^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
|
6 | let _ = returns_result();
| +++++++
解释
#[must_use]
属性表示忽略该值是错误的。有关更多详细信息,请参阅参考文档。
unused-mut
unused_mut
lint 检测不需要可变的 mut 变量。
示例
let mut x = 5;
这将产生
warning: variable does not need to be mutable
--> lint_example.rs:2:5
|
2 | let mut x = 5;
| ----^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
解释
首选的风格是只在需要时才将变量标记为 mut
。
unused-parens
unused_parens
lint 检测带有括号的 if
、match
、while
和 return
;它们不需要括号。
示例
if(true) {}
这将产生
warning: unnecessary parentheses around `if` condition
--> lint_example.rs:2:3
|
2 | if(true) {}
| ^ ^
|
= note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
|
2 - if(true) {}
2 + if true {}
|
解释
括号是不需要的,应该删除。这是编写这些表达式的首选风格。
unused-unsafe
unused_unsafe
lint 检测对 unsafe
块的不必要使用。
示例
unsafe {}
这将产生
warning: unnecessary `unsafe` block
--> lint_example.rs:2:1
|
2 | unsafe {}
| ^^^^^^ unnecessary `unsafe` block
|
= note: `#[warn(unused_unsafe)]` on by default
解释
如果块内没有任何内容需要 unsafe
,则删除 unsafe
标记,因为它不是必需的,并且可能会引起混淆。
unused-variables
unused_variables
lint 检测从未以任何方式使用的变量。
示例
let x = 5;
这将产生
warning: unused variable: `x`
--> lint_example.rs:2:5
|
2 | let x = 5;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
= note: `#[warn(unused_variables)]` on by default
解释
未使用的变量可能表示错误或未完成的代码。要忽略单个变量的警告,请在该变量前加上下划线,例如 _x
。
useless-ptr-null-checks
useless_ptr_null_checks
lint 检查对从非空类型获取的指针进行无用的空检查。
示例
fn test() {}
let fn_ptr: fn() = /* somehow obtained nullable function pointer */
test;
if (fn_ptr as *const ()).is_null() { /* ... */ }
这将产生
warning: function pointers are not nullable, so checking them for null will always return false
--> lint_example.rs:6:4
|
6 | if (fn_ptr as *const ()).is_null() { /* ... */ }
| ^------^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expression has type `fn()`
|
= help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
= note: `#[warn(useless_ptr_null_checks)]` on by default
解释
函数指针和引用被假定为非空,对其进行空检查将始终返回 false。
uses-power-alignment
uses_power_alignment
lint 在 AIX 上检测特定的 repr(C)
聚合。在其平台 C ABI 中,AIX 使用“power”(如 PowerPC 中的)对齐规则(详见 https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=data-using-alignment-modes#alignment),该规则也可以通过 #pragma align(power)
或 -qalign=power
为 XLC 设置。以浮点类型作为递归第一个字段(即“偏移量为 0”)的聚合会修改相关结构体中 后续 字段的布局,使其使用一个对齐值,其中浮点类型按 4 字节边界对齐。
对于 C 兼容性所需的结构体的 power 对齐规则,在编译器中无法在不内置处理 packed 字段引用和传染性嵌套布局的情况下通过 repr(C)
实现,因此在这些情况下会产生警告。
示例
#[repr(C)]
pub struct Floats {
a: f64,
b: u8,
c: f64,
}
这将产生
warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
--> <source>:5:3
|
5 | c: f64,
| ^^^^^^
|
= note: `#[warn(uses_power_alignment)]` on by default
解释
power 对齐规则指定上述结构体具有以下对齐方式
- offset_of!(Floats, a) == 0
- offset_of!(Floats, b) == 8
- offset_of!(Floats, c) == 12 然而,Rust 当前将
c
对齐在 offset_of!(Floats, c) == 16。因此,在这种情况下,上述结构体应该产生一个警告。
warnings
warnings
lint 允许您更改产生警告的其他 lint 的级别。
示例
#![deny(warnings)]
fn foo() {}
这将产生
error: function `foo` is never used
--> lint_example.rs:3:4
|
3 | fn foo() {}
| ^^^
|
note: the lint level is defined here
--> lint_example.rs:1:9
|
1 | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`
解释
warnings
lint 有点特别;通过更改其级别,您可以将所有其他会产生警告的警告更改为您想要的任何值。因此,您永远不会在代码中直接触发此 lint。
wasm-c-abi
wasm_c_abi
lint 检测 wasm 中使用 extern "C"
ABI,该 ABI 受计划的 ABI 变更影响,其目标是使 Rust 与此目标的标准 C ABI 对齐。
示例
#[repr(C)]
struct MyType(i32, i32);
extern "C" my_fun(x: MyType) {}
这将产生
error: this function function definition is affected by the wasm ABI transition: it passes an argument of non-scalar type `MyType`
--> $DIR/wasm_c_abi_transition.rs:17:1
|
| pub extern "C" fn my_fun(_x: MyType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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 #138762 <https://github.com/rust-lang/rust/issues/138762>
= help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
解释
Rust 历史上在 wasm32-unknown-unknown 上实现了一个不符合规范的 C ABI。这导致了与其他编译器和 Wasm 目标的不兼容。在 Rust 的未来版本中,这将得到修复,因此依赖于不符合规范的 C ABI 的代码将停止运行。
while-true
while_true
lint 检测 while true { }
。
示例
while true {
}
这将产生
warning: denote infinite loops with `loop { ... }`
--> lint_example.rs:2:1
|
2 | while true {
| ^^^^^^^^^^ help: use `loop`
|
= note: `#[warn(while_true)]` on by default
解释
while true
应该替换为 loop
。loop
表达式是编写无限循环的首选方式,因为它更直接地表达了循环的意图。