Auto merge of #76549 - ehuss:lints-comments, r=wesleywiser

Auto-generate lint documentation.

This adds a tool which will generate the lint documentation in the rustc book automatically. This is motivated by keeping the documentation up-to-date, and consistently formatted. It also ensures the examples are correct and that they actually generate the expected lint. The lint groups table is also auto-generated. See https://github.com/rust-lang/compiler-team/issues/349 for the original proposal.

An outline of how this works:
- The `declare_lint!` macro now accepts a doc comment where the documentation is written. This is inspired by how clippy works.
- A new tool `src/tools/lint-docs` scrapes the documentation and adds it to the rustc book during the build.
    - It runs each example and verifies its output and embeds the output in the book.
    - It does a few formatting checks.
    - It verifies that every lint is documented.
- Groups are collected from `rustc -W help`.

I updated the documentation for all the missing lints. I have also added an "Explanation" section to each lint providing a reason for the lint and suggestions on how to resolve it.

This can lead towards a future enhancement of possibly showing these docs via the `--explain` flag to make them easily accessible and discoverable.
This commit is contained in:
bors 2020-09-14 05:54:44 +00:00
commit b5f55b7e15
23 changed files with 3869 additions and 1567 deletions

View file

@ -7,6 +7,31 @@ use rustc_session::lint::FutureIncompatibleInfo;
use rustc_span::symbol::sym;
declare_lint! {
/// The `array_into_iter` lint detects calling `into_iter` on arrays.
///
/// ### Example
///
/// ```rust
/// # #![allow(unused)]
/// [1, 2, 3].into_iter().for_each(|n| { *n; });
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// In the future, it is planned to add an `IntoIter` implementation for
/// arrays such that it will iterate over *values* of the array instead of
/// references. Due to how method resolution works, this will change
/// existing code that uses `into_iter` on arrays. The solution to avoid
/// this warning is to use `iter()` instead of `into_iter()`.
///
/// This is a [future-incompatible] lint to transition this to a hard error
/// in the future. See [issue #66145] for more details and a more thorough
/// description of the lint.
///
/// [issue #66145]: https://github.com/rust-lang/rust/issues/66145
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub ARRAY_INTO_ITER,
Warn,
"detects calling `into_iter` on arrays",

View file

@ -61,6 +61,23 @@ use tracing::{debug, trace};
pub use rustc_session::lint::builtin::*;
declare_lint! {
/// The `while_true` lint detects `while true { }`.
///
/// ### Example
///
/// ```rust,no_run
/// while true {
///
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// `while true` should be replaced with `loop`. A `loop` expression is
/// the preferred way to write an infinite loop because it more directly
/// expresses the intent of the loop.
WHILE_TRUE,
Warn,
"suggest using `loop { }` instead of `while true { }`"
@ -102,6 +119,24 @@ impl EarlyLintPass for WhileTrue {
}
declare_lint! {
/// The `box_pointers` lints use of the Box type.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(box_pointers)]
/// struct Foo {
/// x: Box<isize>,
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This lint is mostly historical, and not particularly useful. `Box<T>`
/// used to be built into the language, and the only way to do heap
/// allocation. Today's Rust can call into other allocators, etc.
BOX_POINTERS,
Allow,
"use of owned (Box type) heap memory"
@ -156,6 +191,36 @@ impl<'tcx> LateLintPass<'tcx> for BoxPointers {
}
declare_lint! {
/// The `non_shorthand_field_patterns` lint detects using `Struct { x: x }`
/// instead of `Struct { x }` in a pattern.
///
/// ### Example
///
/// ```rust
/// struct Point {
/// x: i32,
/// y: i32,
/// }
///
///
/// fn main() {
/// let p = Point {
/// x: 5,
/// y: 5,
/// };
///
/// match p {
/// Point { x: x, y: y } => (),
/// }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The preferred style is to avoid the repetition of specifying both the
/// field name and the binding name if both identifiers are the same.
NON_SHORTHAND_FIELD_PATTERNS,
Warn,
"using `Struct { x: x }` instead of `Struct { x }` in a pattern"
@ -216,6 +281,25 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
}
declare_lint! {
/// The `unsafe_code` lint catches usage of `unsafe` code.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unsafe_code)]
/// fn main() {
/// unsafe {
///
/// }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This lint is intended to restrict the usage of `unsafe`, which can be
/// difficult to use correctly.
UNSAFE_CODE,
Allow,
"usage of `unsafe` code"
@ -303,6 +387,25 @@ impl EarlyLintPass for UnsafeCode {
}
declare_lint! {
/// The `missing_docs` lint detects missing documentation for public items.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(missing_docs)]
/// pub fn foo() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This lint is intended to ensure that a library is well-documented.
/// Items without documentation can be difficult for users to understand
/// how to use properly.
///
/// This lint is "allow" by default because it can be noisy, and not all
/// projects may want to enforce everything to be documented.
pub MISSING_DOCS,
Allow,
"detects missing documentation for public members",
@ -528,6 +631,34 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
}
declare_lint! {
/// The `missing_copy_implementations` lint detects potentially-forgotten
/// implementations of [`Copy`].
///
/// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(missing_copy_implementations)]
/// pub struct Foo {
/// pub field: i32
/// }
/// # fn main() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Historically (before 1.0), types were automatically marked as `Copy`
/// if possible. This was changed so that it required an explicit opt-in
/// by implementing the `Copy` trait. As part of this change, a lint was
/// added to alert if a copyable type was not marked `Copy`.
///
/// This lint is "allow" by default because this code isn't bad; it is
/// common to write newtypes like this specifically so that a `Copy` type
/// is no longer `Copy`. `Copy` types can result in unintended copies of
/// large data which can impact performance.
pub MISSING_COPY_IMPLEMENTATIONS,
Allow,
"detects potentially-forgotten implementations of `Copy`"
@ -584,6 +715,32 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
}
declare_lint! {
/// The `missing_debug_implementations` lint detects missing
/// implementations of [`fmt::Debug`].
///
/// [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(missing_debug_implementations)]
/// pub struct Foo;
/// # fn main() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Having a `Debug` implementation on all types can assist with
/// debugging, as it provides a convenient way to format and display a
/// value. Using the `#[derive(Debug)]` attribute will automatically
/// generate a typical implementation, or a custom implementation can be
/// added by manually implementing the `Debug` trait.
///
/// This lint is "allow" by default because adding `Debug` to all types can
/// have a negative impact on compile time and code size. It also requires
/// boilerplate to be added to every type, which can be an impediment.
MISSING_DEBUG_IMPLEMENTATIONS,
Allow,
"detects missing implementations of Debug"
@ -640,6 +797,45 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
}
declare_lint! {
/// The `anonymous_parameters` lint detects anonymous parameters in trait
/// definitions.
///
/// ### Example
///
/// ```rust,edition2015,compile_fail
/// #![deny(anonymous_parameters)]
/// // edition 2015
/// pub trait Foo {
/// fn foo(usize);
/// }
/// fn main() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// This syntax is mostly a historical accident, and can be worked around
/// quite easily by adding an `_` pattern or a descriptive identifier:
///
/// ```rust
/// trait Foo {
/// fn foo(_: usize);
/// }
/// ```
///
/// This syntax is now a hard error in the 2018 edition. In the 2015
/// edition, this lint is "allow" by default, because the old code is
/// still valid, and warning for all old code can be noisy. This lint
/// enables the [`cargo fix`] tool with the `--edition` flag to
/// automatically transition old code from the 2015 edition to 2018. The
/// tool will switch this lint to "warn" and will automatically apply the
/// suggested fix from the compiler (which is to add `_` to each
/// parameter). This provides a completely automated way to update old
/// code for a new edition. See [issue #41686] for more details.
///
/// [issue #41686]: https://github.com/rust-lang/rust/issues/41686
/// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html
pub ANONYMOUS_PARAMETERS,
Allow,
"detects anonymous parameters",
@ -806,12 +1002,54 @@ impl EarlyLintPass for UnusedDocComment {
}
declare_lint! {
/// The `no_mangle_const_items` lint detects any `const` items with the
/// [`no_mangle` attribute].
///
/// [`no_mangle` attribute]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute
///
/// ### Example
///
/// ```rust,compile_fail
/// #[no_mangle]
/// const FOO: i32 = 5;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Constants do not have their symbols exported, and therefore, this
/// probably means you meant to use a [`static`], not a [`const`].
///
/// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html
/// [`const`]: https://doc.rust-lang.org/reference/items/constant-items.html
NO_MANGLE_CONST_ITEMS,
Deny,
"const items will not have their symbols exported"
}
declare_lint! {
/// The `no_mangle_generic_items` lint detects generic items that must be
/// mangled.
///
/// ### Example
///
/// ```rust
/// #[no_mangle]
/// fn foo<T>(t: T) {
///
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// An function with generics must have its symbol mangled to accommodate
/// the generic parameter. The [`no_mangle` attribute] has no effect in
/// this situation, and should be removed.
///
/// [`no_mangle` attribute]: https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute
NO_MANGLE_GENERIC_ITEMS,
Warn,
"generic items must be mangled"
@ -882,6 +1120,27 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
}
declare_lint! {
/// The `mutable_transmutes` lint catches transmuting from `&T` to `&mut
/// T` because it is [undefined behavior].
///
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// ### Example
///
/// ```rust,compile_fail
/// unsafe {
/// let y = std::mem::transmute::<&i32, &mut i32>(&5);
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Certain assumptions are made about aliasing of data, and this transmute
/// violates those assumptions. Consider using [`UnsafeCell`] instead.
///
/// [`UnsafeCell`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html
MUTABLE_TRANSMUTES,
Deny,
"mutating transmuted &mut T from &T may cause undefined behavior"
@ -931,6 +1190,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
}
declare_lint! {
/// The `unstable_features` is deprecated and should no longer be used.
UNSTABLE_FEATURES,
Allow,
"enabling unstable features (deprecated. do not use)"
@ -956,6 +1216,32 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
}
declare_lint! {
/// The `unreachable_pub` lint triggers for `pub` items not reachable from
/// the crate root.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unreachable_pub)]
/// mod foo {
/// pub mod bar {
///
/// }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// A bare `pub` visibility may be misleading if the item is not actually
/// publicly exported from the crate. The `pub(crate)` visibility is
/// recommended to be used instead, which more clearly expresses the intent
/// that the item is only visible within its own crate.
///
/// This lint is "allow" by default because it will trigger for a large
/// amount existing Rust code, and has some false-positives. Eventually it
/// is desired for this to become warn-by-default.
pub UNREACHABLE_PUB,
Allow,
"`pub` items not reachable from crate root"
@ -1035,6 +1321,21 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
}
declare_lint! {
/// The `type_alias_bounds` lint detects bounds in type aliases.
///
/// ### Example
///
/// ```rust
/// type SendVec<T: Send> = Vec<T>;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The trait bounds in a type alias are currently ignored, and should not
/// be included to avoid confusion. This was previously allowed
/// unintentionally; this may become a hard error in the future.
TYPE_ALIAS_BOUNDS,
Warn,
"bounds in type aliases are not enforced"
@ -1194,6 +1495,35 @@ impl<'tcx> LateLintPass<'tcx> for UnusedBrokenConst {
}
declare_lint! {
/// The `trivial_bounds` lint detects trait bounds that don't depend on
/// any type parameters.
///
/// ### Example
///
/// ```rust
/// #![feature(trivial_bounds)]
/// pub struct A where i32: Copy;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Usually you would not write a trait bound that you know is always
/// true, or never true. However, when using macros, the macro may not
/// know whether or not the constraint would hold or not at the time when
/// generating the code. Currently, the compiler does not alert you if the
/// constraint is always true, and generates an error if it is never true.
/// The `trivial_bounds` feature changes this to be a warning in both
/// cases, giving macros more freedom and flexibility to generate code,
/// while still providing a signal when writing non-macro code that
/// something is amiss.
///
/// See [RFC 2056] for more details. This feature is currently only
/// available on the nightly channel, see [tracking issue #48214].
///
/// [RFC 2056]: https://github.com/rust-lang/rfcs/blob/master/text/2056-allow-trivial-where-clause-constraints.md
/// [tracking issue #48214]: https://github.com/rust-lang/rust/issues/48214
TRIVIAL_BOUNDS,
Warn,
"these bounds don't depend on an type parameters"
@ -1270,6 +1600,29 @@ declare_lint_pass!(
);
declare_lint! {
/// The `ellipsis_inclusive_range_patterns` lint detects the [`...` range
/// pattern], which is deprecated.
///
/// [`...` range pattern]: https://doc.rust-lang.org/reference/patterns.html#range-patterns
///
/// ### Example
///
/// ```rust
/// let x = 123;
/// match x {
/// 0...100 => {}
/// _ => {}
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The `...` range pattern syntax was changed to `..=` to avoid potential
/// confusion with the [`..` range expression]. Use the new form instead.
///
/// [`..` range expression]: https://doc.rust-lang.org/reference/expressions/range-expr.html
pub ELLIPSIS_INCLUSIVE_RANGE_PATTERNS,
Warn,
"`...` range patterns are deprecated"
@ -1356,6 +1709,38 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns {
}
declare_lint! {
/// The `unnameable_test_items` lint detects [`#[test]`][test] functions
/// that are not able to be run by the test harness because they are in a
/// position where they are not nameable.
///
/// [test]: https://doc.rust-lang.org/reference/attributes/testing.html#the-test-attribute
///
/// ### Example
///
/// ```rust,test
/// fn main() {
/// #[test]
/// fn foo() {
/// // This test will not fail because it does not run.
/// assert_eq!(1, 2);
/// }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// In order for the test harness to run a test, the test function must be
/// located in a position where it can be accessed from the crate root.
/// This generally means it must be defined in a module, and not anywhere
/// else such as inside another function. The compiler previously allowed
/// this without an error, so a lint was added as an alert that a test is
/// not being used. Whether or not this should be allowed has not yet been
/// decided, see [RFC 2471] and [issue #36629].
///
/// [RFC 2471]: https://github.com/rust-lang/rfcs/pull/2471#issuecomment-397414443
/// [issue #36629]: https://github.com/rust-lang/rust/issues/36629
UNNAMEABLE_TEST_ITEMS,
Warn,
"detects an item that cannot be named being marked as `#[test_case]`",
@ -1401,6 +1786,41 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems {
}
declare_lint! {
/// The `keyword_idents` lint detects edition keywords being used as an
/// identifier.
///
/// ### Example
///
/// ```rust,edition2015,compile_fail
/// #![deny(keyword_idents)]
/// // edition 2015
/// fn dyn() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Rust [editions] allow the language to evolve without breaking
/// backwards compatibility. This lint catches code that uses new keywords
/// that are added to the language that are used as identifiers (such as a
/// variable name, function name, etc.). If you switch the compiler to a
/// new edition without updating the code, then it will fail to compile if
/// you are using a new keyword as an identifier.
///
/// You can manually change the identifiers to a non-keyword, or use a
/// [raw identifier], for example `r#dyn`, to transition to a new edition.
///
/// This lint solves the problem automatically. It is "allow" by default
/// because the code is perfectly valid in older editions. The [`cargo
/// fix`] tool with the `--edition` flag will switch this lint to "warn"
/// and automatically apply the suggested fix from the compiler (which is
/// to use a raw identifier). This provides a completely automated way to
/// update old code for a new edition.
///
/// [editions]: https://doc.rust-lang.org/edition-guide/
/// [raw identifier]: https://doc.rust-lang.org/reference/identifiers.html
/// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html
pub KEYWORD_IDENTS,
Allow,
"detects edition keywords being used as an identifier",
@ -1802,6 +2222,26 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
}
declare_lint! {
/// The `incomplete_features` lint detects unstable features enabled with
/// the [`feature` attribute] that may function improperly in some or all
/// cases.
///
/// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/
///
/// ### Example
///
/// ```rust
/// #![feature(generic_associated_types)]
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Although it is encouraged for people to experiment with unstable
/// features, some of them are known to be incomplete or faulty. This lint
/// is a signal that the feature has not yet been finished, and you may
/// experience problems with it.
pub INCOMPLETE_FEATURES,
Warn,
"incomplete features that may function improperly in some or all cases"
@ -1842,6 +2282,36 @@ impl EarlyLintPass for IncompleteFeatures {
}
declare_lint! {
/// The `invalid_value` lint detects creating a value that is not valid,
/// such as a NULL reference.
///
/// ### Example
///
/// ```rust,no_run
/// # #![allow(unused)]
/// unsafe {
/// let x: &'static i32 = std::mem::zeroed();
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// In some situations the compiler can detect that the code is creating
/// an invalid value, which should be avoided.
///
/// In particular, this lint will check for improper use of
/// [`mem::zeroed`], [`mem::uninitialized`], [`mem::transmute`], and
/// [`MaybeUninit::assume_init`] that can cause [undefined behavior]. The
/// lint should provide extra information to indicate what the problem is
/// and a possible solution.
///
/// [`mem::zeroed`]: https://doc.rust-lang.org/std/mem/fn.zeroed.html
/// [`mem::uninitialized`]: https://doc.rust-lang.org/std/mem/fn.uninitialized.html
/// [`mem::transmute`]: https://doc.rust-lang.org/std/mem/fn.transmute.html
/// [`MaybeUninit::assume_init`]: https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#method.assume_init
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
pub INVALID_VALUE,
Warn,
"an invalid value is being created (such as a NULL reference)"
@ -2073,6 +2543,40 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
}
declare_lint! {
/// The `clashing_extern_declarations` lint detects when an `extern fn`
/// has been declared with the same name but different types.
///
/// ### Example
///
/// ```rust
/// mod m {
/// extern "C" {
/// fn foo();
/// }
/// }
///
/// extern "C" {
/// fn foo(_: u32);
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Because two symbols of the same name cannot be resolved to two
/// different functions at link time, and one function cannot possibly
/// have two types, a clashing extern declaration is almost certainly a
/// mistake. Check to make sure that the `extern` definitions are correct
/// and equivalent, and possibly consider unifying them in one location.
///
/// This lint does not run between crates because a project may have
/// dependencies which both rely on the same extern function, but declare
/// it in a different (but valid) way. For example, they may both declare
/// an opaque type for one or more of the arguments (which would end up
/// distinct types), or use types that are valid conversions in the
/// language the `extern fn` is defined in. In these cases, the compiler
/// can't say that the clashing declaration is incorrect.
pub CLASHING_EXTERN_DECLARATIONS,
Warn,
"detects when an extern fn has been declared with the same name but different types"

View file

@ -4,6 +4,32 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_span::symbol::Symbol;
declare_lint! {
/// The `non_ascii_idents` lint detects non-ASCII identifiers.
///
/// ### Example
///
/// ```rust,compile_fail
/// # #![allow(unused)]
/// #![feature(non_ascii_idents)]
/// #![deny(non_ascii_idents)]
/// fn main() {
/// let föö = 1;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Currently on stable Rust, identifiers must contain ASCII characters.
/// The [`non_ascii_idents`] nightly-only feature allows identifiers to
/// contain non-ASCII characters. This lint allows projects that wish to
/// retain the limit of only using ASCII characters to switch this lint to
/// "forbid" (for example to ease collaboration or for security reasons).
/// See [RFC 2457] for more details.
///
/// [`non_ascii_idents`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/non-ascii-idents.html
/// [RFC 2457]: https://github.com/rust-lang/rfcs/blob/master/text/2457-non-ascii-idents.md
pub NON_ASCII_IDENTS,
Allow,
"detects non-ASCII identifiers",
@ -11,6 +37,37 @@ declare_lint! {
}
declare_lint! {
/// The `uncommon_codepoints` lint detects uncommon Unicode codepoints in
/// identifiers.
///
/// ### Example
///
/// ```rust
/// # #![allow(unused)]
/// #![feature(non_ascii_idents)]
/// const µ: f64 = 0.000001;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// With the [`non_ascii_idents`] nightly-only feature enabled,
/// identifiers are allowed to use non-ASCII characters. This lint warns
/// about using characters which are not commonly used, and may cause
/// visual confusion.
///
/// This lint is triggered by identifiers that contain a codepoint that is
/// not part of the set of "Allowed" codepoints as described by [Unicode®
/// Technical Standard #39 Unicode Security Mechanisms Section 3.1 General
/// Security Profile for Identifiers][TR39Allowed].
///
/// Note that the set of uncommon codepoints may change over time. Beware
/// that if you "forbid" this lint that existing code may fail in the
/// future.
///
/// [`non_ascii_idents`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/non-ascii-idents.html
/// [TR39Allowed]: https://www.unicode.org/reports/tr39/#General_Security_Profile
pub UNCOMMON_CODEPOINTS,
Warn,
"detects uncommon Unicode codepoints in identifiers",
@ -18,6 +75,43 @@ declare_lint! {
}
declare_lint! {
/// The `confusable_idents` lint detects visually confusable pairs between
/// identifiers.
///
/// ### Example
///
/// ```rust
/// #![feature(non_ascii_idents)]
///
/// // Latin Capital Letter E With Caron
/// pub const Ě: i32 = 1;
/// // Latin Capital Letter E With Breve
/// pub const Ĕ: i32 = 2;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// With the [`non_ascii_idents`] nightly-only feature enabled,
/// identifiers are allowed to use non-ASCII characters. This lint warns
/// when different identifiers may appear visually similar, which can
/// cause confusion.
///
/// The confusable detection algorithm is based on [Unicode® Technical
/// Standard #39 Unicode Security Mechanisms Section 4 Confusable
/// Detection][TR39Confusable]. For every distinct identifier X execute
/// the function `skeleton(X)`. If there exist two distinct identifiers X
/// and Y in the same crate where `skeleton(X) = skeleton(Y)` report it.
/// The compiler uses the same mechanism to check if an identifier is too
/// similar to a keyword.
///
/// Note that the set of confusable characters may change over time.
/// Beware that if you "forbid" this lint that existing code may fail in
/// the future.
///
/// [`non_ascii_idents`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/non-ascii-idents.html
/// [TR39Confusable]: https://www.unicode.org/reports/tr39/#Confusable_Detection
pub CONFUSABLE_IDENTS,
Warn,
"detects visually confusable pairs between identifiers",
@ -25,6 +119,41 @@ declare_lint! {
}
declare_lint! {
/// The `mixed_script_confusables` lint detects visually confusable
/// characters in identifiers between different [scripts].
///
/// [scripts]: https://en.wikipedia.org/wiki/Script_(Unicode)
///
/// ### Example
///
/// ```rust
/// #![feature(non_ascii_idents)]
///
/// // The Japanese katakana character エ can be confused with the Han character 工.
/// const エ: &'static str = "アイウ";
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// With the [`non_ascii_idents`] nightly-only feature enabled,
/// identifiers are allowed to use non-ASCII characters. This lint warns
/// when characters between different scripts may appear visually similar,
/// which can cause confusion.
///
/// If the crate contains other identifiers in the same script that have
/// non-confusable characters, then this lint will *not* be issued. For
/// example, if the example given above has another identifier with
/// katakana characters (such as `let カタカナ = 123;`), then this indicates
/// that you are intentionally using katakana, and it will not warn about
/// it.
///
/// Note that the set of confusable characters may change over time.
/// Beware that if you "forbid" this lint that existing code may fail in
/// the future.
///
/// [`non_ascii_idents`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/non-ascii-idents.html
pub MIXED_SCRIPT_CONFUSABLES,
Warn,
"detects Unicode scripts whose mixed script confusables codepoints are solely used",

View file

@ -31,6 +31,24 @@ pub fn method_context(cx: &LateContext<'_>, id: hir::HirId) -> MethodLateContext
}
declare_lint! {
/// The `non_camel_case_types` lint detects types, variants, traits and
/// type parameters that don't have camel case names.
///
/// ### Example
///
/// ```rust
/// struct my_struct;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The preferred style for these identifiers is to use "camel case", such
/// as `MyStruct`, where the first letter should not be lowercase, and
/// should not use underscores between letters. Underscores are allowed at
/// the beginning and end of the identifier, as well as between
/// non-letters (such as `X86_64`).
pub NON_CAMEL_CASE_TYPES,
Warn,
"types, variants, traits and type parameters should have camel case names"
@ -161,6 +179,22 @@ impl EarlyLintPass for NonCamelCaseTypes {
}
declare_lint! {
/// The `non_snake_case` lint detects variables, methods, functions,
/// lifetime parameters and modules that don't have snake case names.
///
/// ### Example
///
/// ```rust
/// let MY_VALUE = 5;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The preferred style for these identifiers is to use "snake case",
/// where all the characters are in lowercase, with words separated with a
/// single underscore, such as `my_value`.
pub NON_SNAKE_CASE,
Warn,
"variables, methods, functions, lifetime parameters and modules should have snake case names"
@ -379,6 +413,21 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
}
declare_lint! {
/// The `non_upper_case_globals` lint detects static items that don't have
/// uppercase identifiers.
///
/// ### Example
///
/// ```rust
/// static max_points: i32 = 5;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The preferred style is for static item names to use all uppercase
/// letters such as `MAX_POINTS`.
pub NON_UPPER_CASE_GLOBALS,
Warn,
"static constants should have uppercase identifiers"

View file

@ -4,6 +4,21 @@ use rustc_errors::Applicability;
use rustc_span::Span;
declare_lint! {
/// The `redundant_semicolons` lint detects unnecessary trailing
/// semicolons.
///
/// ### Example
///
/// ```rust
/// let _ = 123;;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Extra semicolons are not needed, and may be removed to avoid confusion
/// and visual clutter.
pub REDUNDANT_SEMICOLONS,
Warn,
"detects unnecessary trailing semicolons"

View file

@ -23,18 +23,82 @@ use std::cmp;
use tracing::debug;
declare_lint! {
/// The `unused_comparisons` lint detects comparisons made useless by
/// limits of the types involved.
///
/// ### Example
///
/// ```rust
/// fn foo(x: u8) {
/// x >= 0;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// A useless comparison may indicate a mistake, and should be fixed or
/// removed.
UNUSED_COMPARISONS,
Warn,
"comparisons made useless by limits of the types involved"
}
declare_lint! {
/// The `overflowing_literals` lint detects literal out of range for its
/// type.
///
/// ### Example
///
/// ```rust,compile_fail
/// let x: u8 = 1000;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// It is usually a mistake to use a literal that overflows the type where
/// it is used. Either use a literal that is within range, or change the
/// type to be within the range of the literal.
OVERFLOWING_LITERALS,
Deny,
"literal out of range for its type"
}
declare_lint! {
/// The `variant_size_differences` lint detects enums with widely varying
/// variant sizes.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(variant_size_differences)]
/// enum En {
/// V0(u8),
/// VBig([u8; 1024]),
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// It can be a mistake to add a variant to an enum that is much larger
/// than the other variants, bloating the overall size required for all
/// variants. This can impact performance and memory usage. This is
/// triggered if one variant is more than 3 times larger than the
/// second-largest variant.
///
/// Consider placing the large variant's contents on the heap (for example
/// via [`Box`]) to keep the overall size of the enum itself down.
///
/// This lint is "allow" by default because it can be noisy, and may not be
/// an actual problem. Decisions about this should be guided with
/// profiling and benchmarking.
///
/// [`Box`]: https://doc.rust-lang.org/std/boxed/index.html
VARIANT_SIZE_DIFFERENCES,
Allow,
"detects enums with widely varying variant sizes"
@ -495,6 +559,27 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
}
declare_lint! {
/// The `improper_ctypes` lint detects incorrect use of types in foreign
/// modules.
///
/// ### Example
///
/// ```rust
/// extern "C" {
/// static STATIC: String;
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The compiler has several checks to verify that types used in `extern`
/// blocks are safe and follow certain rules to ensure proper
/// compatibility with the foreign interfaces. This lint is issued when it
/// detects a probable mistake in a definition. The lint usually should
/// provide a description of the issue, along with possibly a hint on how
/// to resolve it.
IMPROPER_CTYPES,
Warn,
"proper use of libc types in foreign modules"
@ -503,6 +588,27 @@ declare_lint! {
declare_lint_pass!(ImproperCTypesDeclarations => [IMPROPER_CTYPES]);
declare_lint! {
/// The `improper_ctypes_definitions` lint detects incorrect use of
/// [`extern` function] definitions.
///
/// [`extern` function]: https://doc.rust-lang.org/reference/items/functions.html#extern-function-qualifier
///
/// ### Example
///
/// ```rust
/// # #![allow(unused)]
/// pub extern "C" fn str_type(p: &str) { }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// There are many parameter and return types that may be specified in an
/// `extern` function that are not compatible with the given ABI. This
/// lint is an alert that these types should not be used. The lint usually
/// should provide a description of the issue, along with possibly a hint
/// on how to resolve it.
IMPROPER_CTYPES_DEFINITIONS,
Warn,
"proper use of libc types in foreign item definitions"

View file

@ -20,6 +20,29 @@ use rustc_span::{BytePos, Span, DUMMY_SP};
use tracing::debug;
declare_lint! {
/// The `unused_must_use` lint detects unused result of a type flagged as
/// `#[must_use]`.
///
/// ### Example
///
/// ```rust
/// fn returns_result() -> Result<(), ()> {
/// Ok(())
/// }
///
/// fn main() {
/// returns_result();
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The `#[must_use]` attribute is an indicator that it is a mistake to
/// ignore the value. See [the reference] for more details.
///
/// [the reference]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
pub UNUSED_MUST_USE,
Warn,
"unused result of a type flagged as `#[must_use]`",
@ -27,6 +50,39 @@ declare_lint! {
}
declare_lint! {
/// The `unused_results` lint checks for the unused result of an
/// expression in a statement.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unused_results)]
/// fn foo<T>() -> T { panic!() }
///
/// fn main() {
/// foo::<usize>();
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Ignoring the return value of a function may indicate a mistake. In
/// cases were it is almost certain that the result should be used, it is
/// recommended to annotate the function with the [`must_use` attribute].
/// Failure to use such a return value will trigger the [`unused_must_use`
/// lint] which is warn-by-default. The `unused_results` lint is
/// essentially the same, but triggers for *all* return values.
///
/// This lint is "allow" by default because it can be noisy, and may not be
/// an actual problem. For example, calling the `remove` method of a `Vec`
/// or `HashMap` returns the previous value, which you may not care about.
/// Using this lint would require explicitly ignoring or discarding such
/// values.
///
/// [`must_use` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
/// [`unused_must_use` lint]: warn-by-default.html#unused-must-use
pub UNUSED_RESULTS,
Allow,
"unused result of an expression in a statement"
@ -265,6 +321,21 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
}
declare_lint! {
/// The `path_statements` lint detects path statements with no effect.
///
/// ### Example
///
/// ```rust
/// let x = 42;
///
/// x;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// It is usually a mistake to have a statement that has no effect.
pub PATH_STATEMENTS,
Warn,
"path statements with no effect"
@ -635,6 +706,21 @@ trait UnusedDelimLint {
}
declare_lint! {
/// The `unused_parens` lint detects `if`, `match`, `while` and `return`
/// with parentheses; they do not need them.
///
/// ### Examples
///
/// ```rust
/// if(true) {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The parenthesis are not needed, and should be removed. This is the
/// preferred style for writing these expressions.
pub(super) UNUSED_PARENS,
Warn,
"`if`, `match`, `while` and `return` do not need parentheses"
@ -808,6 +894,23 @@ impl EarlyLintPass for UnusedParens {
}
declare_lint! {
/// The `unused_braces` lint detects unnecessary braces around an
/// expression.
///
/// ### Example
///
/// ```rust
/// if { true } {
/// // ...
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The braces are not needed, and should be removed. This is the
/// preferred style for writing these expressions.
pub(super) UNUSED_BRACES,
Warn,
"unnecessary braces around an expression"
@ -929,6 +1032,30 @@ impl EarlyLintPass for UnusedBraces {
}
declare_lint! {
/// The `unused_import_braces` lint catches unnecessary braces around an
/// imported item.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(unused_import_braces)]
/// use test::{A};
///
/// pub mod test {
/// pub struct A;
/// }
/// # fn main() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// If there is only a single item, then remove the braces (`use test::A;`
/// for example).
///
/// This lint is "allow" by default because it is only enforcing a
/// stylistic choice.
UNUSED_IMPORT_BRACES,
Allow,
"unnecessary braces around an imported item"
@ -978,6 +1105,25 @@ impl EarlyLintPass for UnusedImportBraces {
}
declare_lint! {
/// The `unused_allocation` lint detects unnecessary allocations that can
/// be eliminated.
///
/// ### Example
///
/// ```rust
/// #![feature(box_syntax)]
/// fn main() {
/// let a = (box [1,2,3]).len();
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// When a `box` expression is immediately coerced to a reference, then
/// the allocation is unnecessary, and a reference (using `&` or `&mut`)
/// should be used instead to avoid the allocation.
pub(super) UNUSED_ALLOCATION,
Warn,
"detects unnecessary allocations that can be eliminated"