默认等级为拒绝的 lints
默认情况下,这些 lint 都设置为 'deny' 级别。
- 默认等级为拒绝的 lints
- ambiguous_associated_items
- arithmetic_overflow
- conflicting_repr_hints
- const_err
- ill_formed_attribute_input
- incomplete_include
- invalid_type_param_default
- macro_expanded_macro_exports_accessed_by_absolute_paths
- missing_fragment_specifier
- mutable_transmutes
- no_mangle_const_items
- order_dependent_trait_objects
- overflowing_literals
- patterns_in_fns_without_body
- pub_use_of_private_extern_crate
- soft_unstable
- unconditional_panic
- unknown_crate_types
- useless_deprecated
ambiguous_associated_items
ambiguous_associated_items
lint 检测枚举变量和关联项之间的不确定项。
样例
#![allow(unused)] fn main() { enum E { V } trait Tr { type V; fn foo() -> Self::V; } impl Tr for E { type V = u8; // `Self::V` is ambiguous because it may refer to the associated type or // the enum variant. fn foo() -> Self::V { 0 } } }
显示如下:
error: ambiguous associated item
--> lint_example.rs:15:17
|
15 | fn foo() -> Self::V { 0 }
| ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V`
|
= note: `#[deny(ambiguous_associated_items)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
note: `V` could refer to the variant defined here
--> lint_example.rs:3:5
|
3 | V
| ^
note: `V` could also refer to the associated type defined here
--> lint_example.rs:7:5
|
7 | type V;
| ^^^^^^^
解释
早期 Rust 版本不允许通过类型别名访问枚举变量,当添加此功能时(请参阅 RFC 2338),这引入了某些情况,即类型所指的可能不明确。
要解决该歧义,应使用路径限定明确声明要使用的类型。例如,以上示例中函数可以被写作fn f() -> <Self as Tr>::V { 0 }
以明确引用关联的类型。
这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #57644
arithmetic_overflow
arithmetic_overflow
lint 检测会溢出的算术运算
样例
#![allow(unused)] fn main() { 1_i32 << 32; }
显示如下:
error: this arithmetic operation will overflow
--> lint_example.rs:2:1
|
2 | 1_i32 << 32;
| ^^^^^^^^^^^ attempt to shift left by `32_i32`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default
解释
执行值溢出运算很可能是错误,如果编译器能够在编译时检测到这些溢出,就会触发这个 lint。请考虑调整表达式避免溢出,或者使用不会溢出的数据类型。
conflicting_repr_hints
conflicting_repr_hints
lint 检测带有冲突提示的 repr
属性。
样例
#![allow(unused)] fn main() { #[repr(u32, u64)] enum Foo { Variant1, } }
显示如下:
error[E0566]: conflicting representation hints
--> lint_example.rs:2:8
|
2 | #[repr(u32, u64)]
| ^^^ ^^^
|
= note: `#[deny(conflicting_repr_hints)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
解释
过去编译器错误的接受了这些冲突的表示形式。这是个将来不兼容 的 lint ,将来会转化为固有错误。了解更多细节请参阅 issue #68585
想要更正该问题,请移除冲突的提示之一。
const_err
const_err
lint 检测常量求值时的错误表达式。
样例
#![allow(unused)] #![allow(unconditional_panic)] fn main() { let x: &'static i32 = &(1 / 0); }
显示如下:
error: reaching this expression at runtime will panic or abort
--> lint_example.rs:3:24
|
3 | let x: &'static i32 = &(1 / 0);
| -^^^^^^^
| |
| dividing by zero
|
= note: `#[deny(const_err)]` on by default
解释
该 lint 检测很可能错误的代码,如果将该 lint 等级变为允许,那么代码将不会在编译时进行计算,而是继续生成代码,在运行时计算,这可能会在运行时 panic 。
注意,该 lint 可以在 const 上下文内部或外部触发。在 const 上下文外部,编译器有时会在编译时对表达式求值以生成更高效的代码。如果编译器要在这方面做得更好,它需要决定当遇到肯定会panic 或是不正确的代码时应该怎么做。将此设置为固有错误(hard error)将阻止表现出此行为的现有代码编译,破坏向后兼容性。然而,这肯定是不正确的代码,因此这是一个默认等级为拒绝的 lint。更多细节请参阅 RFC 1229 和 issue #28238。
注意还有几个其他更特定的编译时计算相关的 lint,例如:arithmetic_overflow
,unconditional_panic
。
ill_formed_attribute_input
ill_formed_attribute_input
lint 检测以前被接收并且用于实践中的不良格式的属性输入。
样例
#![allow(unused)] fn main() { #[inline = "this is not valid"] fn foo() {} }
这会显示:
error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
--> lint_example.rs:2:1
|
2 | #[inline = "this is not valid"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[deny(ill_formed_attribute_input)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
解释
以前,许多内置属性的输入没有经过验证,无意义的属性输入被接收。在添加了验证之后,明确了一些现有的项目使用了这些无效的格式。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #57571 。 有关有效输入的属性,更多细节请参阅 attribute reference 。
incomplete_include
incomplete_include
lint 检测一个文件包含多于一个表达式的 include!
宏。
样例
fn main() { include!("foo.txt"); }
当 foo.txt
文件包含以下内容:
println!("hi!");
显示如下:
error: include macro expected single expression in source
--> foo.txt:1:14
|
1 | println!("1");
| ^
|
= note: `#[deny(incomplete_include)]` on by default
解释
include!
宏当前仅打算用于单个表达式或多个项。从以前看,它会忽略第一个表达式之后的任何内容,但这可能会令人困惑。在上例中,println! 表达式( println! expression )刚好在分号之前结束,从而使分号成为多余的信息而被忽略,更令人惊讶的是,如果包含的文件有多个打印语句,后续的语句将被忽略!
一个解决办法是将内容放在大括号中创建块表达式。还可以考虑其他办法,例如函数封装表达式或者使用过程宏。
这是个 lint 而不是固有错误是因为现有项目已经发现并报过错。谨慎起见,它现在还是个 lint 。include!
宏的未来语义还不确定,请参阅 issue #35560。
invalid_type_param_default
invalid_type_param_default
lint 检测在无效位置中错误地允许 (allowed) 使用类型参数默认值。
样例
#![allow(unused)] fn main() { fn foo<T=i32>(t: T) {} }
显示如下:
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions.
--> lint_example.rs:2:8
|
2 | fn foo<T=i32>(t: T) {}
| ^
|
= note: `#[deny(invalid_type_param_default)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
解释
默认类型参数仅在某些情况下才允许使用,但是以前编译器在任何地方都允许使用。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #36887 。
macro_expanded_macro_exports_accessed_by_absolute_paths
macro_expanded_macro_exports_accessed_by_absolute_paths
lint 检测当前 crate 中不能被绝对路径引用的 macro_export
宏的宏展开。
样例
macro_rules! define_exported { () => { #[macro_export] macro_rules! exported { () => {}; } }; } define_exported!(); fn main() { crate::exported!(); }
显示如下:
error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
--> lint_example.rs:13:5
|
13 | crate::exported!();
| ^^^^^^^^^^^^^^^
|
= note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234>
note: the macro is defined here
--> lint_example.rs:4:9
|
4 | / macro_rules! exported {
5 | | () => {};
6 | | }
| |_________^
...
10 | define_exported!();
| ------------------- in this macro invocation
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
解释
我们的目的是所有使用 #[macro_export]
属性的宏在 crate 根是可用的。然而,当一个 macro_rules!
定义由另一个宏生成之时,宏展开是无法遵循该规则的。
这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #53495 。
missing_fragment_specifier
missing_fragment_specifier
lint 当有一个未使用的模式在未跟有片段说明符 (fragment specifier) (例如::expr
)的元变量(例如:$e
)的 macro_rules!
宏定义中时被触发。
始终可以通过移除 macro_rules!
宏定义中未使用的模式来解决此警告。
样例
macro_rules! foo { () => {}; ($name) => { }; } fn main() { foo!(); }
显示如下:
error: missing fragment specifier
--> lint_example.rs:3:5
|
3 | ($name) => { };
| ^^^^^
|
= note: `#[deny(missing_fragment_specifier)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
解释
要修复此问题,从 macro_rules!
定义中移除此未使用模式:
macro_rules! foo { () => {}; } fn main() { foo!(); }
mutable_transmutes
mutable_transmutes
lint 捕捉从 &T
到 &mut T
这种未定义行为 的转换。
样例
#![allow(unused)] fn main() { unsafe { let y = std::mem::transmute::<&i32, &mut i32>(&5); } }
显示如下:
error: mutating transmuted &mut T from &T may cause undefined behavior, consider instead using an UnsafeCell
--> lint_example.rs:3:13
|
3 | let y = std::mem::transmute::<&i32, &mut i32>(&5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[deny(mutable_transmutes)]` on by default
解释
我们对数据别名做出了一些假设,而这种转换是违反这些假设的。考虑使用 UnsafeCell
。
no_mangle_const_items
no_mangle_const_items
lint 检测 no_mangle
属性的所有 const
项。
样例
#![allow(unused)] fn main() { #[no_mangle] const FOO: i32 = 5; }
显示如下:
error: const items should never be `#[no_mangle]`
--> lint_example.rs:3:1
|
3 | const FOO: i32 = 5;
| -----^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`
|
= note: `#[deny(no_mangle_const_items)]` on by default
解释
常量没有其导出符号,因此这可能意味着你得用 static
而不是 const
。
order_dependent_trait_objects
order_dependent_trait_objects
lint 检测一种 trait 一致性冲突,该冲突即为同一个包含标记 trait (marker traits)的 dynamic trait object 创建两个 trait 实现。
样例
#![allow(unused)] fn main() { pub trait Trait {} impl Trait for dyn Send + Sync { } impl Trait for dyn Sync + Send { } }
显示如下:
error: conflicting implementations of trait `main::Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
--> lint_example.rs:5:1
|
4 | impl Trait for dyn Send + Sync { }
| ------------------------------ first implementation here
5 | impl Trait for dyn Sync + Send { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
|
= note: `#[deny(order_dependent_trait_objects)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
解释
以前的一个 bug 导致编译器将不同顺序的 trait (例如 Send + Sync
和 Sync + Send
)解释为不同的类型,然而它们应该被认为是相同的。这允许代码在出现一致性错误的时候定义单独的 trait 实现。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #56484 。
overflowing_literals
overflowing_literals
lint 检测超出其所属类型范围的字面量。
样例
#![allow(unused)] fn main() { let x: u8 = 1000; }
显示如下:
error: literal out of range for `u8`
--> lint_example.rs:2:13
|
2 | let x: u8 = 1000;
| ^^^^
|
= note: `#[deny(overflowing_literals)]` on by default
= note: the literal `1000` does not fit into the type `u8` whose range is `0..=255`
解释
使用溢出其所用类型的字面量通常是错误。要么就使用在其类型范围内的字面量,要么就更改其类型以能容纳该字面量。
patterns_in_fns_without_body
patterns_in_fns_without_body
lint 检测 mut
标识符模式用于没有函数体的函数的参数。
样例
#![allow(unused)] fn main() { trait Trait { fn foo(mut arg: u8); } }
显示如下:
error: patterns aren't allowed in functions without bodies
--> lint_example.rs:3:12
|
3 | fn foo(mut arg: u8);
| ^^^^^^^
|
= note: `#[deny(patterns_in_fns_without_body)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
解释
要想修复此问题, trait 定义中从参数移除 mut
;也可以使用默认实现。也就是说,以下两种都行:
#![allow(unused)] fn main() { trait Trait { fn foo(arg: u8); // Removed `mut` here } impl Trait for i32 { fn foo(mut arg: u8) { // `mut` here is OK } } }
trait 定义中可以定义没有函数体的函数以指定实现必须实现的函数体。无函数体的函数形参名仅允许是 _
或为了文档目的的(仅类型相关)的标识符。以前的编译器版本错误地允许标识符模式使用 mut
关键字,但这是不被允许的。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #35203 。
pub_use_of_private_extern_crate
pub_use_of_private_extern_crate
lint 检测私有 extern crate
重导出的具体情况。
样例
#![allow(unused)]
fn main() {
extern crate core;
pub use core as reexported_core;
}
显示如下:
error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
--> lint_example.rs:3:9
|
3 | pub use core as reexported_core;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[deny(pub_use_of_private_extern_crate)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
解释
一个公开的 use
声明不应该用于 公开性地重导出私有 extern crate
。应该使用 pub extern crate
。
过去是允许该行为的,但是根据可见性规则这是不符合预期的。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #34537 。
soft_unstable
soft_unstable
lint 检测 在 stable 上无意间允许(allowed)的 unstable feature。
样例
#![allow(unused)] fn main() { #[cfg(test)] extern crate test; #[bench] fn name(b: &mut test::Bencher) { b.iter(|| 123) } }
显示如下:
error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
--> lint_example.rs:5:3
|
5 | #[bench]
| ^^^^^
|
= note: `#[deny(soft_unstable)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
解释
bench
属性意外地在 stable release channel 上被指定。将此转化为固有错误会破坏一些(现有)项目。当使用 --cap-lints
时该 lint 允许项目正确地构建,否则会发出一个错误提示。#[bench]
不应该被用在 stable channel。这是个将来不兼容 的 lint ,将来会转化为固有错误。更多细节请参阅 issue #64266 。
unconditional_panic
unconditional_panic
lint 检测将在运行时引起 panic 的操作。
样例
#![allow(unused)] fn main() { #![allow(unused)] let x = 1 / 0; }
显示如下:
error: this operation will panic at runtime
--> lint_example.rs:3:9
|
3 | let x = 1 / 0;
| ^^^^^ attempt to divide `1_i32` by zero
|
= note: `#[deny(unconditional_panic)]` on by default
解释
该 lint 检测很可能不正确的代码。如果可能,编译器将尝试检测代码能够在编译时进行计算的情况,以生成更高效的代码。在计算这类代码时,如果检测到代码会无条件地 panic ,通常表示(要执行的计算)在做一些错误的事情。如果该 lint 等级被改为允许,然后此代码将不会在编译时被计算,而是继续生成代码在运行时计算,这也可能会在运行时 panic。
unknown_crate_types
unknown_crate_types
lint 检测在 crate_type
属性中找到的未知 crate 类型。
样例
#![crate_type="lol"] fn main() {}
显示如下:
error: invalid `crate_type` value
--> lint_example.rs:1:15
|
1 | #![crate_type="lol"]
| ^^^^^
|
= note: `#[deny(unknown_crate_types)]` on by default
解释
给 crate_type
属性赋未知值可以肯定说是一个错误。
useless_deprecated
useless_deprecated
lint 检测无效且弃用的属性。
样例
#![allow(unused)] fn main() { struct X; #[deprecated = "message"] impl Default for X { fn default() -> Self { X } } }
显示如下:
error: this `#[deprecated]` annotation has no effect
--> lint_example.rs:4:1
|
4 | #[deprecated = "message"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the unnecessary deprecation attribute
|
= note: `#[deny(useless_deprecated)]` on by default
解释
弃用属性对 trait 实现是无影响的。