mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 12:13:43 +00:00
Auto merge of #3845 - euclio:unused-comments, r=phansch
move lint documentation into macro invocations This PR moves lint documentation inside `declare_clippy_lint!` macro invocations, to avoid triggering the `unused_doc_comments` lint once it's modified in rust-lang/rust#57882. This PR is necessary to unblock that work, since the large number of warnings generated in `clippy_lints` causes Travis to hit the log length limit. This PR also updates the documentation and website generation script. It would be nice to get a clippy update in the Rust repo once this is merged. cc @phansch
This commit is contained in:
commit
15d1731ce8
@ -12,8 +12,9 @@ use walkdir::WalkDir;
|
||||
lazy_static! {
|
||||
static ref DEC_CLIPPY_LINT_RE: Regex = Regex::new(
|
||||
r#"(?x)
|
||||
declare_clippy_lint!\s*[\{(]\s*
|
||||
pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
||||
declare_clippy_lint!\s*[\{(]
|
||||
(?:\s+///.*)*
|
||||
\s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
||||
(?P<cat>[a-z_]+)\s*,\s*
|
||||
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
||||
"#
|
||||
@ -22,7 +23,8 @@ lazy_static! {
|
||||
static ref DEC_DEPRECATED_LINT_RE: Regex = Regex::new(
|
||||
r#"(?x)
|
||||
declare_deprecated_lint!\s*[{(]\s*
|
||||
pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
||||
(?:\s+///.*)*
|
||||
\s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
|
||||
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
||||
"#
|
||||
)
|
||||
|
@ -6,28 +6,28 @@ use std::f64::consts as f64;
|
||||
use syntax::ast::{FloatTy, Lit, LitKind};
|
||||
use syntax::symbol;
|
||||
|
||||
/// **What it does:** Checks for floating point literals that approximate
|
||||
/// constants which are defined in
|
||||
/// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
|
||||
/// or
|
||||
/// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
|
||||
/// respectively, suggesting to use the predefined constant.
|
||||
///
|
||||
/// **Why is this bad?** Usually, the definition in the standard library is more
|
||||
/// precise than what people come up with. If you find that your definition is
|
||||
/// actually more precise, please [file a Rust
|
||||
/// issue](https://github.com/rust-lang/rust/issues).
|
||||
///
|
||||
/// **Known problems:** If you happen to have a value that is within 1/8192 of a
|
||||
/// known constant, but is not *and should not* be the same, this lint will
|
||||
/// report your value anyway. We have not yet noticed any false positives in
|
||||
/// code we tested clippy with (this includes servo), but YMMV.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = 3.14;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for floating point literals that approximate
|
||||
/// constants which are defined in
|
||||
/// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
|
||||
/// or
|
||||
/// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
|
||||
/// respectively, suggesting to use the predefined constant.
|
||||
///
|
||||
/// **Why is this bad?** Usually, the definition in the standard library is more
|
||||
/// precise than what people come up with. If you find that your definition is
|
||||
/// actually more precise, please [file a Rust
|
||||
/// issue](https://github.com/rust-lang/rust/issues).
|
||||
///
|
||||
/// **Known problems:** If you happen to have a value that is within 1/8192 of a
|
||||
/// known constant, but is not *and should not* be the same, this lint will
|
||||
/// report your value anyway. We have not yet noticed any false positives in
|
||||
/// code we tested clippy with (this includes servo), but YMMV.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = 3.14;
|
||||
/// ```
|
||||
pub APPROX_CONSTANT,
|
||||
correctness,
|
||||
"the approximate of a known float constant (in `std::fXX::consts`)"
|
||||
|
@ -5,36 +5,36 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for plain integer arithmetic.
|
||||
///
|
||||
/// **Why is this bad?** This is only checked against overflow in debug builds.
|
||||
/// In some applications one wants explicitly checked, wrapping or saturating
|
||||
/// arithmetic.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + 1
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for plain integer arithmetic.
|
||||
///
|
||||
/// **Why is this bad?** This is only checked against overflow in debug builds.
|
||||
/// In some applications one wants explicitly checked, wrapping or saturating
|
||||
/// arithmetic.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + 1
|
||||
/// ```
|
||||
pub INTEGER_ARITHMETIC,
|
||||
restriction,
|
||||
"any integer arithmetic statement"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for float arithmetic.
|
||||
///
|
||||
/// **Why is this bad?** For some embedded systems or kernel development, it
|
||||
/// can be useful to rule out floating-point numbers.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + 1.0
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for float arithmetic.
|
||||
///
|
||||
/// **Why is this bad?** For some embedded systems or kernel development, it
|
||||
/// can be useful to rule out floating-point numbers.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + 1.0
|
||||
/// ```
|
||||
pub FLOAT_ARITHMETIC,
|
||||
restriction,
|
||||
"any floating-point arithmetic statement"
|
||||
|
@ -6,23 +6,23 @@ use crate::syntax::ast::LitKind;
|
||||
use crate::utils::{in_macro, is_direct_expn_of, span_help_and_lint};
|
||||
use if_chain::if_chain;
|
||||
|
||||
/// **What it does:** Check to call assert!(true/false)
|
||||
///
|
||||
/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
|
||||
/// panic!() or unreachable!()
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// assert!(false)
|
||||
/// // or
|
||||
/// assert!(true)
|
||||
/// // or
|
||||
/// const B: bool = false;
|
||||
/// assert!(B)
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Check to call assert!(true/false)
|
||||
///
|
||||
/// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
|
||||
/// panic!() or unreachable!()
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// assert!(false);
|
||||
/// // or
|
||||
/// assert!(true);
|
||||
/// // or
|
||||
/// const B: bool = false;
|
||||
/// assert!(B);
|
||||
/// ```
|
||||
pub ASSERTIONS_ON_CONSTANTS,
|
||||
style,
|
||||
"assert!(true/false) will be optimized out by the compiler/should probably be replaced by a panic!() or unreachable!()"
|
||||
|
@ -7,43 +7,43 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
|
||||
/// patterns.
|
||||
///
|
||||
/// **Why is this bad?** These can be written as the shorter `a op= b`.
|
||||
///
|
||||
/// **Known problems:** While forbidden by the spec, `OpAssign` traits may have
|
||||
/// implementations that differ from the regular `Op` impl.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a = a + b;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
|
||||
/// patterns.
|
||||
///
|
||||
/// **Why is this bad?** These can be written as the shorter `a op= b`.
|
||||
///
|
||||
/// **Known problems:** While forbidden by the spec, `OpAssign` traits may have
|
||||
/// implementations that differ from the regular `Op` impl.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a = a + b;
|
||||
/// ```
|
||||
pub ASSIGN_OP_PATTERN,
|
||||
style,
|
||||
"assigning the result of an operation on a variable to that same variable"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns.
|
||||
///
|
||||
/// **Why is this bad?** Most likely these are bugs where one meant to write `a
|
||||
/// op= b`.
|
||||
///
|
||||
/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have
|
||||
/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore it suggests both.
|
||||
/// If `a op= a op b` is really the correct behaviour it should be
|
||||
/// written as `a = a op a op b` as it's less confusing.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a += a + b;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `a op= a op b` or `a op= b op a` patterns.
|
||||
///
|
||||
/// **Why is this bad?** Most likely these are bugs where one meant to write `a
|
||||
/// op= b`.
|
||||
///
|
||||
/// **Known problems:** Clippy cannot know for sure if `a op= a op b` should have
|
||||
/// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore it suggests both.
|
||||
/// If `a op= a op b` is really the correct behaviour it should be
|
||||
/// written as `a = a op a op b` as it's less confusing.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a += a + b;
|
||||
/// ```
|
||||
pub MISREFACTORED_ASSIGN_OP,
|
||||
complexity,
|
||||
"having a variable on both sides of an assign op"
|
||||
|
@ -17,170 +17,170 @@ use semver::Version;
|
||||
use syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
|
||||
/// unless the annotated function is empty or simply panics.
|
||||
///
|
||||
/// **Why is this bad?** While there are valid uses of this annotation (and once
|
||||
/// you know when to use it, by all means `allow` this lint), it's a common
|
||||
/// newbie-mistake to pepper one's code with it.
|
||||
///
|
||||
/// As a rule of thumb, before slapping `#[inline(always)]` on a function,
|
||||
/// measure if that additional function call really affects your runtime profile
|
||||
/// sufficiently to make up for the increase in compile time.
|
||||
///
|
||||
/// **Known problems:** False positives, big time. This lint is meant to be
|
||||
/// deactivated by everyone doing serious performance work. This means having
|
||||
/// done the measurement.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[inline(always)]
|
||||
/// fn not_quite_hot_code(..) { ... }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
|
||||
/// unless the annotated function is empty or simply panics.
|
||||
///
|
||||
/// **Why is this bad?** While there are valid uses of this annotation (and once
|
||||
/// you know when to use it, by all means `allow` this lint), it's a common
|
||||
/// newbie-mistake to pepper one's code with it.
|
||||
///
|
||||
/// As a rule of thumb, before slapping `#[inline(always)]` on a function,
|
||||
/// measure if that additional function call really affects your runtime profile
|
||||
/// sufficiently to make up for the increase in compile time.
|
||||
///
|
||||
/// **Known problems:** False positives, big time. This lint is meant to be
|
||||
/// deactivated by everyone doing serious performance work. This means having
|
||||
/// done the measurement.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// #[inline(always)]
|
||||
/// fn not_quite_hot_code(..) { ... }
|
||||
/// ```
|
||||
pub INLINE_ALWAYS,
|
||||
pedantic,
|
||||
"use of `#[inline(always)]`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `extern crate` and `use` items annotated with
|
||||
/// lint attributes.
|
||||
///
|
||||
/// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on
|
||||
/// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a
|
||||
/// `#[macro_use]` attribute.
|
||||
///
|
||||
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
|
||||
/// likely a `!` was forgotten.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// #[deny(dead_code)]
|
||||
/// extern crate foo;
|
||||
/// #[forbid(dead_code)]
|
||||
/// use foo::bar;
|
||||
///
|
||||
/// // Ok
|
||||
/// #[allow(unused_imports)]
|
||||
/// use foo::baz;
|
||||
/// #[allow(unused_imports)]
|
||||
/// #[macro_use]
|
||||
/// extern crate baz;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `extern crate` and `use` items annotated with
|
||||
/// lint attributes.
|
||||
///
|
||||
/// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on
|
||||
/// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a
|
||||
/// `#[macro_use]` attribute.
|
||||
///
|
||||
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
|
||||
/// likely a `!` was forgotten.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// // Bad
|
||||
/// #[deny(dead_code)]
|
||||
/// extern crate foo;
|
||||
/// #[forbid(dead_code)]
|
||||
/// use foo::bar;
|
||||
///
|
||||
/// // Ok
|
||||
/// #[allow(unused_imports)]
|
||||
/// use foo::baz;
|
||||
/// #[allow(unused_imports)]
|
||||
/// #[macro_use]
|
||||
/// extern crate baz;
|
||||
/// ```
|
||||
pub USELESS_ATTRIBUTE,
|
||||
correctness,
|
||||
"use of lint attributes on `extern crate` items"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `#[deprecated]` annotations with a `since`
|
||||
/// field that is not a valid semantic version.
|
||||
///
|
||||
/// **Why is this bad?** For checking the version of the deprecation, it must be
|
||||
/// a valid semver. Failing that, the contained information is useless.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[deprecated(since = "forever")]
|
||||
/// fn something_else(..) { ... }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `#[deprecated]` annotations with a `since`
|
||||
/// field that is not a valid semantic version.
|
||||
///
|
||||
/// **Why is this bad?** For checking the version of the deprecation, it must be
|
||||
/// a valid semver. Failing that, the contained information is useless.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[deprecated(since = "forever")]
|
||||
/// fn something_else() { /* ... */ }
|
||||
/// ```
|
||||
pub DEPRECATED_SEMVER,
|
||||
correctness,
|
||||
"use of `#[deprecated(since = \"x\")]` where x is not semver"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for empty lines after outer attributes
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// Most likely the attribute was meant to be an inner attribute using a '!'.
|
||||
/// If it was meant to be an outer attribute, then the following item
|
||||
/// should not be separated by empty lines.
|
||||
///
|
||||
/// **Known problems:** Can cause false positives.
|
||||
///
|
||||
/// From the clippy side it's difficult to detect empty lines between an attributes and the
|
||||
/// following item because empty lines and comments are not part of the AST. The parsing
|
||||
/// currently works for basic cases but is not perfect.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// #[inline(always)]
|
||||
///
|
||||
/// fn not_quite_good_code(..) { ... }
|
||||
///
|
||||
/// // Good (as inner attribute)
|
||||
/// #![inline(always)]
|
||||
///
|
||||
/// fn this_is_fine(..) { ... }
|
||||
///
|
||||
/// // Good (as outer attribute)
|
||||
/// #[inline(always)]
|
||||
/// fn this_is_fine_too(..) { ... }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for empty lines after outer attributes
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// Most likely the attribute was meant to be an inner attribute using a '!'.
|
||||
/// If it was meant to be an outer attribute, then the following item
|
||||
/// should not be separated by empty lines.
|
||||
///
|
||||
/// **Known problems:** Can cause false positives.
|
||||
///
|
||||
/// From the clippy side it's difficult to detect empty lines between an attributes and the
|
||||
/// following item because empty lines and comments are not part of the AST. The parsing
|
||||
/// currently works for basic cases but is not perfect.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// #[inline(always)]
|
||||
///
|
||||
/// fn not_quite_good_code(..) { ... }
|
||||
///
|
||||
/// // Good (as inner attribute)
|
||||
/// #![inline(always)]
|
||||
///
|
||||
/// fn this_is_fine(..) { ... }
|
||||
///
|
||||
/// // Good (as outer attribute)
|
||||
/// #[inline(always)]
|
||||
/// fn this_is_fine_too(..) { ... }
|
||||
/// ```
|
||||
pub EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
nursery,
|
||||
"empty line after outer attribute"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy
|
||||
/// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name
|
||||
/// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase
|
||||
/// the lint name.
|
||||
///
|
||||
/// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #![warn(if_not_els)]
|
||||
/// #![deny(clippy::All)]
|
||||
/// ```
|
||||
///
|
||||
/// Good:
|
||||
/// ```rust
|
||||
/// #![warn(if_not_else)]
|
||||
/// #![deny(clippy::all)]
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy
|
||||
/// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name
|
||||
/// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase
|
||||
/// the lint name.
|
||||
///
|
||||
/// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #![warn(if_not_els)]
|
||||
/// #![deny(clippy::All)]
|
||||
/// ```
|
||||
///
|
||||
/// Good:
|
||||
/// ```rust
|
||||
/// #![warn(if_not_else)]
|
||||
/// #![deny(clippy::all)]
|
||||
/// ```
|
||||
pub UNKNOWN_CLIPPY_LINTS,
|
||||
style,
|
||||
"unknown_lints for scoped Clippy lints"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
|
||||
/// with `#[rustfmt::skip]`.
|
||||
///
|
||||
/// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
|
||||
/// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
|
||||
///
|
||||
/// **Known problems:** This lint doesn't detect crate level inner attributes, because they get
|
||||
/// processed before the PreExpansionPass lints get executed. See
|
||||
/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
/// fn main() { }
|
||||
/// ```
|
||||
///
|
||||
/// Good:
|
||||
/// ```rust
|
||||
/// #[rustfmt::skip]
|
||||
/// fn main() { }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
|
||||
/// with `#[rustfmt::skip]`.
|
||||
///
|
||||
/// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
|
||||
/// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
|
||||
///
|
||||
/// **Known problems:** This lint doesn't detect crate level inner attributes, because they get
|
||||
/// processed before the PreExpansionPass lints get executed. See
|
||||
/// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
/// fn main() { }
|
||||
/// ```
|
||||
///
|
||||
/// Good:
|
||||
/// ```rust
|
||||
/// #[rustfmt::skip]
|
||||
/// fn main() { }
|
||||
/// ```
|
||||
pub DEPRECATED_CFG_ATTR,
|
||||
complexity,
|
||||
"usage of `cfg_attr(rustfmt)` instead of `tool_attributes`"
|
||||
|
@ -9,83 +9,83 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for incompatible bit masks in comparisons.
|
||||
///
|
||||
/// The formula for detecting if an expression of the type `_ <bit_op> m
|
||||
/// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
|
||||
/// {`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following
|
||||
/// table:
|
||||
///
|
||||
/// |Comparison |Bit Op|Example |is always|Formula |
|
||||
/// |------------|------|------------|---------|----------------------|
|
||||
/// |`==` or `!=`| `&` |`x & 2 == 3`|`false` |`c & m != c` |
|
||||
/// |`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |
|
||||
/// |`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |
|
||||
/// |`==` or `!=`| `|` |`x | 1 == 0`|`false` |`c | m != c` |
|
||||
/// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` |
|
||||
/// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` |
|
||||
///
|
||||
/// **Why is this bad?** If the bits that the comparison cares about are always
|
||||
/// set to zero or one by the bit mask, the comparison is constant `true` or
|
||||
/// `false` (depending on mask, compared value, and operators).
|
||||
///
|
||||
/// So the code is actively misleading, and the only reason someone would write
|
||||
/// this intentionally is to win an underhanded Rust contest or create a
|
||||
/// test-case for this lint.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if (x & 1 == 2) { … }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for incompatible bit masks in comparisons.
|
||||
///
|
||||
/// The formula for detecting if an expression of the type `_ <bit_op> m
|
||||
/// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of
|
||||
/// {`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following
|
||||
/// table:
|
||||
///
|
||||
/// |Comparison |Bit Op|Example |is always|Formula |
|
||||
/// |------------|------|------------|---------|----------------------|
|
||||
/// |`==` or `!=`| `&` |`x & 2 == 3`|`false` |`c & m != c` |
|
||||
/// |`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |
|
||||
/// |`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |
|
||||
/// |`==` or `!=`| `|` |`x | 1 == 0`|`false` |`c | m != c` |
|
||||
/// |`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` |
|
||||
/// |`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` |
|
||||
///
|
||||
/// **Why is this bad?** If the bits that the comparison cares about are always
|
||||
/// set to zero or one by the bit mask, the comparison is constant `true` or
|
||||
/// `false` (depending on mask, compared value, and operators).
|
||||
///
|
||||
/// So the code is actively misleading, and the only reason someone would write
|
||||
/// this intentionally is to win an underhanded Rust contest or create a
|
||||
/// test-case for this lint.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if (x & 1 == 2) { … }
|
||||
/// ```
|
||||
pub BAD_BIT_MASK,
|
||||
correctness,
|
||||
"expressions of the form `_ & mask == select` that will only ever return `true` or `false`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for bit masks in comparisons which can be removed
|
||||
/// without changing the outcome. The basic structure can be seen in the
|
||||
/// following table:
|
||||
///
|
||||
/// |Comparison| Bit Op |Example |equals |
|
||||
/// |----------|---------|-----------|-------|
|
||||
/// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|
|
||||
/// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|
|
||||
///
|
||||
/// **Why is this bad?** Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
|
||||
/// but still a bit misleading, because the bit mask is ineffective.
|
||||
///
|
||||
/// **Known problems:** False negatives: This lint will only match instances
|
||||
/// where we have figured out the math (which is for a power-of-two compared
|
||||
/// value). This means things like `x | 1 >= 7` (which would be better written
|
||||
/// as `x >= 6`) will not be reported (but bit masks like this are fairly
|
||||
/// uncommon).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if (x | 1 > 3) { … }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for bit masks in comparisons which can be removed
|
||||
/// without changing the outcome. The basic structure can be seen in the
|
||||
/// following table:
|
||||
///
|
||||
/// |Comparison| Bit Op |Example |equals |
|
||||
/// |----------|---------|-----------|-------|
|
||||
/// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|
|
||||
/// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|
|
||||
///
|
||||
/// **Why is this bad?** Not equally evil as [`bad_bit_mask`](#bad_bit_mask),
|
||||
/// but still a bit misleading, because the bit mask is ineffective.
|
||||
///
|
||||
/// **Known problems:** False negatives: This lint will only match instances
|
||||
/// where we have figured out the math (which is for a power-of-two compared
|
||||
/// value). This means things like `x | 1 >= 7` (which would be better written
|
||||
/// as `x >= 6`) will not be reported (but bit masks like this are fairly
|
||||
/// uncommon).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if (x | 1 > 3) { … }
|
||||
/// ```
|
||||
pub INEFFECTIVE_BIT_MASK,
|
||||
correctness,
|
||||
"expressions where a bit mask will be rendered useless by a comparison, e.g. `(x | 1) > 2`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for bit masks that can be replaced by a call
|
||||
/// to `trailing_zeros`
|
||||
///
|
||||
/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15
|
||||
/// == 0`
|
||||
///
|
||||
/// **Known problems:** llvm generates better code for `x & 15 == 0` on x86
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x & 0x1111 == 0
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for bit masks that can be replaced by a call
|
||||
/// to `trailing_zeros`
|
||||
///
|
||||
/// **Why is this bad?** `x.trailing_zeros() > 4` is much clearer than `x & 15
|
||||
/// == 0`
|
||||
///
|
||||
/// **Known problems:** llvm generates better code for `x & 15 == 0` on x86
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// x & 0x1111 == 0
|
||||
/// ```
|
||||
pub VERBOSE_BIT_MASK,
|
||||
style,
|
||||
"expressions where a bit mask is less readable than the corresponding method call"
|
||||
|
@ -4,19 +4,19 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
/// **What it does:** Checks for usage of blacklisted names for variables, such
|
||||
/// as `foo`.
|
||||
///
|
||||
/// **Why is this bad?** These names are usually placeholder names and should be
|
||||
/// avoided.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let foo = 3.14;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of blacklisted names for variables, such
|
||||
/// as `foo`.
|
||||
///
|
||||
/// **Why is this bad?** These names are usually placeholder names and should be
|
||||
/// avoided.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let foo = 3.14;
|
||||
/// ```
|
||||
pub BLACKLISTED_NAME,
|
||||
style,
|
||||
"usage of a blacklisted/placeholder name"
|
||||
|
@ -5,38 +5,38 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for `if` conditions that use blocks to contain an
|
||||
/// expression.
|
||||
///
|
||||
/// **Why is this bad?** It isn't really Rust style, same as using parentheses
|
||||
/// to contain expressions.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if { true } ..
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `if` conditions that use blocks to contain an
|
||||
/// expression.
|
||||
///
|
||||
/// **Why is this bad?** It isn't really Rust style, same as using parentheses
|
||||
/// to contain expressions.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if { true } { /* ... */ }
|
||||
/// ```
|
||||
pub BLOCK_IN_IF_CONDITION_EXPR,
|
||||
style,
|
||||
"braces that can be eliminated in conditions, e.g. `if { true } ...`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `if` conditions that use blocks containing
|
||||
/// statements, or conditions that use closures with blocks.
|
||||
///
|
||||
/// **Why is this bad?** Using blocks in the condition makes it hard to read.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if { let x = somefunc(); x } ..
|
||||
/// // or
|
||||
/// if somefunc(|x| { x == 47 }) ..
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `if` conditions that use blocks containing
|
||||
/// statements, or conditions that use closures with blocks.
|
||||
///
|
||||
/// **Why is this bad?** Using blocks in the condition makes it hard to read.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if { let x = somefunc(); x } {}
|
||||
/// // or
|
||||
/// if somefunc(|x| { x == 47 }) {}
|
||||
/// ```
|
||||
pub BLOCK_IN_IF_CONDITION_STMT,
|
||||
style,
|
||||
"complex blocks in conditions, e.g. `if { let x = true; x } ...`"
|
||||
|
@ -10,39 +10,39 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::{dummy_spanned, Span, DUMMY_SP};
|
||||
|
||||
/// **What it does:** Checks for boolean expressions that can be written more
|
||||
/// concisely.
|
||||
///
|
||||
/// **Why is this bad?** Readability of boolean expressions suffers from
|
||||
/// unnecessary duplication.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior of `||` and
|
||||
/// `&&`. Ignores `|`, `&` and `^`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if a && true // should be: if a
|
||||
/// if !(a == b) // should be: if a != b
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for boolean expressions that can be written more
|
||||
/// concisely.
|
||||
///
|
||||
/// **Why is this bad?** Readability of boolean expressions suffers from
|
||||
/// unnecessary duplication.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior of `||` and
|
||||
/// `&&`. Ignores `|`, `&` and `^`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if a && true // should be: if a
|
||||
/// if !(a == b) // should be: if a != b
|
||||
/// ```
|
||||
pub NONMINIMAL_BOOL,
|
||||
complexity,
|
||||
"boolean expressions that can be written more concisely"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for boolean expressions that contain terminals that
|
||||
/// can be eliminated.
|
||||
///
|
||||
/// **Why is this bad?** This is most likely a logic bug.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if a && b || a { ... }
|
||||
/// ```
|
||||
/// The `b` is unnecessary, the expression is equivalent to `if a`.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for boolean expressions that contain terminals that
|
||||
/// can be eliminated.
|
||||
///
|
||||
/// **Why is this bad?** This is most likely a logic bug.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if a && b || a { ... }
|
||||
/// ```
|
||||
/// The `b` is unnecessary, the expression is equivalent to `if a`.
|
||||
pub LOGIC_BUG,
|
||||
correctness,
|
||||
"boolean expressions that contain terminals which can be eliminated"
|
||||
|
@ -10,22 +10,22 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::{Name, UintTy};
|
||||
|
||||
/// **What it does:** Checks for naive byte counts
|
||||
///
|
||||
/// **Why is this bad?** The [`bytecount`](https://crates.io/crates/bytecount)
|
||||
/// crate has methods to count your bytes faster, especially for large slices.
|
||||
///
|
||||
/// **Known problems:** If you have predominantly small slices, the
|
||||
/// `bytecount::count(..)` method may actually be slower. However, if you can
|
||||
/// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
|
||||
/// faster in those cases.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// &my_data.filter(|&x| x == 0u8).count() // use bytecount::count instead
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for naive byte counts
|
||||
///
|
||||
/// **Why is this bad?** The [`bytecount`](https://crates.io/crates/bytecount)
|
||||
/// crate has methods to count your bytes faster, especially for large slices.
|
||||
///
|
||||
/// **Known problems:** If you have predominantly small slices, the
|
||||
/// `bytecount::count(..)` method may actually be slower. However, if you can
|
||||
/// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be
|
||||
/// faster in those cases.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// &my_data.filter(|&x| x == 0u8).count() // use bytecount::count instead
|
||||
/// ```
|
||||
pub NAIVE_BYTECOUNT,
|
||||
perf,
|
||||
"use of naive `<slice>.filter(|&x| x == y).count()` to count byte values"
|
||||
|
@ -7,28 +7,28 @@ use syntax::{ast::*, source_map::DUMMY_SP};
|
||||
|
||||
use cargo_metadata;
|
||||
|
||||
/// **What it does:** Checks to see if all common metadata is defined in
|
||||
/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
|
||||
///
|
||||
/// **Why is this bad?** It will be more difficult for users to discover the
|
||||
/// purpose of the crate, and key information related to it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```toml
|
||||
/// # This `Cargo.toml` is missing an authors field:
|
||||
/// [package]
|
||||
/// name = "clippy"
|
||||
/// version = "0.0.212"
|
||||
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
/// repository = "https://github.com/rust-lang/rust-clippy"
|
||||
/// readme = "README.md"
|
||||
/// license = "MIT/Apache-2.0"
|
||||
/// keywords = ["clippy", "lint", "plugin"]
|
||||
/// categories = ["development-tools", "development-tools::cargo-plugins"]
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks to see if all common metadata is defined in
|
||||
/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
|
||||
///
|
||||
/// **Why is this bad?** It will be more difficult for users to discover the
|
||||
/// purpose of the crate, and key information related to it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```toml
|
||||
/// # This `Cargo.toml` is missing an authors field:
|
||||
/// [package]
|
||||
/// name = "clippy"
|
||||
/// version = "0.0.212"
|
||||
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
/// repository = "https://github.com/rust-lang/rust-clippy"
|
||||
/// readme = "README.md"
|
||||
/// license = "MIT/Apache-2.0"
|
||||
/// keywords = ["clippy", "lint", "plugin"]
|
||||
/// categories = ["development-tools", "development-tools::cargo-plugins"]
|
||||
/// ```
|
||||
pub CARGO_COMMON_METADATA,
|
||||
cargo,
|
||||
"common metadata is defined in `Cargo.toml`"
|
||||
|
@ -21,51 +21,51 @@ use crate::utils::sugg::Sugg;
|
||||
use crate::utils::{in_macro, snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for nested `if` statements which can be collapsed
|
||||
/// by `&&`-combining their conditions and for `else { if ... }` expressions
|
||||
/// that
|
||||
/// can be collapsed to `else if ...`.
|
||||
///
|
||||
/// **Why is this bad?** Each `if`-statement adds one level of nesting, which
|
||||
/// makes code look more complex than it really is.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// if x {
|
||||
/// if y {
|
||||
/// …
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// if x {
|
||||
/// …
|
||||
/// } else {
|
||||
/// if y {
|
||||
/// …
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Should be written:
|
||||
///
|
||||
/// ```rust.ignore
|
||||
/// if x && y {
|
||||
/// …
|
||||
/// }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// if x {
|
||||
/// …
|
||||
/// } else if y {
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for nested `if` statements which can be collapsed
|
||||
/// by `&&`-combining their conditions and for `else { if ... }` expressions
|
||||
/// that
|
||||
/// can be collapsed to `else if ...`.
|
||||
///
|
||||
/// **Why is this bad?** Each `if`-statement adds one level of nesting, which
|
||||
/// makes code look more complex than it really is.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// if x {
|
||||
/// if y {
|
||||
/// …
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// if x {
|
||||
/// …
|
||||
/// } else {
|
||||
/// if y {
|
||||
/// …
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Should be written:
|
||||
///
|
||||
/// ```rust.ignore
|
||||
/// if x && y {
|
||||
/// …
|
||||
/// }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// if x {
|
||||
/// …
|
||||
/// } else if y {
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
pub COLLAPSIBLE_IF,
|
||||
style,
|
||||
"`if`s that can be collapsed (e.g. `if x { if y { ... } }` and `else { if x { ... } }`)"
|
||||
|
@ -4,23 +4,23 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::*;
|
||||
|
||||
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
|
||||
///
|
||||
/// **Why is this bad?** Adding `'static` to every reference can create very
|
||||
/// complicated types.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =
|
||||
/// &[...]
|
||||
/// ```
|
||||
/// This code can be rewritten as
|
||||
/// ```rust
|
||||
/// const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
|
||||
///
|
||||
/// **Why is this bad?** Adding `'static` to every reference can create very
|
||||
/// complicated types.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =
|
||||
/// &[...]
|
||||
/// ```
|
||||
/// This code can be rewritten as
|
||||
/// ```ignore
|
||||
/// const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]
|
||||
/// ```
|
||||
pub CONST_STATIC_LIFETIME,
|
||||
style,
|
||||
"Using explicit `'static` lifetime for constants when elision rules would allow omitting them."
|
||||
|
@ -10,94 +10,94 @@ use std::collections::hash_map::Entry;
|
||||
use std::hash::BuildHasherDefault;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
|
||||
/// **What it does:** Checks for consecutive `if`s with the same condition.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if a == b {
|
||||
/// …
|
||||
/// } else if a == b {
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that this lint ignores all conditions with a function call as it could
|
||||
/// have side effects:
|
||||
///
|
||||
/// ```rust
|
||||
/// if foo() {
|
||||
/// …
|
||||
/// } else if foo() { // not linted
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for consecutive `if`s with the same condition.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if a == b {
|
||||
/// …
|
||||
/// } else if a == b {
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that this lint ignores all conditions with a function call as it could
|
||||
/// have side effects:
|
||||
///
|
||||
/// ```ignore
|
||||
/// if foo() {
|
||||
/// …
|
||||
/// } else if foo() { // not linted
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
pub IFS_SAME_COND,
|
||||
correctness,
|
||||
"consecutive `ifs` with the same condition"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `if/else` with the same body as the *then* part
|
||||
/// and the *else* part.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let foo = if … {
|
||||
/// 42
|
||||
/// } else {
|
||||
/// 42
|
||||
/// };
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `if/else` with the same body as the *then* part
|
||||
/// and the *else* part.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let foo = if … {
|
||||
/// 42
|
||||
/// } else {
|
||||
/// 42
|
||||
/// };
|
||||
/// ```
|
||||
pub IF_SAME_THEN_ELSE,
|
||||
correctness,
|
||||
"if with the same *then* and *else* blocks"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `match` with identical arm bodies.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error. If arm bodies
|
||||
/// are the same on purpose, you can factor them
|
||||
/// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).
|
||||
///
|
||||
/// **Known problems:** False positive possible with order dependent `match`
|
||||
/// (see issue
|
||||
/// [#860](https://github.com/rust-lang/rust-clippy/issues/860)).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// match foo {
|
||||
/// Bar => bar(),
|
||||
/// Quz => quz(),
|
||||
/// Baz => bar(), // <= oops
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This should probably be
|
||||
/// ```rust,ignore
|
||||
/// match foo {
|
||||
/// Bar => bar(),
|
||||
/// Quz => quz(),
|
||||
/// Baz => baz(), // <= fixed
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// or if the original code was not a typo:
|
||||
/// ```rust,ignore
|
||||
/// match foo {
|
||||
/// Bar | Baz => bar(), // <= shows the intent better
|
||||
/// Quz => quz(),
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `match` with identical arm bodies.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error. If arm bodies
|
||||
/// are the same on purpose, you can factor them
|
||||
/// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).
|
||||
///
|
||||
/// **Known problems:** False positive possible with order dependent `match`
|
||||
/// (see issue
|
||||
/// [#860](https://github.com/rust-lang/rust-clippy/issues/860)).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// match foo {
|
||||
/// Bar => bar(),
|
||||
/// Quz => quz(),
|
||||
/// Baz => bar(), // <= oops
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This should probably be
|
||||
/// ```rust,ignore
|
||||
/// match foo {
|
||||
/// Bar => bar(),
|
||||
/// Quz => quz(),
|
||||
/// Baz => baz(), // <= fixed
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// or if the original code was not a typo:
|
||||
/// ```rust,ignore
|
||||
/// match foo {
|
||||
/// Bar | Baz => bar(), // <= shows the intent better
|
||||
/// Quz => quz(),
|
||||
/// }
|
||||
/// ```
|
||||
pub MATCH_SAME_ARMS,
|
||||
pedantic,
|
||||
"`match` with identical arm bodies"
|
||||
|
@ -3,27 +3,27 @@ use rustc::hir::{Item, ItemKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for types that implement `Copy` as well as
|
||||
/// `Iterator`.
|
||||
///
|
||||
/// **Why is this bad?** Implicit copies can be confusing when working with
|
||||
/// iterator combinators.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[derive(Copy, Clone)]
|
||||
/// struct Countdown(u8);
|
||||
///
|
||||
/// impl Iterator for Countdown {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let a: Vec<_> = my_iterator.take(1).collect();
|
||||
/// let b: Vec<_> = my_iterator.collect();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for types that implement `Copy` as well as
|
||||
/// `Iterator`.
|
||||
///
|
||||
/// **Why is this bad?** Implicit copies can be confusing when working with
|
||||
/// iterator combinators.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[derive(Copy, Clone)]
|
||||
/// struct Countdown(u8);
|
||||
///
|
||||
/// impl Iterator for Countdown {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let a: Vec<_> = my_iterator.take(1).collect();
|
||||
/// let b: Vec<_> = my_iterator.collect();
|
||||
/// ```
|
||||
pub COPY_ITERATOR,
|
||||
pedantic,
|
||||
"implementing `Iterator` on a `Copy` type"
|
||||
|
@ -11,16 +11,16 @@ use syntax::source_map::Span;
|
||||
|
||||
use crate::utils::{in_macro, is_allowed, match_type, paths, span_help_and_lint, LimitStack};
|
||||
|
||||
/// **What it does:** Checks for methods with high cyclomatic complexity.
|
||||
///
|
||||
/// **Why is this bad?** Methods of high cyclomatic complexity tend to be badly
|
||||
/// readable. Also LLVM will usually optimize small methods better.
|
||||
///
|
||||
/// **Known problems:** Sometimes it's hard to find a way to reduce the
|
||||
/// complexity.
|
||||
///
|
||||
/// **Example:** No. You'll see it when you get the warning.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for methods with high cyclomatic complexity.
|
||||
///
|
||||
/// **Why is this bad?** Methods of high cyclomatic complexity tend to be badly
|
||||
/// readable. Also LLVM will usually optimize small methods better.
|
||||
///
|
||||
/// **Known problems:** Sometimes it's hard to find a way to reduce the
|
||||
/// complexity.
|
||||
///
|
||||
/// **Example:** No. You'll see it when you get the warning.
|
||||
pub CYCLOMATIC_COMPLEXITY,
|
||||
complexity,
|
||||
"functions that should be split up into multiple functions"
|
||||
|
@ -6,22 +6,22 @@ use syntax::ast;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::tokenstream::TokenStream;
|
||||
|
||||
/// **What it does:** Checks for usage of dbg!() macro.
|
||||
///
|
||||
/// **Why is this bad?** `dbg!` macro is intended as a debugging tool. It
|
||||
/// should not be in version control.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// // Bad
|
||||
/// dbg!(true)
|
||||
///
|
||||
/// // Good
|
||||
/// true
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of dbg!() macro.
|
||||
///
|
||||
/// **Why is this bad?** `dbg!` macro is intended as a debugging tool. It
|
||||
/// should not be in version control.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// // Bad
|
||||
/// dbg!(true)
|
||||
///
|
||||
/// // Good
|
||||
/// true
|
||||
/// ```
|
||||
pub DBG_MACRO,
|
||||
restriction,
|
||||
"`dbg!` macro is intended as a debugging tool"
|
||||
|
@ -7,22 +7,22 @@ use rustc_errors::Applicability;
|
||||
|
||||
use crate::utils::{any_parent_is_automatically_derived, match_def_path, opt_def_id, paths, span_lint_and_sugg};
|
||||
|
||||
/// **What it does:** Checks for literal calls to `Default::default()`.
|
||||
///
|
||||
/// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is
|
||||
/// being gotten than the generic `Default`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let s: String = Default::default();
|
||||
///
|
||||
/// // Good
|
||||
/// let s = String::default();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for literal calls to `Default::default()`.
|
||||
///
|
||||
/// **Why is this bad?** It's more clear to the reader to use the name of the type whose default is
|
||||
/// being gotten than the generic `Default`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let s: String = Default::default();
|
||||
///
|
||||
/// // Good
|
||||
/// let s = String::default();
|
||||
/// ```
|
||||
pub DEFAULT_TRAIT_ACCESS,
|
||||
pedantic,
|
||||
"checks for literal calls to Default::default()"
|
||||
|
@ -7,56 +7,56 @@ use rustc::ty::{self, Ty};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for deriving `Hash` but implementing `PartialEq`
|
||||
/// explicitly or vice versa.
|
||||
///
|
||||
/// **Why is this bad?** The implementation of these traits must agree (for
|
||||
/// example for use with `HashMap`) so it’s probably a bad idea to use a
|
||||
/// default-generated `Hash` implementation with an explicitly defined
|
||||
/// `PartialEq`. In particular, the following must hold for any type:
|
||||
///
|
||||
/// ```rust
|
||||
/// k1 == k2 ⇒ hash(k1) == hash(k2)
|
||||
/// ```
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[derive(Hash)]
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl PartialEq for Foo {
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for deriving `Hash` but implementing `PartialEq`
|
||||
/// explicitly or vice versa.
|
||||
///
|
||||
/// **Why is this bad?** The implementation of these traits must agree (for
|
||||
/// example for use with `HashMap`) so it’s probably a bad idea to use a
|
||||
/// default-generated `Hash` implementation with an explicitly defined
|
||||
/// `PartialEq`. In particular, the following must hold for any type:
|
||||
///
|
||||
/// ```text
|
||||
/// k1 == k2 ⇒ hash(k1) == hash(k2)
|
||||
/// ```
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// #[derive(Hash)]
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl PartialEq for Foo {
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
pub DERIVE_HASH_XOR_EQ,
|
||||
correctness,
|
||||
"deriving `Hash` but implementing `PartialEq` explicitly"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for explicit `Clone` implementations for `Copy`
|
||||
/// types.
|
||||
///
|
||||
/// **Why is this bad?** To avoid surprising behaviour, these traits should
|
||||
/// agree and the behaviour of `Copy` cannot be overridden. In almost all
|
||||
/// situations a `Copy` type should have a `Clone` implementation that does
|
||||
/// nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
|
||||
/// gets you.
|
||||
///
|
||||
/// **Known problems:** Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[derive(Copy)]
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Clone for Foo {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for explicit `Clone` implementations for `Copy`
|
||||
/// types.
|
||||
///
|
||||
/// **Why is this bad?** To avoid surprising behaviour, these traits should
|
||||
/// agree and the behaviour of `Copy` cannot be overridden. In almost all
|
||||
/// situations a `Copy` type should have a `Clone` implementation that does
|
||||
/// nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
|
||||
/// gets you.
|
||||
///
|
||||
/// **Known problems:** Bounds of generic types are sometimes wrong: https://github.com/rust-lang/rust/issues/26925
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[derive(Copy)]
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Clone for Foo {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub EXPL_IMPL_CLONE_ON_COPY,
|
||||
pedantic,
|
||||
"implementing `Clone` explicitly on `Copy` types"
|
||||
|
@ -9,25 +9,25 @@ use syntax::source_map::{BytePos, Span};
|
||||
use syntax_pos::Pos;
|
||||
use url::Url;
|
||||
|
||||
/// **What it does:** Checks for the presence of `_`, `::` or camel-case words
|
||||
/// outside ticks in documentation.
|
||||
///
|
||||
/// **Why is this bad?** *Rustdoc* supports markdown formatting, `_`, `::` and
|
||||
/// camel-case probably indicates some code which should be included between
|
||||
/// ticks. `_` can also be used for emphasis in markdown, this lint tries to
|
||||
/// consider that.
|
||||
///
|
||||
/// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks
|
||||
/// for is limited, and there are still false positives.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ```rust
|
||||
/// /// Do something with the foo_bar parameter. See also
|
||||
/// /// that::other::module::foo.
|
||||
/// // ^ `foo_bar` and `that::other::module::foo` should be ticked.
|
||||
/// fn doit(foo_bar) { .. }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the presence of `_`, `::` or camel-case words
|
||||
/// outside ticks in documentation.
|
||||
///
|
||||
/// **Why is this bad?** *Rustdoc* supports markdown formatting, `_`, `::` and
|
||||
/// camel-case probably indicates some code which should be included between
|
||||
/// ticks. `_` can also be used for emphasis in markdown, this lint tries to
|
||||
/// consider that.
|
||||
///
|
||||
/// **Known problems:** Lots of bad docs won’t be fixed, what the lint checks
|
||||
/// for is limited, and there are still false positives.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ```rust
|
||||
/// /// Do something with the foo_bar parameter. See also
|
||||
/// /// that::other::module::foo.
|
||||
/// // ^ `foo_bar` and `that::other::module::foo` should be ticked.
|
||||
/// fn doit(foo_bar) { .. }
|
||||
/// ```
|
||||
pub DOC_MARKDOWN,
|
||||
pedantic,
|
||||
"presence of `_`, `::` or camel-case outside backticks in documentation"
|
||||
|
@ -8,24 +8,24 @@ use syntax::source_map::Span;
|
||||
|
||||
use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
|
||||
|
||||
/// **What it does:** Checks for double comparions that could be simplified to a single expression.
|
||||
///
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x == y || x < y
|
||||
/// ```
|
||||
///
|
||||
/// Could be written as:
|
||||
///
|
||||
/// ```rust
|
||||
/// x <= y
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for double comparions that could be simplified to a single expression.
|
||||
///
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x == y || x < y
|
||||
/// ```
|
||||
///
|
||||
/// Could be written as:
|
||||
///
|
||||
/// ```rust
|
||||
/// x <= y
|
||||
/// ```
|
||||
pub DOUBLE_COMPARISONS,
|
||||
complexity,
|
||||
"unnecessary double comparisons that can be simplified"
|
||||
|
@ -3,20 +3,20 @@ use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
|
||||
/// **What it does:** Checks for unnecessary double parentheses.
|
||||
///
|
||||
/// **Why is this bad?** This makes code harder to read and might indicate a
|
||||
/// mistake.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// ((0))
|
||||
/// foo((0))
|
||||
/// ((1, 2))
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for unnecessary double parentheses.
|
||||
///
|
||||
/// **Why is this bad?** This makes code harder to read and might indicate a
|
||||
/// mistake.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// ((0))
|
||||
/// foo((0))
|
||||
/// ((1, 2))
|
||||
/// ```
|
||||
pub DOUBLE_PARENS,
|
||||
complexity,
|
||||
"Warn on unnecessary double parentheses"
|
||||
|
@ -4,29 +4,29 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for generics with `std::ops::Drop` as bounds.
|
||||
///
|
||||
/// **Why is this bad?** `Drop` bounds do not really accomplish anything.
|
||||
/// A type may have compiler-generated drop glue without implementing the
|
||||
/// `Drop` trait itself. The `Drop` trait also only has one method,
|
||||
/// `Drop::drop`, and that function is by fiat not callable in user code.
|
||||
/// So there is really no use case for using `Drop` in trait bounds.
|
||||
///
|
||||
/// The most likely use case of a drop bound is to distinguish between types
|
||||
/// that have destructors and types that don't. Combined with specialization,
|
||||
/// a naive coder would write an implementation that assumed a type could be
|
||||
/// trivially dropped, then write a specialization for `T: Drop` that actually
|
||||
/// calls the destructor. Except that doing so is not correct; String, for
|
||||
/// example, doesn't actually implement Drop, but because String contains a
|
||||
/// Vec, assuming it can be trivially dropped will leak memory.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo<T: Drop>() {}
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for generics with `std::ops::Drop` as bounds.
|
||||
///
|
||||
/// **Why is this bad?** `Drop` bounds do not really accomplish anything.
|
||||
/// A type may have compiler-generated drop glue without implementing the
|
||||
/// `Drop` trait itself. The `Drop` trait also only has one method,
|
||||
/// `Drop::drop`, and that function is by fiat not callable in user code.
|
||||
/// So there is really no use case for using `Drop` in trait bounds.
|
||||
///
|
||||
/// The most likely use case of a drop bound is to distinguish between types
|
||||
/// that have destructors and types that don't. Combined with specialization,
|
||||
/// a naive coder would write an implementation that assumed a type could be
|
||||
/// trivially dropped, then write a specialization for `T: Drop` that actually
|
||||
/// calls the destructor. Except that doing so is not correct; String, for
|
||||
/// example, doesn't actually implement Drop, but because String contains a
|
||||
/// Vec, assuming it can be trivially dropped will leak memory.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo<T: Drop>() {}
|
||||
/// ```
|
||||
pub DROP_BOUNDS,
|
||||
correctness,
|
||||
"Bounds of the form `T: Drop` are useless"
|
||||
|
@ -5,93 +5,93 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for calls to `std::mem::drop` with a reference
|
||||
/// instead of an owned value.
|
||||
///
|
||||
/// **Why is this bad?** Calling `drop` on a reference will only drop the
|
||||
/// reference itself, which is a no-op. It will not call the `drop` method (from
|
||||
/// the `Drop` trait implementation) on the underlying referenced value, which
|
||||
/// is likely what was intended.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// 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();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::drop` with a reference
|
||||
/// instead of an owned value.
|
||||
///
|
||||
/// **Why is this bad?** Calling `drop` on a reference will only drop the
|
||||
/// reference itself, which is a no-op. It will not call the `drop` method (from
|
||||
/// the `Drop` trait implementation) on the underlying referenced value, which
|
||||
/// is likely what was intended.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// 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();
|
||||
/// ```
|
||||
pub DROP_REF,
|
||||
correctness,
|
||||
"calls to `std::mem::drop` with a reference instead of an owned value"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for calls to `std::mem::forget` with a reference
|
||||
/// instead of an owned value.
|
||||
///
|
||||
/// **Why is this bad?** Calling `forget` on a reference will only forget the
|
||||
/// reference itself, which is a no-op. It will not forget the underlying
|
||||
/// referenced
|
||||
/// value, which is likely what was intended.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Box::new(1);
|
||||
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::forget` with a reference
|
||||
/// instead of an owned value.
|
||||
///
|
||||
/// **Why is this bad?** Calling `forget` on a reference will only forget the
|
||||
/// reference itself, which is a no-op. It will not forget the underlying
|
||||
/// referenced
|
||||
/// value, which is likely what was intended.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Box::new(1);
|
||||
/// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
|
||||
/// ```
|
||||
pub FORGET_REF,
|
||||
correctness,
|
||||
"calls to `std::mem::forget` with a reference instead of an owned value"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for calls to `std::mem::drop` with a value
|
||||
/// that derives the Copy trait
|
||||
///
|
||||
/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that
|
||||
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
|
||||
/// value will be copied and moved into the function on invocation.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: i32 = 42; // i32 implements Copy
|
||||
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the
|
||||
/// // original unaffected
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::drop` with a value
|
||||
/// that derives the Copy trait
|
||||
///
|
||||
/// **Why is this bad?** Calling `std::mem::drop` [does nothing for types that
|
||||
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
|
||||
/// value will be copied and moved into the function on invocation.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: i32 = 42; // i32 implements Copy
|
||||
/// std::mem::drop(x) // A copy of x is passed to the function, leaving the
|
||||
/// // original unaffected
|
||||
/// ```
|
||||
pub DROP_COPY,
|
||||
correctness,
|
||||
"calls to `std::mem::drop` with a value that implements Copy"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for calls to `std::mem::forget` with a value that
|
||||
/// derives the Copy trait
|
||||
///
|
||||
/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that
|
||||
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
|
||||
/// value will be copied and moved into the function on invocation.
|
||||
///
|
||||
/// An alternative, but also valid, explanation is that Copy types do not
|
||||
/// implement
|
||||
/// the Drop trait, which means they have no destructors. Without a destructor,
|
||||
/// there
|
||||
/// is nothing for `std::mem::forget` to ignore.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: i32 = 42; // i32 implements Copy
|
||||
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the
|
||||
/// // original unaffected
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `std::mem::forget` with a value that
|
||||
/// derives the Copy trait
|
||||
///
|
||||
/// **Why is this bad?** Calling `std::mem::forget` [does nothing for types that
|
||||
/// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
|
||||
/// value will be copied and moved into the function on invocation.
|
||||
///
|
||||
/// An alternative, but also valid, explanation is that Copy types do not
|
||||
/// implement
|
||||
/// the Drop trait, which means they have no destructors. Without a destructor,
|
||||
/// there
|
||||
/// is nothing for `std::mem::forget` to ignore.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: i32 = 42; // i32 implements Copy
|
||||
/// std::mem::forget(x) // A copy of x is passed to the function, leaving the
|
||||
/// // original unaffected
|
||||
/// ```
|
||||
pub FORGET_COPY,
|
||||
correctness,
|
||||
"calls to `std::mem::forget` with a value that implements Copy"
|
||||
|
@ -9,21 +9,21 @@ use crate::consts::{constant, Constant};
|
||||
use crate::utils::paths;
|
||||
use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty};
|
||||
|
||||
/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds
|
||||
/// from other `Duration` methods.
|
||||
///
|
||||
/// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or
|
||||
/// `Duration::subsec_millis()` than to calculate them.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let dur = Duration::new(5, 0);
|
||||
/// let _micros = dur.subsec_nanos() / 1_000;
|
||||
/// let _millis = dur.subsec_nanos() / 1_000_000;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds
|
||||
/// from other `Duration` methods.
|
||||
///
|
||||
/// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or
|
||||
/// `Duration::subsec_millis()` than to calculate them.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let dur = Duration::new(5, 0);
|
||||
/// let _micros = dur.subsec_nanos() / 1_000;
|
||||
/// let _millis = dur.subsec_nanos() / 1_000_000;
|
||||
/// ```
|
||||
pub DURATION_SUBSEC,
|
||||
complexity,
|
||||
"checks for calculation of subsecond microseconds or milliseconds"
|
||||
|
@ -6,34 +6,34 @@ use syntax::ast::*;
|
||||
|
||||
use crate::utils::span_help_and_lint;
|
||||
|
||||
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
|
||||
/// but without a final `else` branch.
|
||||
///
|
||||
/// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x.is_positive() {
|
||||
/// a();
|
||||
/// } else if x.is_negative() {
|
||||
/// b();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// if x.is_positive() {
|
||||
/// a();
|
||||
/// } else if x.is_negative() {
|
||||
/// b();
|
||||
/// } else {
|
||||
/// // we don't care about zero
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
|
||||
/// but without a final `else` branch.
|
||||
///
|
||||
/// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x.is_positive() {
|
||||
/// a();
|
||||
/// } else if x.is_negative() {
|
||||
/// b();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// if x.is_positive() {
|
||||
/// a();
|
||||
/// } else if x.is_negative() {
|
||||
/// b();
|
||||
/// } else {
|
||||
/// // we don't care about zero
|
||||
/// }
|
||||
/// ```
|
||||
pub ELSE_IF_WITHOUT_ELSE,
|
||||
restriction,
|
||||
"if expression with an `else if`, but without a final `else` branch"
|
||||
|
@ -5,19 +5,19 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for `enum`s with no variants.
|
||||
///
|
||||
/// **Why is this bad?** Enum's with no variants should be replaced with `!`,
|
||||
/// the uninhabited type,
|
||||
/// or a wrapper around it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Test {}
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `enum`s with no variants.
|
||||
///
|
||||
/// **Why is this bad?** Enum's with no variants should be replaced with `!`,
|
||||
/// the uninhabited type,
|
||||
/// or a wrapper around it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Test {}
|
||||
/// ```
|
||||
pub EMPTY_ENUM,
|
||||
pedantic,
|
||||
"enum with no variants"
|
||||
|
@ -8,30 +8,30 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap`
|
||||
/// or `BTreeMap`.
|
||||
///
|
||||
/// **Why is this bad?** Using `entry` is more efficient.
|
||||
///
|
||||
/// **Known problems:** Some false negatives, eg.:
|
||||
/// ```rust
|
||||
/// let k = &key;
|
||||
/// if !m.contains_key(k) {
|
||||
/// m.insert(k.clone(), v);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if !m.contains_key(&k) {
|
||||
/// m.insert(k, v)
|
||||
/// }
|
||||
/// ```
|
||||
/// can be rewritten as:
|
||||
/// ```rust
|
||||
/// m.entry(k).or_insert(v);
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for uses of `contains_key` + `insert` on `HashMap`
|
||||
/// or `BTreeMap`.
|
||||
///
|
||||
/// **Why is this bad?** Using `entry` is more efficient.
|
||||
///
|
||||
/// **Known problems:** Some false negatives, eg.:
|
||||
/// ```rust
|
||||
/// let k = &key;
|
||||
/// if !m.contains_key(k) {
|
||||
/// m.insert(k.clone(), v);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if !m.contains_key(&k) {
|
||||
/// m.insert(k, v)
|
||||
/// }
|
||||
/// ```
|
||||
/// can be rewritten as:
|
||||
/// ```rust
|
||||
/// m.entry(k).or_insert(v);
|
||||
/// ```
|
||||
pub MAP_ENTRY,
|
||||
perf,
|
||||
"use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`"
|
||||
|
@ -12,23 +12,23 @@ use rustc::ty::util::IntTypeExt;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::{IntTy, UintTy};
|
||||
|
||||
/// **What it does:** Checks for C-like enumerations that are
|
||||
/// `repr(isize/usize)` and have values that don't fit into an `i32`.
|
||||
///
|
||||
/// **Why is this bad?** This will truncate the variant value on 32 bit
|
||||
/// architectures, but works fine on 64 bit.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[repr(usize)]
|
||||
/// enum NonPortable {
|
||||
/// X = 0x1_0000_0000,
|
||||
/// Y = 0,
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for C-like enumerations that are
|
||||
/// `repr(isize/usize)` and have values that don't fit into an `i32`.
|
||||
///
|
||||
/// **Why is this bad?** This will truncate the variant value on 32 bit
|
||||
/// architectures, but works fine on 64 bit.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[repr(usize)]
|
||||
/// enum NonPortable {
|
||||
/// X = 0x1_0000_0000,
|
||||
/// Y = 0,
|
||||
/// }
|
||||
/// ```
|
||||
pub ENUM_CLIKE_UNPORTABLE_VARIANT,
|
||||
correctness,
|
||||
"C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`"
|
||||
|
@ -7,19 +7,19 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for `use Enum::*`.
|
||||
///
|
||||
/// **Why is this bad?** It is usually better style to use the prefixed name of
|
||||
/// an enumeration variant, rather than importing variants.
|
||||
///
|
||||
/// **Known problems:** Old-style enumerations that prefix the variants are
|
||||
/// still around.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::cmp::Ordering::*;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `use Enum::*`.
|
||||
///
|
||||
/// **Why is this bad?** It is usually better style to use the prefixed name of
|
||||
/// an enumeration variant, rather than importing variants.
|
||||
///
|
||||
/// **Known problems:** Old-style enumerations that prefix the variants are
|
||||
/// still around.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::cmp::Ordering::*;
|
||||
/// ```
|
||||
pub ENUM_GLOB_USE,
|
||||
pedantic,
|
||||
"use items that import all variants of an enum"
|
||||
|
@ -8,94 +8,94 @@ use syntax::ast::*;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::{InternedString, LocalInternedString};
|
||||
|
||||
/// **What it does:** Detects enumeration variants that are prefixed or suffixed
|
||||
/// by the same characters.
|
||||
///
|
||||
/// **Why is this bad?** Enumeration variant names should specify their variant,
|
||||
/// not repeat the enumeration name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Cake {
|
||||
/// BlackForestCake,
|
||||
/// HummingbirdCake,
|
||||
/// BattenbergCake,
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects enumeration variants that are prefixed or suffixed
|
||||
/// by the same characters.
|
||||
///
|
||||
/// **Why is this bad?** Enumeration variant names should specify their variant,
|
||||
/// not repeat the enumeration name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Cake {
|
||||
/// BlackForestCake,
|
||||
/// HummingbirdCake,
|
||||
/// BattenbergCake,
|
||||
/// }
|
||||
/// ```
|
||||
pub ENUM_VARIANT_NAMES,
|
||||
style,
|
||||
"enums where all variants share a prefix/postfix"
|
||||
}
|
||||
|
||||
/// **What it does:** Detects enumeration variants that are prefixed or suffixed
|
||||
/// by the same characters.
|
||||
///
|
||||
/// **Why is this bad?** Enumeration variant names should specify their variant,
|
||||
/// not repeat the enumeration name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Cake {
|
||||
/// BlackForestCake,
|
||||
/// HummingbirdCake,
|
||||
/// BattenbergCake,
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects enumeration variants that are prefixed or suffixed
|
||||
/// by the same characters.
|
||||
///
|
||||
/// **Why is this bad?** Enumeration variant names should specify their variant,
|
||||
/// not repeat the enumeration name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Cake {
|
||||
/// BlackForestCake,
|
||||
/// HummingbirdCake,
|
||||
/// BattenbergCake,
|
||||
/// }
|
||||
/// ```
|
||||
pub PUB_ENUM_VARIANT_NAMES,
|
||||
pedantic,
|
||||
"enums where all variants share a prefix/postfix"
|
||||
}
|
||||
|
||||
/// **What it does:** Detects type names that are prefixed or suffixed by the
|
||||
/// containing module's name.
|
||||
///
|
||||
/// **Why is this bad?** It requires the user to type the module name twice.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mod cake {
|
||||
/// struct BlackForestCake;
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects type names that are prefixed or suffixed by the
|
||||
/// containing module's name.
|
||||
///
|
||||
/// **Why is this bad?** It requires the user to type the module name twice.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mod cake {
|
||||
/// struct BlackForestCake;
|
||||
/// }
|
||||
/// ```
|
||||
pub MODULE_NAME_REPETITIONS,
|
||||
pedantic,
|
||||
"type names prefixed/postfixed with their containing module's name"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for modules that have the same name as their
|
||||
/// parent module
|
||||
///
|
||||
/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and
|
||||
/// again `mod foo { ..
|
||||
/// }` in `foo.rs`.
|
||||
/// The expectation is that items inside the inner `mod foo { .. }` are then
|
||||
/// available
|
||||
/// through `foo::x`, but they are only available through
|
||||
/// `foo::foo::x`.
|
||||
/// If this is done on purpose, it would be better to choose a more
|
||||
/// representative module name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // lib.rs
|
||||
/// mod foo;
|
||||
/// // foo.rs
|
||||
/// mod foo {
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for modules that have the same name as their
|
||||
/// parent module
|
||||
///
|
||||
/// **Why is this bad?** A typical beginner mistake is to have `mod foo;` and
|
||||
/// again `mod foo { ..
|
||||
/// }` in `foo.rs`.
|
||||
/// The expectation is that items inside the inner `mod foo { .. }` are then
|
||||
/// available
|
||||
/// through `foo::x`, but they are only available through
|
||||
/// `foo::foo::x`.
|
||||
/// If this is done on purpose, it would be better to choose a more
|
||||
/// representative module name.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// // lib.rs
|
||||
/// mod foo;
|
||||
/// // foo.rs
|
||||
/// mod foo {
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
pub MODULE_INCEPTION,
|
||||
style,
|
||||
"modules that have the same name as their parent module"
|
||||
|
@ -6,40 +6,40 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for equal operands to comparison, logical and
|
||||
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
|
||||
/// `||`, `&`, `|`, `^`, `-` and `/`).
|
||||
///
|
||||
/// **Why is this bad?** This is usually just a typo or a copy and paste error.
|
||||
///
|
||||
/// **Known problems:** False negatives: We had some false positives regarding
|
||||
/// calls (notably [racer](https://github.com/phildawes/racer) had one instance
|
||||
/// of `x.pop() && x.pop()`), so we removed matching any function or method
|
||||
/// calls. We may introduce a whitelist of known pure functions in the future.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x + 1 == x + 1
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for equal operands to comparison, logical and
|
||||
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
|
||||
/// `||`, `&`, `|`, `^`, `-` and `/`).
|
||||
///
|
||||
/// **Why is this bad?** This is usually just a typo or a copy and paste error.
|
||||
///
|
||||
/// **Known problems:** False negatives: We had some false positives regarding
|
||||
/// calls (notably [racer](https://github.com/phildawes/racer) had one instance
|
||||
/// of `x.pop() && x.pop()`), so we removed matching any function or method
|
||||
/// calls. We may introduce a whitelist of known pure functions in the future.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// x + 1 == x + 1
|
||||
/// ```
|
||||
pub EQ_OP,
|
||||
correctness,
|
||||
"equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for arguments to `==` which have their address
|
||||
/// taken to satisfy a bound
|
||||
/// and suggests to dereference the other argument instead
|
||||
///
|
||||
/// **Why is this bad?** It is more idiomatic to dereference the other argument.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// &x == y
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for arguments to `==` which have their address
|
||||
/// taken to satisfy a bound
|
||||
/// and suggests to dereference the other argument instead
|
||||
///
|
||||
/// **Why is this bad?** It is more idiomatic to dereference the other argument.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// &x == y
|
||||
/// ```
|
||||
pub OP_REF,
|
||||
style,
|
||||
"taking a reference to satisfy the type constraints on `==`"
|
||||
|
@ -5,21 +5,21 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for erasing operations, e.g. `x * 0`.
|
||||
///
|
||||
/// **Why is this bad?** The whole expression can be replaced by zero.
|
||||
/// This is most likely not the intended outcome and should probably be
|
||||
/// corrected
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// 0 / x;
|
||||
/// 0 * x;
|
||||
/// x & 0
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for erasing operations, e.g. `x * 0`.
|
||||
///
|
||||
/// **Why is this bad?** The whole expression can be replaced by zero.
|
||||
/// This is most likely not the intended outcome and should probably be
|
||||
/// corrected
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// 0 / x;
|
||||
/// 0 * x;
|
||||
/// x & 0
|
||||
/// ```
|
||||
pub ERASING_OP,
|
||||
correctness,
|
||||
"using erasing operations, e.g. `x * 0` or `y & 0`"
|
||||
|
@ -14,24 +14,24 @@ pub struct Pass {
|
||||
pub too_large_for_stack: u64,
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for usage of `Box<T>` where an unboxed `T` would
|
||||
/// work fine.
|
||||
///
|
||||
/// **Why is this bad?** This is an unnecessary allocation, and bad for
|
||||
/// performance. It is only necessary to allocate if you wish to move the box
|
||||
/// into something.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// let x = Box::new(1);
|
||||
/// foo(*x);
|
||||
/// println!("{}", *x);
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `Box<T>` where an unboxed `T` would
|
||||
/// work fine.
|
||||
///
|
||||
/// **Why is this bad?** This is an unnecessary allocation, and bad for
|
||||
/// performance. It is only necessary to allocate if you wish to move the box
|
||||
/// into something.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// let x = Box::new(1);
|
||||
/// foo(*x);
|
||||
/// println!("{}", *x);
|
||||
/// }
|
||||
/// ```
|
||||
pub BOXED_LOCAL,
|
||||
perf,
|
||||
"using `Box<T>` where unnecessary"
|
||||
|
@ -8,26 +8,26 @@ use rustc_errors::Applicability;
|
||||
|
||||
pub struct EtaPass;
|
||||
|
||||
/// **What it does:** Checks for closures which just call another function where
|
||||
/// the function can be called directly. `unsafe` functions or calls where types
|
||||
/// get adjusted are ignored.
|
||||
///
|
||||
/// **Why is this bad?** Needlessly creating a closure adds code for no benefit
|
||||
/// and gives the optimizer more work.
|
||||
///
|
||||
/// **Known problems:** If creating the closure inside the closure has a side-
|
||||
/// effect then moving the closure creation out will change when that side-
|
||||
/// effect runs.
|
||||
/// See https://github.com/rust-lang/rust-clippy/issues/1439 for more
|
||||
/// details.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// xs.map(|x| foo(x))
|
||||
/// ```
|
||||
/// where `foo(_)` is a plain function that takes the exact argument type of
|
||||
/// `x`.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for closures which just call another function where
|
||||
/// the function can be called directly. `unsafe` functions or calls where types
|
||||
/// get adjusted are ignored.
|
||||
///
|
||||
/// **Why is this bad?** Needlessly creating a closure adds code for no benefit
|
||||
/// and gives the optimizer more work.
|
||||
///
|
||||
/// **Known problems:** If creating the closure inside the closure has a side-
|
||||
/// effect then moving the closure creation out will change when that side-
|
||||
/// effect runs.
|
||||
/// See https://github.com/rust-lang/rust-clippy/issues/1439 for more
|
||||
/// details.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// xs.map(|x| foo(x))
|
||||
/// ```
|
||||
/// where `foo(_)` is a plain function that takes the exact argument type of
|
||||
/// `x`.
|
||||
pub REDUNDANT_CLOSURE,
|
||||
style,
|
||||
"redundant closures, i.e. `|a| foo(a)` (which can be written as just `foo`)"
|
||||
|
@ -7,48 +7,48 @@ use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
|
||||
/// **What it does:** Checks for a read and a write to the same variable where
|
||||
/// whether the read occurs before or after the write depends on the evaluation
|
||||
/// order of sub-expressions.
|
||||
///
|
||||
/// **Why is this bad?** It is often confusing to read. In addition, the
|
||||
/// sub-expression evaluation order for Rust is not well documented.
|
||||
///
|
||||
/// **Known problems:** Code which intentionally depends on the evaluation
|
||||
/// order, or which is correct for any evaluation order.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut x = 0;
|
||||
/// let a = {
|
||||
/// x = 1;
|
||||
/// 1
|
||||
/// } + x;
|
||||
/// // Unclear whether a is 1 or 2.
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for a read and a write to the same variable where
|
||||
/// whether the read occurs before or after the write depends on the evaluation
|
||||
/// order of sub-expressions.
|
||||
///
|
||||
/// **Why is this bad?** It is often confusing to read. In addition, the
|
||||
/// sub-expression evaluation order for Rust is not well documented.
|
||||
///
|
||||
/// **Known problems:** Code which intentionally depends on the evaluation
|
||||
/// order, or which is correct for any evaluation order.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut x = 0;
|
||||
/// let a = {
|
||||
/// x = 1;
|
||||
/// 1
|
||||
/// } + x;
|
||||
/// // Unclear whether a is 1 or 2.
|
||||
/// ```
|
||||
pub EVAL_ORDER_DEPENDENCE,
|
||||
complexity,
|
||||
"whether a variable read occurs before a write depends on sub-expression evaluation order"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for diverging calls that are not match arms or
|
||||
/// statements.
|
||||
///
|
||||
/// **Why is this bad?** It is often confusing to read. In addition, the
|
||||
/// sub-expression evaluation order for Rust is not well documented.
|
||||
///
|
||||
/// **Known problems:** Someone might want to use `some_bool || panic!()` as a
|
||||
/// shorthand.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let a = b() || panic!() || c();
|
||||
/// // `c()` is dead, `panic!()` is only called if `b()` returns `false`
|
||||
/// let x = (a, b, c, panic!());
|
||||
/// // can simply be replaced by `panic!()`
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for diverging calls that are not match arms or
|
||||
/// statements.
|
||||
///
|
||||
/// **Why is this bad?** It is often confusing to read. In addition, the
|
||||
/// sub-expression evaluation order for Rust is not well documented.
|
||||
///
|
||||
/// **Known problems:** Someone might want to use `some_bool || panic!()` as a
|
||||
/// shorthand.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let a = b() || panic!() || c();
|
||||
/// // `c()` is dead, `panic!()` is only called if `b()` returns `false`
|
||||
/// let x = (a, b, c, panic!());
|
||||
/// // can simply be replaced by `panic!()`
|
||||
/// ```
|
||||
pub DIVERGING_SUB_EXPRESSION,
|
||||
complexity,
|
||||
"whether an expression contains a diverging sub expression"
|
||||
|
@ -11,25 +11,25 @@ use std::fmt;
|
||||
use syntax::ast::*;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
/// **What it does:** Checks for float literals with a precision greater
|
||||
/// than that supported by the underlying type
|
||||
///
|
||||
/// **Why is this bad?** Rust will truncate the literal silently.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let v: f32 = 0.123_456_789_9;
|
||||
/// println!("{}", v); // 0.123_456_789
|
||||
///
|
||||
/// // Good
|
||||
/// let v: f64 = 0.123_456_789_9;
|
||||
/// println!("{}", v); // 0.123_456_789_9
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for float literals with a precision greater
|
||||
/// than that supported by the underlying type
|
||||
///
|
||||
/// **Why is this bad?** Rust will truncate the literal silently.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// // Bad
|
||||
/// let v: f32 = 0.123_456_789_9;
|
||||
/// println!("{}", v); // 0.123_456_789
|
||||
///
|
||||
/// // Good
|
||||
/// let v: f64 = 0.123_456_789_9;
|
||||
/// println!("{}", v); // 0.123_456_789_9
|
||||
/// ```
|
||||
pub EXCESSIVE_PRECISION,
|
||||
style,
|
||||
"excessive precision for float literal"
|
||||
|
@ -6,19 +6,19 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
|
||||
/// **What it does:** Checks for usage of `write!()` / `writeln()!` which can be
|
||||
/// replaced with `(e)print!()` / `(e)println!()`
|
||||
///
|
||||
/// **Why is this bad?** Using `(e)println! is clearer and more concise
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // this would be clearer as `eprintln!("foo: {:?}", bar);`
|
||||
/// writeln!(&mut io::stderr(), "foo: {:?}", bar).unwrap();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `write!()` / `writeln()!` which can be
|
||||
/// replaced with `(e)print!()` / `(e)println!()`
|
||||
///
|
||||
/// **Why is this bad?** Using `(e)println! is clearer and more concise
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // this would be clearer as `eprintln!("foo: {:?}", bar);`
|
||||
/// writeln!(&mut io::stderr(), "foo: {:?}", bar).unwrap();
|
||||
/// ```
|
||||
pub EXPLICIT_WRITE,
|
||||
complexity,
|
||||
"using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work"
|
||||
|
@ -7,22 +7,22 @@ use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
|
||||
///
|
||||
/// **Why is this bad?** `TryFrom` should be used if there's a possibility of failure.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct Foo(i32);
|
||||
/// impl From<String> for Foo {
|
||||
/// fn from(s: String) -> Self {
|
||||
/// Foo(s.parse().unwrap())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`
|
||||
///
|
||||
/// **Why is this bad?** `TryFrom` should be used if there's a possibility of failure.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct Foo(i32);
|
||||
/// impl From<String> for Foo {
|
||||
/// fn from(s: String) -> Self {
|
||||
/// Foo(s.parse().unwrap())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub FALLIBLE_IMPL_FROM,
|
||||
nursery,
|
||||
"Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`"
|
||||
|
@ -12,23 +12,23 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for the use of `format!("string literal with no
|
||||
/// argument")` and `format!("{}", foo)` where `foo` is a string.
|
||||
///
|
||||
/// **Why is this bad?** There is no point of doing that. `format!("foo")` can
|
||||
/// be replaced by `"foo".to_owned()` if you really need a `String`. The even
|
||||
/// worse `&format!("foo")` is often encountered in the wild. `format!("{}",
|
||||
/// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`
|
||||
/// if `foo: &str`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ```rust
|
||||
/// format!("foo")
|
||||
/// format!("{}", foo)
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the use of `format!("string literal with no
|
||||
/// argument")` and `format!("{}", foo)` where `foo` is a string.
|
||||
///
|
||||
/// **Why is this bad?** There is no point of doing that. `format!("foo")` can
|
||||
/// be replaced by `"foo".to_owned()` if you really need a `String`. The even
|
||||
/// worse `&format!("foo")` is often encountered in the wild. `format!("{}",
|
||||
/// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`
|
||||
/// if `foo: &str`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Examples:**
|
||||
/// ```rust
|
||||
/// format!("foo")
|
||||
/// format!("{}", foo)
|
||||
/// ```
|
||||
pub USELESS_FORMAT,
|
||||
complexity,
|
||||
"useless use of `format!`"
|
||||
|
@ -4,75 +4,75 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
use syntax::ptr::P;
|
||||
|
||||
/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-`
|
||||
/// operators.
|
||||
///
|
||||
/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or
|
||||
/// confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for use of the non-existent `=*`, `=!` and `=-`
|
||||
/// operators.
|
||||
///
|
||||
/// **Why is this bad?** This is either a typo of `*=`, `!=` or `-=` or
|
||||
/// confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?
|
||||
/// ```
|
||||
pub SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||
style,
|
||||
"suspicious formatting of `*=`, `-=` or `!=`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for formatting of `else`. It lints if the `else`
|
||||
/// is followed immediately by a newline or the `else` seems to be missing.
|
||||
///
|
||||
/// **Why is this bad?** This is probably some refactoring remnant, even if the
|
||||
/// code is correct, it might look confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// if foo {
|
||||
/// } { // looks like an `else` is missing here
|
||||
/// }
|
||||
///
|
||||
/// if foo {
|
||||
/// } if bar { // looks like an `else` is missing here
|
||||
/// }
|
||||
///
|
||||
/// if foo {
|
||||
/// } else
|
||||
///
|
||||
/// { // this is the `else` block of the previous `if`, but should it be?
|
||||
/// }
|
||||
///
|
||||
/// if foo {
|
||||
/// } else
|
||||
///
|
||||
/// if bar { // this is the `else` block of the previous `if`, but should it be?
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for formatting of `else`. It lints if the `else`
|
||||
/// is followed immediately by a newline or the `else` seems to be missing.
|
||||
///
|
||||
/// **Why is this bad?** This is probably some refactoring remnant, even if the
|
||||
/// code is correct, it might look confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// if foo {
|
||||
/// } { // looks like an `else` is missing here
|
||||
/// }
|
||||
///
|
||||
/// if foo {
|
||||
/// } if bar { // looks like an `else` is missing here
|
||||
/// }
|
||||
///
|
||||
/// if foo {
|
||||
/// } else
|
||||
///
|
||||
/// { // this is the `else` block of the previous `if`, but should it be?
|
||||
/// }
|
||||
///
|
||||
/// if foo {
|
||||
/// } else
|
||||
///
|
||||
/// if bar { // this is the `else` block of the previous `if`, but should it be?
|
||||
/// }
|
||||
/// ```
|
||||
pub SUSPICIOUS_ELSE_FORMATTING,
|
||||
style,
|
||||
"suspicious formatting of `else`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for possible missing comma in an array. It lints if
|
||||
/// an array element is a binary operator expression and it lies on two lines.
|
||||
///
|
||||
/// **Why is this bad?** This could lead to unexpected results.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// let a = &[
|
||||
/// -1, -2, -3 // <= no comma here
|
||||
/// -4, -5, -6
|
||||
/// ];
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for possible missing comma in an array. It lints if
|
||||
/// an array element is a binary operator expression and it lies on two lines.
|
||||
///
|
||||
/// **Why is this bad?** This could lead to unexpected results.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// let a = &[
|
||||
/// -1, -2, -3 // <= no comma here
|
||||
/// -4, -5, -6
|
||||
/// ];
|
||||
/// ```
|
||||
pub POSSIBLE_MISSING_COMMA,
|
||||
correctness,
|
||||
"possible missing comma in array"
|
||||
|
@ -11,72 +11,72 @@ use rustc_target::spec::abi::Abi;
|
||||
use syntax::ast;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for functions with too many parameters.
|
||||
///
|
||||
/// **Why is this bad?** Functions with lots of parameters are considered bad
|
||||
/// style and reduce readability (“what does the 5th parameter mean?”). Consider
|
||||
/// grouping some parameters into a new type.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for functions with too many parameters.
|
||||
///
|
||||
/// **Why is this bad?** Functions with lots of parameters are considered bad
|
||||
/// style and reduce readability (“what does the 5th parameter mean?”). Consider
|
||||
/// grouping some parameters into a new type.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub TOO_MANY_ARGUMENTS,
|
||||
complexity,
|
||||
"functions with too many arguments"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for functions with a large amount of lines.
|
||||
///
|
||||
/// **Why is this bad?** Functions with a lot of lines are harder to understand
|
||||
/// due to having to look at a larger amount of code to understand what the
|
||||
/// function is doing. Consider splitting the body of the function into
|
||||
/// multiple functions.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ``` rust
|
||||
/// fn im_too_long() {
|
||||
/// println!("");
|
||||
/// // ... 100 more LoC
|
||||
/// println!("");
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for functions with a large amount of lines.
|
||||
///
|
||||
/// **Why is this bad?** Functions with a lot of lines are harder to understand
|
||||
/// due to having to look at a larger amount of code to understand what the
|
||||
/// function is doing. Consider splitting the body of the function into
|
||||
/// multiple functions.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ``` rust
|
||||
/// fn im_too_long() {
|
||||
/// println!("");
|
||||
/// // ... 100 more LoC
|
||||
/// println!("");
|
||||
/// }
|
||||
/// ```
|
||||
pub TOO_MANY_LINES,
|
||||
pedantic,
|
||||
"functions with too many lines"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for public functions that dereferences raw pointer
|
||||
/// arguments but are not marked unsafe.
|
||||
///
|
||||
/// **Why is this bad?** The function should probably be marked `unsafe`, since
|
||||
/// for an arbitrary raw pointer, there is no way of telling for sure if it is
|
||||
/// valid.
|
||||
///
|
||||
/// **Known problems:**
|
||||
///
|
||||
/// * It does not check functions recursively so if the pointer is passed to a
|
||||
/// private non-`unsafe` function which does the dereferencing, the lint won't
|
||||
/// trigger.
|
||||
/// * It only checks for arguments whose type are raw pointers, not raw pointers
|
||||
/// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
|
||||
/// `some_argument.get_raw_ptr()`).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// pub fn foo(x: *const u8) {
|
||||
/// println!("{}", unsafe { *x });
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for public functions that dereferences raw pointer
|
||||
/// arguments but are not marked unsafe.
|
||||
///
|
||||
/// **Why is this bad?** The function should probably be marked `unsafe`, since
|
||||
/// for an arbitrary raw pointer, there is no way of telling for sure if it is
|
||||
/// valid.
|
||||
///
|
||||
/// **Known problems:**
|
||||
///
|
||||
/// * It does not check functions recursively so if the pointer is passed to a
|
||||
/// private non-`unsafe` function which does the dereferencing, the lint won't
|
||||
/// trigger.
|
||||
/// * It only checks for arguments whose type are raw pointers, not raw pointers
|
||||
/// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
|
||||
/// `some_argument.get_raw_ptr()`).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// pub fn foo(x: *const u8) {
|
||||
/// println!("{}", unsafe { *x });
|
||||
/// }
|
||||
/// ```
|
||||
pub NOT_UNSAFE_PTR_ARG_DEREF,
|
||||
correctness,
|
||||
"public functions dereferencing raw pointer arguments but not marked `unsafe`"
|
||||
|
@ -7,18 +7,18 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for always-identical `Into`/`From`/`IntoIter` conversions.
|
||||
///
|
||||
/// **Why is this bad?** Redundant code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // format!() returns a `String`
|
||||
/// let s: String = format!("hello").into();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for always-identical `Into`/`From`/`IntoIter` conversions.
|
||||
///
|
||||
/// **Why is this bad?** Redundant code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // format!() returns a `String`
|
||||
/// let s: String = format!("hello").into();
|
||||
/// ```
|
||||
pub IDENTITY_CONVERSION,
|
||||
complexity,
|
||||
"using always-identical `Into`/`From`/`IntoIter` conversions"
|
||||
|
@ -6,18 +6,18 @@ use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for identity operations, e.g. `x + 0`.
|
||||
///
|
||||
/// **Why is this bad?** This code can be removed without changing the
|
||||
/// meaning. So it just obscures what's going on. Delete it mercilessly.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x / 1 + 0 * 1 - 0 | 0
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for identity operations, e.g. `x + 0`.
|
||||
///
|
||||
/// **Why is this bad?** This code can be removed without changing the
|
||||
/// meaning. So it just obscures what's going on. Delete it mercilessly.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x / 1 + 0 * 1 - 0 | 0
|
||||
/// ```
|
||||
pub IDENTITY_OP,
|
||||
complexity,
|
||||
"using identity operations, e.g. `x + 0` or `y / 1`"
|
||||
|
@ -7,32 +7,32 @@ use syntax::ast::*;
|
||||
|
||||
use crate::utils::span_help_and_lint;
|
||||
|
||||
/// **What it does:** Checks for usage of `!` or `!=` in an if condition with an
|
||||
/// else branch.
|
||||
///
|
||||
/// **Why is this bad?** Negations reduce the readability of statements.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if !v.is_empty() {
|
||||
/// a()
|
||||
/// } else {
|
||||
/// b()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// if v.is_empty() {
|
||||
/// b()
|
||||
/// } else {
|
||||
/// a()
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `!` or `!=` in an if condition with an
|
||||
/// else branch.
|
||||
///
|
||||
/// **Why is this bad?** Negations reduce the readability of statements.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if !v.is_empty() {
|
||||
/// a()
|
||||
/// } else {
|
||||
/// b()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// if v.is_empty() {
|
||||
/// b()
|
||||
/// } else {
|
||||
/// a()
|
||||
/// }
|
||||
/// ```
|
||||
pub IF_NOT_ELSE,
|
||||
pedantic,
|
||||
"`if` branches that could be swapped so no negation operation is necessary on the condition"
|
||||
|
@ -5,29 +5,29 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for missing return statements at the end of a block.
|
||||
///
|
||||
/// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
|
||||
/// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
|
||||
/// the last returning statement because the only difference is a missing `;`. Especially in bigger
|
||||
/// code with multiple return paths having a `return` keyword makes it easier to find the
|
||||
/// corresponding statements.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(x: usize) {
|
||||
/// x
|
||||
/// }
|
||||
/// ```
|
||||
/// add return
|
||||
/// ```rust
|
||||
/// fn foo(x: usize) {
|
||||
/// return x;
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for missing return statements at the end of a block.
|
||||
///
|
||||
/// **Why is this bad?** Actually omitting the return keyword is idiomatic Rust code. Programmers
|
||||
/// coming from other languages might prefer the expressiveness of `return`. It's possible to miss
|
||||
/// the last returning statement because the only difference is a missing `;`. Especially in bigger
|
||||
/// code with multiple return paths having a `return` keyword makes it easier to find the
|
||||
/// corresponding statements.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(x: usize) {
|
||||
/// x
|
||||
/// }
|
||||
/// ```
|
||||
/// add return
|
||||
/// ```rust
|
||||
/// fn foo(x: usize) {
|
||||
/// return x;
|
||||
/// }
|
||||
/// ```
|
||||
pub IMPLICIT_RETURN,
|
||||
restriction,
|
||||
"use a return statement like `return expr` instead of an expression"
|
||||
|
@ -10,75 +10,76 @@ use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::RangeLimits;
|
||||
|
||||
/// **What it does:** Checks for out of bounds array indexing with a constant
|
||||
/// index.
|
||||
///
|
||||
/// **Why is this bad?** This will always panic at runtime.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = [1, 2, 3, 4];
|
||||
///
|
||||
/// // Bad
|
||||
/// x[9];
|
||||
/// &x[2..9];
|
||||
///
|
||||
/// // Good
|
||||
/// x[0];
|
||||
/// x[3];
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for out of bounds array indexing with a constant
|
||||
/// index.
|
||||
///
|
||||
/// **Why is this bad?** This will always panic at runtime.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// # #![allow(const_err)]
|
||||
/// let x = [1, 2, 3, 4];
|
||||
///
|
||||
/// // Bad
|
||||
/// x[9];
|
||||
/// &x[2..9];
|
||||
///
|
||||
/// // Good
|
||||
/// x[0];
|
||||
/// x[3];
|
||||
/// ```
|
||||
pub OUT_OF_BOUNDS_INDEXING,
|
||||
correctness,
|
||||
"out of bounds constant indexing"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for usage of indexing or slicing. Arrays are special cased, this lint
|
||||
/// does report on arrays if we can tell that slicing operations are in bounds and does not
|
||||
/// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
|
||||
///
|
||||
/// **Why is this bad?** Indexing and slicing can panic at runtime and there are
|
||||
/// safe alternatives.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Vector
|
||||
/// let x = vec![0; 5];
|
||||
///
|
||||
/// // Bad
|
||||
/// x[2];
|
||||
/// &x[2..100];
|
||||
/// &x[2..];
|
||||
/// &x[..100];
|
||||
///
|
||||
/// // Good
|
||||
/// x.get(2);
|
||||
/// x.get(2..100);
|
||||
/// x.get(2..);
|
||||
/// x.get(..100);
|
||||
///
|
||||
/// // Array
|
||||
/// let y = [0, 1, 2, 3];
|
||||
///
|
||||
/// // Bad
|
||||
/// &y[10..100];
|
||||
/// &y[10..];
|
||||
/// &y[..100];
|
||||
///
|
||||
/// // Good
|
||||
/// &y[2..];
|
||||
/// &y[..2];
|
||||
/// &y[0..3];
|
||||
/// y.get(10);
|
||||
/// y.get(10..100);
|
||||
/// y.get(10..);
|
||||
/// y.get(..100);
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of indexing or slicing. Arrays are special cased, this lint
|
||||
/// does report on arrays if we can tell that slicing operations are in bounds and does not
|
||||
/// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
|
||||
///
|
||||
/// **Why is this bad?** Indexing and slicing can panic at runtime and there are
|
||||
/// safe alternatives.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // Vector
|
||||
/// let x = vec![0; 5];
|
||||
///
|
||||
/// // Bad
|
||||
/// x[2];
|
||||
/// &x[2..100];
|
||||
/// &x[2..];
|
||||
/// &x[..100];
|
||||
///
|
||||
/// // Good
|
||||
/// x.get(2);
|
||||
/// x.get(2..100);
|
||||
/// x.get(2..);
|
||||
/// x.get(..100);
|
||||
///
|
||||
/// // Array
|
||||
/// let y = [0, 1, 2, 3];
|
||||
///
|
||||
/// // Bad
|
||||
/// &y[10..100];
|
||||
/// &y[10..];
|
||||
/// &y[..100];
|
||||
///
|
||||
/// // Good
|
||||
/// &y[2..];
|
||||
/// &y[..2];
|
||||
/// &y[0..3];
|
||||
/// y.get(10);
|
||||
/// y.get(10..100);
|
||||
/// y.get(10..);
|
||||
/// y.get(..100);
|
||||
/// ```
|
||||
pub INDEXING_SLICING,
|
||||
restriction,
|
||||
"indexing/slicing usage"
|
||||
|
@ -5,36 +5,36 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for matches being used to destructure a single-variant enum
|
||||
/// or tuple struct where a `let` will suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `let` doesn't nest, whereas a `match` does.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Wrapper {
|
||||
/// Data(i32),
|
||||
/// }
|
||||
///
|
||||
/// let wrapper = Wrapper::Data(42);
|
||||
///
|
||||
/// let data = match wrapper {
|
||||
/// Wrapper::Data(i) => i,
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
/// ```rust
|
||||
/// enum Wrapper {
|
||||
/// Data(i32),
|
||||
/// }
|
||||
///
|
||||
/// let wrapper = Wrapper::Data(42);
|
||||
/// let Wrapper::Data(data) = wrapper;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for matches being used to destructure a single-variant enum
|
||||
/// or tuple struct where a `let` will suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `let` doesn't nest, whereas a `match` does.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Wrapper {
|
||||
/// Data(i32),
|
||||
/// }
|
||||
///
|
||||
/// let wrapper = Wrapper::Data(42);
|
||||
///
|
||||
/// let data = match wrapper {
|
||||
/// Wrapper::Data(i) => i,
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
/// ```rust
|
||||
/// enum Wrapper {
|
||||
/// Data(i32),
|
||||
/// }
|
||||
///
|
||||
/// let wrapper = Wrapper::Data(42);
|
||||
/// let Wrapper::Data(data) = wrapper;
|
||||
/// ```
|
||||
pub INFALLIBLE_DESTRUCTURING_MATCH,
|
||||
style,
|
||||
"a match statement with a single infallible arm instead of a `let`"
|
||||
|
@ -3,36 +3,38 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// (e.g. in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// repeat(1_u8).iter().collect::<Vec<_>>()
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// (e.g. in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// use std::iter;
|
||||
///
|
||||
/// iter::repeat(1_u8).collect::<Vec<_>>();
|
||||
/// ```
|
||||
pub INFINITE_ITER,
|
||||
correctness,
|
||||
"infinite iteration"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for iteration that may be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// (e.g. in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** The code may have a condition to stop iteration, but
|
||||
/// this lint is not clever enough to analyze it.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// [0..].iter().zip(infinite_iter.take_while(|x| x > 5))
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iteration that may be infinite.
|
||||
///
|
||||
/// **Why is this bad?** While there may be places where this is acceptable
|
||||
/// (e.g. in event streams), in most cases this is simply an error.
|
||||
///
|
||||
/// **Known problems:** The code may have a condition to stop iteration, but
|
||||
/// this lint is not clever enough to analyze it.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// [0..].iter().zip(infinite_iter.take_while(|x| x > 5))
|
||||
/// ```
|
||||
pub MAYBE_INFINITE_ITER,
|
||||
pedantic,
|
||||
"possible infinite iteration"
|
||||
|
@ -8,33 +8,33 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use std::default::Default;
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// **What it does:** Checks for multiple inherent implementations of a struct
|
||||
///
|
||||
/// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct X;
|
||||
/// impl X {
|
||||
/// fn one() {}
|
||||
/// }
|
||||
/// impl X {
|
||||
/// fn other() {}
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct X;
|
||||
/// impl X {
|
||||
/// fn one() {}
|
||||
/// fn other() {}
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for multiple inherent implementations of a struct
|
||||
///
|
||||
/// **Why is this bad?** Splitting the implementation of a type makes the code harder to navigate.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct X;
|
||||
/// impl X {
|
||||
/// fn one() {}
|
||||
/// }
|
||||
/// impl X {
|
||||
/// fn other() {}
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct X;
|
||||
/// impl X {
|
||||
/// fn one() {}
|
||||
/// fn other() {}
|
||||
/// }
|
||||
/// ```
|
||||
pub MULTIPLE_INHERENT_IMPL,
|
||||
restriction,
|
||||
"Multiple inherent impl that could be grouped"
|
||||
|
@ -8,21 +8,21 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast::{Attribute, Name};
|
||||
|
||||
/// **What it does:** Checks for `#[inline]` on trait methods without bodies
|
||||
///
|
||||
/// **Why is this bad?** Only implementations of trait methods may be inlined.
|
||||
/// The inline attribute is ignored for trait methods without bodies.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// trait Animal {
|
||||
/// #[inline]
|
||||
/// fn name(&self) -> &'static str;
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `#[inline]` on trait methods without bodies
|
||||
///
|
||||
/// **Why is this bad?** Only implementations of trait methods may be inlined.
|
||||
/// The inline attribute is ignored for trait methods without bodies.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// trait Animal {
|
||||
/// #[inline]
|
||||
/// fn name(&self) -> &'static str;
|
||||
/// }
|
||||
/// ```
|
||||
pub INLINE_FN_WITHOUT_BODY,
|
||||
correctness,
|
||||
"use of `#[inline]` on trait methods without bodies"
|
||||
|
@ -7,24 +7,24 @@ use syntax::ast::*;
|
||||
|
||||
use crate::utils::{snippet_opt, span_lint_and_then};
|
||||
|
||||
/// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
|
||||
///
|
||||
///
|
||||
/// **Why is this bad?** Readability -- better to use `> y` instead of `>= y + 1`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x >= y + 1
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// x > y
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block
|
||||
///
|
||||
///
|
||||
/// **Why is this bad?** Readability -- better to use `> y` instead of `>= y + 1`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x >= y + 1
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// x > y
|
||||
/// ```
|
||||
pub INT_PLUS_ONE,
|
||||
complexity,
|
||||
"instead of using x >= y + 1, use x > y"
|
||||
|
@ -5,17 +5,17 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for creation of references to zeroed or uninitialized memory.
|
||||
///
|
||||
/// **Why is this bad?** Creation of null references is undefined behavior.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let bad_ref: &usize = std::mem::zeroed();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for creation of references to zeroed or uninitialized memory.
|
||||
///
|
||||
/// **Why is this bad?** Creation of null references is undefined behavior.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// let bad_ref: &usize = unsafe { std::mem::zeroed() };
|
||||
/// ```
|
||||
pub INVALID_REF,
|
||||
correctness,
|
||||
"creation of invalid reference"
|
||||
|
@ -6,29 +6,29 @@ use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
|
||||
/// **What it does:** Checks for items declared after some statement in a block.
|
||||
///
|
||||
/// **Why is this bad?** Items live for the entire scope they are declared
|
||||
/// in. But statements are processed in order. This might cause confusion as
|
||||
/// it's hard to figure out which item is meant in a statement.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo() {
|
||||
/// println!("cake");
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// foo(); // prints "foo"
|
||||
/// fn foo() {
|
||||
/// println!("foo");
|
||||
/// }
|
||||
/// foo(); // prints "foo"
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items declared after some statement in a block.
|
||||
///
|
||||
/// **Why is this bad?** Items live for the entire scope they are declared
|
||||
/// in. But statements are processed in order. This might cause confusion as
|
||||
/// it's hard to figure out which item is meant in a statement.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo() {
|
||||
/// println!("cake");
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// foo(); // prints "foo"
|
||||
/// fn foo() {
|
||||
/// println!("foo");
|
||||
/// }
|
||||
/// foo(); // prints "foo"
|
||||
/// }
|
||||
/// ```
|
||||
pub ITEMS_AFTER_STATEMENTS,
|
||||
pedantic,
|
||||
"blocks where an item comes after a statement"
|
||||
|
@ -7,23 +7,23 @@ use rustc::ty::layout::LayoutOf;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for large size differences between variants on
|
||||
/// `enum`s.
|
||||
///
|
||||
/// **Why is this bad?** Enum size is bounded by the largest variant. Having a
|
||||
/// large variant
|
||||
/// can penalize the memory layout of that enum.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Test {
|
||||
/// A(i32),
|
||||
/// B([i32; 8000]),
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for large size differences between variants on
|
||||
/// `enum`s.
|
||||
///
|
||||
/// **Why is this bad?** Enum size is bounded by the largest variant. Having a
|
||||
/// large variant
|
||||
/// can penalize the memory layout of that enum.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Test {
|
||||
/// A(i32),
|
||||
/// B([i32; 8000]),
|
||||
/// }
|
||||
/// ```
|
||||
pub LARGE_ENUM_VARIANT,
|
||||
perf,
|
||||
"large size difference between variants on an enum"
|
||||
|
@ -9,62 +9,61 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::{Lit, LitKind, Name};
|
||||
use syntax::source_map::{Span, Spanned};
|
||||
|
||||
/// **What it does:** Checks for getting the length of something via `.len()`
|
||||
/// just to compare to zero, and suggests using `.is_empty()` where applicable.
|
||||
///
|
||||
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster
|
||||
/// than calculating their length. Notably, for slices, getting the length
|
||||
/// requires a subtraction whereas `.is_empty()` is just a comparison. So it is
|
||||
/// good to get into the habit of using `.is_empty()`, and having it is cheap.
|
||||
/// Besides, it makes the intent clearer than a manual comparison.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x.len() == 0 {
|
||||
/// ..
|
||||
/// }
|
||||
/// if y.len() != 0 {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
/// instead use
|
||||
/// ```rust
|
||||
/// if x.is_empty() {
|
||||
/// ..
|
||||
/// }
|
||||
/// if !y.is_empty() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub LEN_ZERO,
|
||||
style,
|
||||
"checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` \
|
||||
could be used instead"
|
||||
/// **What it does:** Checks for getting the length of something via `.len()`
|
||||
/// just to compare to zero, and suggests using `.is_empty()` where applicable.
|
||||
///
|
||||
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster
|
||||
/// than calculating their length. Notably, for slices, getting the length
|
||||
/// requires a subtraction whereas `.is_empty()` is just a comparison. So it is
|
||||
/// good to get into the habit of using `.is_empty()`, and having it is cheap.
|
||||
/// Besides, it makes the intent clearer than a manual comparison.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if x.len() == 0 {
|
||||
/// ..
|
||||
/// }
|
||||
/// if y.len() != 0 {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
/// instead use
|
||||
/// ```ignore
|
||||
/// if x.is_empty() {
|
||||
/// ..
|
||||
/// }
|
||||
/// if !y.is_empty() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub LEN_ZERO,
|
||||
style,
|
||||
"checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for items that implement `.len()` but not
|
||||
/// `.is_empty()`.
|
||||
///
|
||||
/// **Why is this bad?** It is good custom to have both methods, because for
|
||||
/// some data structures, asking about the length will be a costly operation,
|
||||
/// whereas `.is_empty()` can usually answer in constant time. Also it used to
|
||||
/// lead to false positives on the [`len_zero`](#len_zero) lint – currently that
|
||||
/// lint will ignore such entities.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// impl X {
|
||||
/// pub fn len(&self) -> usize {
|
||||
/// ..
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for items that implement `.len()` but not
|
||||
/// `.is_empty()`.
|
||||
///
|
||||
/// **Why is this bad?** It is good custom to have both methods, because for
|
||||
/// some data structures, asking about the length will be a costly operation,
|
||||
/// whereas `.is_empty()` can usually answer in constant time. Also it used to
|
||||
/// lead to false positives on the [`len_zero`](#len_zero) lint – currently that
|
||||
/// lint will ignore such entities.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// impl X {
|
||||
/// pub fn len(&self) -> usize {
|
||||
/// ..
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub LEN_WITHOUT_IS_EMPTY,
|
||||
style,
|
||||
"traits or impls with a public `len` method but no corresponding `is_empty` method"
|
||||
|
@ -8,46 +8,46 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast;
|
||||
|
||||
/// **What it does:** Checks for variable declarations immediately followed by a
|
||||
/// conditional affectation.
|
||||
///
|
||||
/// **Why is this bad?** This is not idiomatic Rust.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// let foo;
|
||||
///
|
||||
/// if bar() {
|
||||
/// foo = 42;
|
||||
/// } else {
|
||||
/// foo = 0;
|
||||
/// }
|
||||
///
|
||||
/// let mut baz = None;
|
||||
///
|
||||
/// if bar() {
|
||||
/// baz = Some(42);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// should be written
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// let foo = if bar() {
|
||||
/// 42
|
||||
/// } else {
|
||||
/// 0
|
||||
/// };
|
||||
///
|
||||
/// let baz = if bar() {
|
||||
/// Some(42)
|
||||
/// } else {
|
||||
/// None
|
||||
/// };
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for variable declarations immediately followed by a
|
||||
/// conditional affectation.
|
||||
///
|
||||
/// **Why is this bad?** This is not idiomatic Rust.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust,ignore
|
||||
/// let foo;
|
||||
///
|
||||
/// if bar() {
|
||||
/// foo = 42;
|
||||
/// } else {
|
||||
/// foo = 0;
|
||||
/// }
|
||||
///
|
||||
/// let mut baz = None;
|
||||
///
|
||||
/// if bar() {
|
||||
/// baz = Some(42);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// should be written
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// let foo = if bar() {
|
||||
/// 42
|
||||
/// } else {
|
||||
/// 0
|
||||
/// };
|
||||
///
|
||||
/// let baz = if bar() {
|
||||
/// Some(42)
|
||||
/// } else {
|
||||
/// None
|
||||
/// };
|
||||
/// ```
|
||||
pub USELESS_LET_IF_SEQ,
|
||||
style,
|
||||
"unidiomatic `let mut` declaration followed by initialization in `if`"
|
||||
|
@ -39,7 +39,7 @@ use toml;
|
||||
///
|
||||
/// Every lint declaration consists of 4 parts:
|
||||
///
|
||||
/// 1. The documentation above the lint, which is used for the website
|
||||
/// 1. The documentation, which is used for the website
|
||||
/// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions.
|
||||
/// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or
|
||||
/// `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
|
||||
@ -60,6 +60,7 @@ use toml;
|
||||
/// # use clippy_lints::declare_clippy_lint;
|
||||
/// use rustc::declare_tool_lint;
|
||||
///
|
||||
/// declare_clippy_lint! {
|
||||
/// /// **What it does:** Checks for ... (describe what the lint matches).
|
||||
/// ///
|
||||
/// /// **Why is this bad?** Supply the reason for linting the code.
|
||||
@ -75,7 +76,6 @@ use toml;
|
||||
/// /// // Good
|
||||
/// /// Insert a short example of improved code that doesn't trigger the lint
|
||||
/// /// ```
|
||||
/// declare_clippy_lint! {
|
||||
/// pub LINT_NAME,
|
||||
/// pedantic,
|
||||
/// "description"
|
||||
@ -84,35 +84,55 @@ use toml;
|
||||
/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
|
||||
#[macro_export]
|
||||
macro_rules! declare_clippy_lint {
|
||||
{ pub $name:tt, style, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, style, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
$(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, correctness, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Deny, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, correctness, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
$(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, complexity, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, perf, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, perf, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, pedantic, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, pedantic, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, restriction, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, restriction, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, cargo, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, cargo, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, nursery, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, nursery, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, internal, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, internal, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
{ pub $name:tt, internal_warn, $description:tt } => {
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
{ $(#[$attr:meta])* pub $name:tt, internal_warn, $description:tt } => {
|
||||
declare_tool_lint! {
|
||||
pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -10,45 +10,45 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::keywords;
|
||||
|
||||
/// **What it does:** Checks for lifetime annotations which can be removed by
|
||||
/// relying on lifetime elision.
|
||||
///
|
||||
/// **Why is this bad?** The additional lifetimes make the code look more
|
||||
/// complicated, while there is nothing out of the ordinary going on. Removing
|
||||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:** Potential false negatives: we bail out if the function
|
||||
/// has a `where` clause where lifetimes are mentioned.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {
|
||||
/// x
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub NEEDLESS_LIFETIMES,
|
||||
complexity,
|
||||
"using explicit lifetimes for references in function arguments when elision rules \
|
||||
/// **What it does:** Checks for lifetime annotations which can be removed by
|
||||
/// relying on lifetime elision.
|
||||
///
|
||||
/// **Why is this bad?** The additional lifetimes make the code look more
|
||||
/// complicated, while there is nothing out of the ordinary going on. Removing
|
||||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:** Potential false negatives: we bail out if the function
|
||||
/// has a `where` clause where lifetimes are mentioned.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {
|
||||
/// x
|
||||
/// }
|
||||
/// ```
|
||||
pub NEEDLESS_LIFETIMES,
|
||||
complexity,
|
||||
"using explicit lifetimes for references in function arguments when elision rules \
|
||||
would allow omitting them"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for lifetimes in generics that are never used
|
||||
/// anywhere else.
|
||||
///
|
||||
/// **Why is this bad?** The additional lifetimes make the code look more
|
||||
/// complicated, while there is nothing out of the ordinary going on. Removing
|
||||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn unused_lifetime<'a>(x: u8) {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for lifetimes in generics that are never used
|
||||
/// anywhere else.
|
||||
///
|
||||
/// **Why is this bad?** The additional lifetimes make the code look more
|
||||
/// complicated, while there is nothing out of the ordinary going on. Removing
|
||||
/// them leads to more readable code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn unused_lifetime<'a>(x: u8) {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub EXTRA_UNUSED_LIFETIMES,
|
||||
complexity,
|
||||
"unused lifetimes in function definitions"
|
||||
|
@ -9,95 +9,95 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::*;
|
||||
use syntax_pos;
|
||||
|
||||
/// **What it does:** Warns if a long integral or floating-point constant does
|
||||
/// not contain underscores.
|
||||
///
|
||||
/// **Why is this bad?** Reading long numbers is difficult without separators.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// 61864918973511
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if a long integral or floating-point constant does
|
||||
/// not contain underscores.
|
||||
///
|
||||
/// **Why is this bad?** Reading long numbers is difficult without separators.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: u64 = 61864918973511;
|
||||
/// ```
|
||||
pub UNREADABLE_LITERAL,
|
||||
style,
|
||||
"long integer literal without underscores"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns for mistyped suffix in literals
|
||||
///
|
||||
/// **Why is this bad?** This is most probably a typo
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// - Recommends a signed suffix, even though the number might be too big and an unsigned
|
||||
/// suffix is required
|
||||
/// - Does not match on `_128` since that is a valid grouping for decimal and octal numbers
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// 2_32
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns for mistyped suffix in literals
|
||||
///
|
||||
/// **Why is this bad?** This is most probably a typo
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// - Recommends a signed suffix, even though the number might be too big and an unsigned
|
||||
/// suffix is required
|
||||
/// - Does not match on `_128` since that is a valid grouping for decimal and octal numbers
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// 2_32;
|
||||
/// ```
|
||||
pub MISTYPED_LITERAL_SUFFIXES,
|
||||
correctness,
|
||||
"mistyped literal suffix"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns if an integral or floating-point constant is
|
||||
/// grouped inconsistently with underscores.
|
||||
///
|
||||
/// **Why is this bad?** Readers may incorrectly interpret inconsistently
|
||||
/// grouped digits.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// 618_64_9189_73_511
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if an integral or floating-point constant is
|
||||
/// grouped inconsistently with underscores.
|
||||
///
|
||||
/// **Why is this bad?** Readers may incorrectly interpret inconsistently
|
||||
/// grouped digits.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: u64 = 618_64_9189_73_511;
|
||||
/// ```
|
||||
pub INCONSISTENT_DIGIT_GROUPING,
|
||||
style,
|
||||
"integer literals with digits grouped inconsistently"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns if the digits of an integral or floating-point
|
||||
/// constant are grouped into groups that
|
||||
/// are too large.
|
||||
///
|
||||
/// **Why is this bad?** Negatively impacts readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// 6186491_8973511
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if the digits of an integral or floating-point
|
||||
/// constant are grouped into groups that
|
||||
/// are too large.
|
||||
///
|
||||
/// **Why is this bad?** Negatively impacts readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: u64 = 6186491_8973511;
|
||||
/// ```
|
||||
pub LARGE_DIGIT_GROUPS,
|
||||
pedantic,
|
||||
"grouping digits into groups that are too large"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns if there is a better representation for a numeric literal.
|
||||
///
|
||||
/// **Why is this bad?** Especially for big powers of 2 a hexadecimal representation is more
|
||||
/// readable than a decimal representation.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// `255` => `0xFF`
|
||||
/// `65_535` => `0xFFFF`
|
||||
/// `4_042_322_160` => `0xF0F0_F0F0`
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if there is a better representation for a numeric literal.
|
||||
///
|
||||
/// **Why is this bad?** Especially for big powers of 2 a hexadecimal representation is more
|
||||
/// readable than a decimal representation.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// `255` => `0xFF`
|
||||
/// `65_535` => `0xFFFF`
|
||||
/// `4_042_322_160` => `0xF0F0_F0F0`
|
||||
pub DECIMAL_LITERAL_REPRESENTATION,
|
||||
restriction,
|
||||
"using decimal representation when hexadecimal would be better"
|
||||
|
@ -32,408 +32,408 @@ use crate::utils::{
|
||||
span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, SpanlessEq,
|
||||
};
|
||||
|
||||
/// **What it does:** Checks for for-loops that manually copy items between
|
||||
/// slices that could be optimized by having a memcpy.
|
||||
///
|
||||
/// **Why is this bad?** It is not as fast as a memcpy.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for i in 0..src.len() {
|
||||
/// dst[i + 64] = src[i];
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for for-loops that manually copy items between
|
||||
/// slices that could be optimized by having a memcpy.
|
||||
///
|
||||
/// **Why is this bad?** It is not as fast as a memcpy.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for i in 0..src.len() {
|
||||
/// dst[i + 64] = src[i];
|
||||
/// }
|
||||
/// ```
|
||||
pub MANUAL_MEMCPY,
|
||||
perf,
|
||||
"manually copying items between slices"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for looping over the range of `0..len` of some
|
||||
/// collection just to get the values by index.
|
||||
///
|
||||
/// **Why is this bad?** Just iterating the collection itself makes the intent
|
||||
/// more clear and is probably faster.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for i in 0..vec.len() {
|
||||
/// println!("{}", vec[i]);
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for looping over the range of `0..len` of some
|
||||
/// collection just to get the values by index.
|
||||
///
|
||||
/// **Why is this bad?** Just iterating the collection itself makes the intent
|
||||
/// more clear and is probably faster.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for i in 0..vec.len() {
|
||||
/// println!("{}", vec[i]);
|
||||
/// }
|
||||
/// ```
|
||||
pub NEEDLESS_RANGE_LOOP,
|
||||
style,
|
||||
"for-looping over a range of indices where an iterator over items would do"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for loops on `x.iter()` where `&x` will do, and
|
||||
/// suggests the latter.
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
///
|
||||
/// **Known problems:** False negatives. We currently only warn on some known
|
||||
/// types.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // with `y` a `Vec` or slice:
|
||||
/// for x in y.iter() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
/// can be rewritten to
|
||||
/// ```rust
|
||||
/// for x in &y {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for loops on `x.iter()` where `&x` will do, and
|
||||
/// suggests the latter.
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
///
|
||||
/// **Known problems:** False negatives. We currently only warn on some known
|
||||
/// types.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// // with `y` a `Vec` or slice:
|
||||
/// for x in y.iter() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
/// can be rewritten to
|
||||
/// ```rust
|
||||
/// for x in &y {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub EXPLICIT_ITER_LOOP,
|
||||
pedantic,
|
||||
"for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for loops on `y.into_iter()` where `y` will do, and
|
||||
/// suggests the latter.
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // with `y` a `Vec` or slice:
|
||||
/// for x in y.into_iter() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
/// can be rewritten to
|
||||
/// ```rust
|
||||
/// for x in y {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for loops on `y.into_iter()` where `y` will do, and
|
||||
/// suggests the latter.
|
||||
///
|
||||
/// **Why is this bad?** Readability.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// // with `y` a `Vec` or slice:
|
||||
/// for x in y.into_iter() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
/// can be rewritten to
|
||||
/// ```ignore
|
||||
/// for x in y {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub EXPLICIT_INTO_ITER_LOOP,
|
||||
pedantic,
|
||||
"for-looping over `_.into_iter()` when `_` would do"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for loops on `x.next()`.
|
||||
///
|
||||
/// **Why is this bad?** `next()` returns either `Some(value)` if there was a
|
||||
/// value, or `None` otherwise. The insidious thing is that `Option<_>`
|
||||
/// implements `IntoIterator`, so that possibly one value will be iterated,
|
||||
/// leading to some hard to find bugs. No one will want to write such code
|
||||
/// [except to win an Underhanded Rust
|
||||
/// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in y.next() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for loops on `x.next()`.
|
||||
///
|
||||
/// **Why is this bad?** `next()` returns either `Some(value)` if there was a
|
||||
/// value, or `None` otherwise. The insidious thing is that `Option<_>`
|
||||
/// implements `IntoIterator`, so that possibly one value will be iterated,
|
||||
/// leading to some hard to find bugs. No one will want to write such code
|
||||
/// [except to win an Underhanded Rust
|
||||
/// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for x in y.next() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub ITER_NEXT_LOOP,
|
||||
correctness,
|
||||
"for-looping over `_.next()` which is probably not intended"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `for` loops over `Option` values.
|
||||
///
|
||||
/// **Why is this bad?** Readability. This is more clearly expressed as an `if
|
||||
/// let`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in option {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This should be
|
||||
/// ```rust
|
||||
/// if let Some(x) = option {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `for` loops over `Option` values.
|
||||
///
|
||||
/// **Why is this bad?** Readability. This is more clearly expressed as an `if
|
||||
/// let`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for x in option {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This should be
|
||||
/// ```ignore
|
||||
/// if let Some(x) = option {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub FOR_LOOP_OVER_OPTION,
|
||||
correctness,
|
||||
"for-looping over an `Option`, which is more clearly expressed as an `if let`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `for` loops over `Result` values.
|
||||
///
|
||||
/// **Why is this bad?** Readability. This is more clearly expressed as an `if
|
||||
/// let`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in result {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This should be
|
||||
/// ```rust
|
||||
/// if let Ok(x) = result {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `for` loops over `Result` values.
|
||||
///
|
||||
/// **Why is this bad?** Readability. This is more clearly expressed as an `if
|
||||
/// let`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for x in result {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This should be
|
||||
/// ```ignore
|
||||
/// if let Ok(x) = result {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub FOR_LOOP_OVER_RESULT,
|
||||
correctness,
|
||||
"for-looping over a `Result`, which is more clearly expressed as an `if let`"
|
||||
}
|
||||
|
||||
/// **What it does:** Detects `loop + match` combinations that are easier
|
||||
/// written as a `while let` loop.
|
||||
///
|
||||
/// **Why is this bad?** The `while let` loop is usually shorter and more
|
||||
/// readable.
|
||||
///
|
||||
/// **Known problems:** Sometimes the wrong binding is displayed (#383).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// let x = match y {
|
||||
/// Some(x) => x,
|
||||
/// None => break,
|
||||
/// }
|
||||
/// // .. do something with x
|
||||
/// }
|
||||
/// // is easier written as
|
||||
/// while let Some(x) = y {
|
||||
/// // .. do something with x
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects `loop + match` combinations that are easier
|
||||
/// written as a `while let` loop.
|
||||
///
|
||||
/// **Why is this bad?** The `while let` loop is usually shorter and more
|
||||
/// readable.
|
||||
///
|
||||
/// **Known problems:** Sometimes the wrong binding is displayed (#383).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// let x = match y {
|
||||
/// Some(x) => x,
|
||||
/// None => break,
|
||||
/// }
|
||||
/// // .. do something with x
|
||||
/// }
|
||||
/// // is easier written as
|
||||
/// while let Some(x) = y {
|
||||
/// // .. do something with x
|
||||
/// }
|
||||
/// ```
|
||||
pub WHILE_LET_LOOP,
|
||||
complexity,
|
||||
"`loop { if let { ... } else break }`, which can be written as a `while let` loop"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for using `collect()` on an iterator without using
|
||||
/// the result.
|
||||
///
|
||||
/// **Why is this bad?** It is more idiomatic to use a `for` loop over the
|
||||
/// iterator instead.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// vec.iter().map(|x| /* some operation returning () */).collect::<Vec<_>>();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for using `collect()` on an iterator without using
|
||||
/// the result.
|
||||
///
|
||||
/// **Why is this bad?** It is more idiomatic to use a `for` loop over the
|
||||
/// iterator instead.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// vec.iter().map(|x| /* some operation returning () */).collect::<Vec<_>>();
|
||||
/// ```
|
||||
pub UNUSED_COLLECT,
|
||||
perf,
|
||||
"`collect()`ing an iterator without using the result; this is usually better written as a for loop"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for functions collecting an iterator when collect
|
||||
/// is not needed.
|
||||
///
|
||||
/// **Why is this bad?** `collect` causes the allocation of a new data structure,
|
||||
/// when this allocation may not be needed.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let len = iterator.collect::<Vec<_>>().len();
|
||||
/// // should be
|
||||
/// let len = iterator.count();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for functions collecting an iterator when collect
|
||||
/// is not needed.
|
||||
///
|
||||
/// **Why is this bad?** `collect` causes the allocation of a new data structure,
|
||||
/// when this allocation may not be needed.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let len = iterator.collect::<Vec<_>>().len();
|
||||
/// // should be
|
||||
/// let len = iterator.count();
|
||||
/// ```
|
||||
pub NEEDLESS_COLLECT,
|
||||
perf,
|
||||
"collecting an iterator when collect is not needed"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for loops over ranges `x..y` where both `x` and `y`
|
||||
/// are constant and `x` is greater or equal to `y`, unless the range is
|
||||
/// reversed or has a negative `.step_by(_)`.
|
||||
///
|
||||
/// **Why is it bad?** Such loops will either be skipped or loop until
|
||||
/// wrap-around (in debug code, this may `panic!()`). Both options are probably
|
||||
/// not intended.
|
||||
///
|
||||
/// **Known problems:** The lint cannot catch loops over dynamically defined
|
||||
/// ranges. Doing this would require simulating all possible inputs and code
|
||||
/// paths through the program, which would be complex and error-prone.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in 5..10 - 5 {
|
||||
/// ..
|
||||
/// } // oops, stray `-`
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for loops over ranges `x..y` where both `x` and `y`
|
||||
/// are constant and `x` is greater or equal to `y`, unless the range is
|
||||
/// reversed or has a negative `.step_by(_)`.
|
||||
///
|
||||
/// **Why is it bad?** Such loops will either be skipped or loop until
|
||||
/// wrap-around (in debug code, this may `panic!()`). Both options are probably
|
||||
/// not intended.
|
||||
///
|
||||
/// **Known problems:** The lint cannot catch loops over dynamically defined
|
||||
/// ranges. Doing this would require simulating all possible inputs and code
|
||||
/// paths through the program, which would be complex and error-prone.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for x in 5..10 - 5 {
|
||||
/// ..
|
||||
/// } // oops, stray `-`
|
||||
/// ```
|
||||
pub REVERSE_RANGE_LOOP,
|
||||
correctness,
|
||||
"iteration over an empty range, such as `10..0` or `5..5`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks `for` loops over slices with an explicit counter
|
||||
/// and suggests the use of `.enumerate()`.
|
||||
///
|
||||
/// **Why is it bad?** Not only is the version using `.enumerate()` more
|
||||
/// readable, the compiler is able to remove bounds checks which can lead to
|
||||
/// faster code in some instances.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for i in 0..v.len() { foo(v[i]);
|
||||
/// for i in 0..v.len() { bar(i, v[i]); }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks `for` loops over slices with an explicit counter
|
||||
/// and suggests the use of `.enumerate()`.
|
||||
///
|
||||
/// **Why is it bad?** Not only is the version using `.enumerate()` more
|
||||
/// readable, the compiler is able to remove bounds checks which can lead to
|
||||
/// faster code in some instances.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for i in 0..v.len() { foo(v[i]);
|
||||
/// for i in 0..v.len() { bar(i, v[i]); }
|
||||
/// ```
|
||||
pub EXPLICIT_COUNTER_LOOP,
|
||||
complexity,
|
||||
"for-looping with an explicit counter when `_.enumerate()` would do"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for empty `loop` expressions.
|
||||
///
|
||||
/// **Why is this bad?** Those busy loops burn CPU cycles without doing
|
||||
/// anything. Think of the environment and either block on something or at least
|
||||
/// make the thread sleep for some microseconds.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// loop {}
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for empty `loop` expressions.
|
||||
///
|
||||
/// **Why is this bad?** Those busy loops burn CPU cycles without doing
|
||||
/// anything. Think of the environment and either block on something or at least
|
||||
/// make the thread sleep for some microseconds.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// loop {}
|
||||
/// ```
|
||||
pub EMPTY_LOOP,
|
||||
style,
|
||||
"empty `loop {}`, which should block or sleep"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `while let` expressions on iterators.
|
||||
///
|
||||
/// **Why is this bad?** Readability. A simple `for` loop is shorter and conveys
|
||||
/// the intent better.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// while let Some(val) = iter() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `while let` expressions on iterators.
|
||||
///
|
||||
/// **Why is this bad?** Readability. A simple `for` loop is shorter and conveys
|
||||
/// the intent better.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// while let Some(val) = iter() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub WHILE_LET_ON_ITERATOR,
|
||||
style,
|
||||
"using a while-let loop instead of a for loop on an iterator"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for iterating a map (`HashMap` or `BTreeMap`) and
|
||||
/// ignoring either the keys or values.
|
||||
///
|
||||
/// **Why is this bad?** Readability. There are `keys` and `values` methods that
|
||||
/// can be used to express that don't need the values or keys.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for (k, _) in &map {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// could be replaced by
|
||||
///
|
||||
/// ```rust
|
||||
/// for k in map.keys() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for iterating a map (`HashMap` or `BTreeMap`) and
|
||||
/// ignoring either the keys or values.
|
||||
///
|
||||
/// **Why is this bad?** Readability. There are `keys` and `values` methods that
|
||||
/// can be used to express that don't need the values or keys.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for (k, _) in &map {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// could be replaced by
|
||||
///
|
||||
/// ```ignore
|
||||
/// for k in map.keys() {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub FOR_KV_MAP,
|
||||
style,
|
||||
"looping on a map using `iter` when `keys` or `values` would do"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for loops that will always `break`, `return` or
|
||||
/// `continue` an outer loop.
|
||||
///
|
||||
/// **Why is this bad?** This loop never loops, all it does is obfuscating the
|
||||
/// code.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// ..;
|
||||
/// break;
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for loops that will always `break`, `return` or
|
||||
/// `continue` an outer loop.
|
||||
///
|
||||
/// **Why is this bad?** This loop never loops, all it does is obfuscating the
|
||||
/// code.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// ..;
|
||||
/// break;
|
||||
/// }
|
||||
/// ```
|
||||
pub NEVER_LOOP,
|
||||
correctness,
|
||||
"any loop that will always `break` or `return`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for loops which have a range bound that is a mutable variable
|
||||
///
|
||||
/// **Why is this bad?** One might think that modifying the mutable variable changes the loop bounds
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut foo = 42;
|
||||
/// for i in 0..foo {
|
||||
/// foo -= 1;
|
||||
/// println!("{}", i); // prints numbers from 0 to 42, not 0 to 21
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for loops which have a range bound that is a mutable variable
|
||||
///
|
||||
/// **Why is this bad?** One might think that modifying the mutable variable changes the loop bounds
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut foo = 42;
|
||||
/// for i in 0..foo {
|
||||
/// foo -= 1;
|
||||
/// println!("{}", i); // prints numbers from 0 to 42, not 0 to 21
|
||||
/// }
|
||||
/// ```
|
||||
pub MUT_RANGE_BOUND,
|
||||
complexity,
|
||||
"for loop over a range where one of the bounds is a mutable variable"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks whether variables used within while loop condition
|
||||
/// can be (and are) mutated in the body.
|
||||
///
|
||||
/// **Why is this bad?** If the condition is unchanged, entering the body of the loop
|
||||
/// will lead to an infinite loop.
|
||||
///
|
||||
/// **Known problems:** If the `while`-loop is in a closure, the check for mutation of the
|
||||
/// condition variables in the body can cause false negatives. For example when only `Upvar` `a` is
|
||||
/// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let i = 0;
|
||||
/// while i > 10 {
|
||||
/// println!("let me loop forever!");
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks whether variables used within while loop condition
|
||||
/// can be (and are) mutated in the body.
|
||||
///
|
||||
/// **Why is this bad?** If the condition is unchanged, entering the body of the loop
|
||||
/// will lead to an infinite loop.
|
||||
///
|
||||
/// **Known problems:** If the `while`-loop is in a closure, the check for mutation of the
|
||||
/// condition variables in the body can cause false negatives. For example when only `Upvar` `a` is
|
||||
/// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let i = 0;
|
||||
/// while i > 10 {
|
||||
/// println!("let me loop forever!");
|
||||
/// }
|
||||
/// ```
|
||||
pub WHILE_IMMUTABLE_CONDITION,
|
||||
correctness,
|
||||
"variables used within while expression are not mutated in the body"
|
||||
|
@ -14,29 +14,29 @@ use syntax::source_map::Span;
|
||||
#[derive(Clone)]
|
||||
pub struct Pass;
|
||||
|
||||
/// **What it does:** Checks for usage of `iterator.map(|x| x.clone())` and suggests
|
||||
/// `iterator.cloned()` instead
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more concisely
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x = vec![42, 43];
|
||||
/// let y = x.iter();
|
||||
/// let z = y.map(|i| *i);
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
///
|
||||
/// ```rust
|
||||
/// let x = vec![42, 43];
|
||||
/// let y = x.iter();
|
||||
/// let z = y.cloned();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `iterator.map(|x| x.clone())` and suggests
|
||||
/// `iterator.cloned()` instead
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more concisely
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x = vec![42, 43];
|
||||
/// let y = x.iter();
|
||||
/// let z = y.map(|i| *i);
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
///
|
||||
/// ```rust
|
||||
/// let x = vec![42, 43];
|
||||
/// let y = x.iter();
|
||||
/// let z = y.cloned();
|
||||
/// ```
|
||||
pub MAP_CLONE,
|
||||
style,
|
||||
"using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types"
|
||||
|
@ -11,67 +11,67 @@ use syntax::source_map::Span;
|
||||
#[derive(Clone)]
|
||||
pub struct Pass;
|
||||
|
||||
/// **What it does:** Checks for usage of `option.map(f)` where f is a function
|
||||
/// or closure that returns the unit type.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more clearly with
|
||||
/// an if let statement
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Option<&str> = do_stuff();
|
||||
/// x.map(log_err_msg);
|
||||
/// x.map(|msg| log_err_msg(format_msg(msg)))
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Option<&str> = do_stuff();
|
||||
/// if let Some(msg) = x {
|
||||
/// log_err_msg(msg)
|
||||
/// }
|
||||
/// if let Some(msg) = x {
|
||||
/// log_err_msg(format_msg(msg))
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `option.map(f)` where f is a function
|
||||
/// or closure that returns the unit type.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more clearly with
|
||||
/// an if let statement
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Option<&str> = do_stuff();
|
||||
/// x.map(log_err_msg);
|
||||
/// x.map(|msg| log_err_msg(format_msg(msg)))
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Option<&str> = do_stuff();
|
||||
/// if let Some(msg) = x {
|
||||
/// log_err_msg(msg)
|
||||
/// }
|
||||
/// if let Some(msg) = x {
|
||||
/// log_err_msg(format_msg(msg))
|
||||
/// }
|
||||
/// ```
|
||||
pub OPTION_MAP_UNIT_FN,
|
||||
complexity,
|
||||
"using `option.map(f)`, where f is a function or closure that returns ()"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for usage of `result.map(f)` where f is a function
|
||||
/// or closure that returns the unit type.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more clearly with
|
||||
/// an if let statement
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Result<&str, &str> = do_stuff();
|
||||
/// x.map(log_err_msg);
|
||||
/// x.map(|msg| log_err_msg(format_msg(msg)))
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Result<&str, &str> = do_stuff();
|
||||
/// if let Ok(msg) = x {
|
||||
/// log_err_msg(msg)
|
||||
/// }
|
||||
/// if let Ok(msg) = x {
|
||||
/// log_err_msg(format_msg(msg))
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `result.map(f)` where f is a function
|
||||
/// or closure that returns the unit type.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more clearly with
|
||||
/// an if let statement
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Result<&str, &str> = do_stuff();
|
||||
/// x.map(log_err_msg);
|
||||
/// x.map(|msg| log_err_msg(format_msg(msg)))
|
||||
/// ```
|
||||
///
|
||||
/// The correct use would be:
|
||||
///
|
||||
/// ```rust
|
||||
/// let x: Result<&str, &str> = do_stuff();
|
||||
/// if let Ok(msg) = x {
|
||||
/// log_err_msg(msg)
|
||||
/// }
|
||||
/// if let Ok(msg) = x {
|
||||
/// log_err_msg(format_msg(msg))
|
||||
/// }
|
||||
/// ```
|
||||
pub RESULT_MAP_UNIT_FN,
|
||||
complexity,
|
||||
"using `result.map(f)`, where f is a function or closure that returns ()"
|
||||
|
@ -18,192 +18,192 @@ use std::ops::Deref;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for matches with a single arm where an `if let`
|
||||
/// will usually suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// Some(ref foo) => bar(foo),
|
||||
/// _ => (),
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for matches with a single arm where an `if let`
|
||||
/// will usually suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// match x {
|
||||
/// Some(ref foo) => bar(foo),
|
||||
/// _ => (),
|
||||
/// }
|
||||
/// ```
|
||||
pub SINGLE_MATCH,
|
||||
style,
|
||||
"a match statement with a single nontrivial arm (i.e. where the other arm is `_ => {}`) instead of `if let`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for matches with a two arms where an `if let else` will
|
||||
/// usually suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
|
||||
///
|
||||
/// **Known problems:** Personal style preferences may differ.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// Using `match`:
|
||||
///
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// Some(ref foo) => bar(foo),
|
||||
/// _ => bar(other_ref),
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Using `if let` with `else`:
|
||||
///
|
||||
/// ```rust
|
||||
/// if let Some(ref foo) = x {
|
||||
/// bar(foo);
|
||||
/// } else {
|
||||
/// bar(other_ref);
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for matches with a two arms where an `if let else` will
|
||||
/// usually suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
|
||||
///
|
||||
/// **Known problems:** Personal style preferences may differ.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// Using `match`:
|
||||
///
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// Some(ref foo) => bar(foo),
|
||||
/// _ => bar(other_ref),
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Using `if let` with `else`:
|
||||
///
|
||||
/// ```ignore
|
||||
/// if let Some(ref foo) = x {
|
||||
/// bar(foo);
|
||||
/// } else {
|
||||
/// bar(other_ref);
|
||||
/// }
|
||||
/// ```
|
||||
pub SINGLE_MATCH_ELSE,
|
||||
pedantic,
|
||||
"a match statement with a two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for matches where all arms match a reference,
|
||||
/// suggesting to remove the reference and deref the matched expression
|
||||
/// instead. It also checks for `if let &foo = bar` blocks.
|
||||
///
|
||||
/// **Why is this bad?** It just makes the code less readable. That reference
|
||||
/// destructuring adds nothing to the code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// &A(ref y) => foo(y),
|
||||
/// &B => bar(),
|
||||
/// _ => frob(&x),
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for matches where all arms match a reference,
|
||||
/// suggesting to remove the reference and deref the matched expression
|
||||
/// instead. It also checks for `if let &foo = bar` blocks.
|
||||
///
|
||||
/// **Why is this bad?** It just makes the code less readable. That reference
|
||||
/// destructuring adds nothing to the code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// match x {
|
||||
/// &A(ref y) => foo(y),
|
||||
/// &B => bar(),
|
||||
/// _ => frob(&x),
|
||||
/// }
|
||||
/// ```
|
||||
pub MATCH_REF_PATS,
|
||||
style,
|
||||
"a match or `if let` with all arms prefixed with `&` instead of deref-ing the match expression"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for matches where match expression is a `bool`. It
|
||||
/// suggests to replace the expression with an `if...else` block.
|
||||
///
|
||||
/// **Why is this bad?** It makes the code less readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let condition: bool = true;
|
||||
/// match condition {
|
||||
/// true => foo(),
|
||||
/// false => bar(),
|
||||
/// }
|
||||
/// ```
|
||||
/// Use if/else instead:
|
||||
/// ```rust
|
||||
/// let condition: bool = true;
|
||||
/// if condition {
|
||||
/// foo();
|
||||
/// } else {
|
||||
/// bar();
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for matches where match expression is a `bool`. It
|
||||
/// suggests to replace the expression with an `if...else` block.
|
||||
///
|
||||
/// **Why is this bad?** It makes the code less readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let condition: bool = true;
|
||||
/// match condition {
|
||||
/// true => foo(),
|
||||
/// false => bar(),
|
||||
/// }
|
||||
/// ```
|
||||
/// Use if/else instead:
|
||||
/// ```ignore
|
||||
/// let condition: bool = true;
|
||||
/// if condition {
|
||||
/// foo();
|
||||
/// } else {
|
||||
/// bar();
|
||||
/// }
|
||||
/// ```
|
||||
pub MATCH_BOOL,
|
||||
style,
|
||||
"a match on a boolean expression instead of an `if..else` block"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for overlapping match arms.
|
||||
///
|
||||
/// **Why is this bad?** It is likely to be an error and if not, makes the code
|
||||
/// less obvious.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = 5;
|
||||
/// match x {
|
||||
/// 1...10 => println!("1 ... 10"),
|
||||
/// 5...15 => println!("5 ... 15"),
|
||||
/// _ => (),
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for overlapping match arms.
|
||||
///
|
||||
/// **Why is this bad?** It is likely to be an error and if not, makes the code
|
||||
/// less obvious.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = 5;
|
||||
/// match x {
|
||||
/// 1...10 => println!("1 ... 10"),
|
||||
/// 5...15 => println!("5 ... 15"),
|
||||
/// _ => (),
|
||||
/// }
|
||||
/// ```
|
||||
pub MATCH_OVERLAPPING_ARM,
|
||||
style,
|
||||
"a match with overlapping arms"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for arm which matches all errors with `Err(_)`
|
||||
/// and take drastic actions like `panic!`.
|
||||
///
|
||||
/// **Why is this bad?** It is generally a bad practice, just like
|
||||
/// catching all exceptions in java with `catch(Exception)`
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: Result(i32, &str) = Ok(3);
|
||||
/// match x {
|
||||
/// Ok(_) => println!("ok"),
|
||||
/// Err(_) => panic!("err"),
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for arm which matches all errors with `Err(_)`
|
||||
/// and take drastic actions like `panic!`.
|
||||
///
|
||||
/// **Why is this bad?** It is generally a bad practice, just like
|
||||
/// catching all exceptions in java with `catch(Exception)`
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: Result<i32, &str> = Ok(3);
|
||||
/// match x {
|
||||
/// Ok(_) => println!("ok"),
|
||||
/// Err(_) => panic!("err"),
|
||||
/// }
|
||||
/// ```
|
||||
pub MATCH_WILD_ERR_ARM,
|
||||
style,
|
||||
"a match with `Err(_)` arm and take drastic actions"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for match which is used to add a reference to an
|
||||
/// `Option` value.
|
||||
///
|
||||
/// **Why is this bad?** Using `as_ref()` or `as_mut()` instead is shorter.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: Option<()> = None;
|
||||
/// let r: Option<&()> = match x {
|
||||
/// None => None,
|
||||
/// Some(ref v) => Some(v),
|
||||
/// };
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for match which is used to add a reference to an
|
||||
/// `Option` value.
|
||||
///
|
||||
/// **Why is this bad?** Using `as_ref()` or `as_mut()` instead is shorter.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: Option<()> = None;
|
||||
/// let r: Option<&()> = match x {
|
||||
/// None => None,
|
||||
/// Some(ref v) => Some(v),
|
||||
/// };
|
||||
/// ```
|
||||
pub MATCH_AS_REF,
|
||||
complexity,
|
||||
"a match on an Option value instead of using `as_ref()` or `as_mut`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for wildcard enum matches using `_`.
|
||||
///
|
||||
/// **Why is this bad?** New enum variants added by library updates can be missed.
|
||||
///
|
||||
/// **Known problems:** Suggested replacements may be incorrect if guards exhaustively cover some
|
||||
/// variants, and also may not use correct path to enum if it's not present in the current scope.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// A => {},
|
||||
/// _ => {},
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for wildcard enum matches using `_`.
|
||||
///
|
||||
/// **Why is this bad?** New enum variants added by library updates can be missed.
|
||||
///
|
||||
/// **Known problems:** Suggested replacements may be incorrect if guards exhaustively cover some
|
||||
/// variants, and also may not use correct path to enum if it's not present in the current scope.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// A => {},
|
||||
/// _ => {},
|
||||
/// }
|
||||
/// ```
|
||||
pub WILDCARD_ENUM_MATCH_ARM,
|
||||
restriction,
|
||||
"a wildcard enum match arm using `_`"
|
||||
|
@ -7,19 +7,21 @@ use rustc_errors::Applicability;
|
||||
|
||||
use std::iter;
|
||||
|
||||
/// **What it does:** Checks for calls of `mem::discriminant()` on a non-enum type.
|
||||
///
|
||||
/// **Why is this bad?** The value of `mem::discriminant()` on non-enum types
|
||||
/// is unspecified.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mem::discriminant(&"hello");
|
||||
/// mem::discriminant(&&Some(2));
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls of `mem::discriminant()` on a non-enum type.
|
||||
///
|
||||
/// **Why is this bad?** The value of `mem::discriminant()` on non-enum types
|
||||
/// is unspecified.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::mem;
|
||||
///
|
||||
/// mem::discriminant(&"hello");
|
||||
/// mem::discriminant(&&Some(2));
|
||||
/// ```
|
||||
pub MEM_DISCRIMINANT_NON_ENUM,
|
||||
correctness,
|
||||
"calling mem::descriminant on non-enum type"
|
||||
|
@ -3,19 +3,19 @@ use rustc::hir::{Expr, ExprKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is
|
||||
/// `Drop`.
|
||||
///
|
||||
/// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its
|
||||
/// destructor, possibly causing leaks.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mem::forget(Rc::new(55))
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is
|
||||
/// `Drop`.
|
||||
///
|
||||
/// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its
|
||||
/// destructor, possibly causing leaks.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mem::forget(Rc::new(55))
|
||||
/// ```
|
||||
pub MEM_FORGET,
|
||||
restriction,
|
||||
"`mem::forget` usage on `Drop` types, likely to cause memory leaks"
|
||||
|
@ -5,26 +5,28 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for `mem::replace()` on an `Option` with
|
||||
/// `None`.
|
||||
///
|
||||
/// **Why is this bad?** `Option` already has the method `take()` for
|
||||
/// taking its current value (Some(..) or None) and replacing it with
|
||||
/// `None`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut an_option = Some(0);
|
||||
/// let replaced = mem::replace(&mut an_option, None);
|
||||
/// ```
|
||||
/// Is better expressed with:
|
||||
/// ```rust
|
||||
/// let mut an_option = Some(0);
|
||||
/// let taken = an_option.take();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `mem::replace()` on an `Option` with
|
||||
/// `None`.
|
||||
///
|
||||
/// **Why is this bad?** `Option` already has the method `take()` for
|
||||
/// taking its current value (Some(..) or None) and replacing it with
|
||||
/// `None`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::mem;
|
||||
///
|
||||
/// let mut an_option = Some(0);
|
||||
/// let replaced = mem::replace(&mut an_option, None);
|
||||
/// ```
|
||||
/// Is better expressed with:
|
||||
/// ```rust
|
||||
/// let mut an_option = Some(0);
|
||||
/// let taken = an_option.take();
|
||||
/// ```
|
||||
pub MEM_REPLACE_OPTION_WITH_NONE,
|
||||
style,
|
||||
"replacing an `Option` with `None` instead of `take()`"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,21 +5,21 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
||||
/// used to clamp values, but switched so that the result is constant.
|
||||
///
|
||||
/// **Why is this bad?** This is in all probability not the intended outcome. At
|
||||
/// the least it hurts readability of the code.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// min(0, max(100, x))
|
||||
/// ```
|
||||
/// It will always be equal to `0`. Probably the author meant to clamp the value
|
||||
/// between 0 and 100, but has erroneously swapped `min` and `max`.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
||||
/// used to clamp values, but switched so that the result is constant.
|
||||
///
|
||||
/// **Why is this bad?** This is in all probability not the intended outcome. At
|
||||
/// the least it hurts readability of the code.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// min(0, max(100, x))
|
||||
/// ```
|
||||
/// It will always be equal to `0`. Probably the author meant to clamp the value
|
||||
/// between 0 and 100, but has erroneously swapped `min` and `max`.
|
||||
pub MIN_MAX,
|
||||
correctness,
|
||||
"`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant"
|
||||
|
@ -16,208 +16,208 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::{ExpnFormat, Span};
|
||||
|
||||
/// **What it does:** Checks for function arguments and let bindings denoted as
|
||||
/// `ref`.
|
||||
///
|
||||
/// **Why is this bad?** The `ref` declaration makes the function take an owned
|
||||
/// value, but turns the argument into a reference (which means that the value
|
||||
/// is destroyed when exiting the function). This adds not much value: either
|
||||
/// take a reference type, or take an owned value and create references in the
|
||||
/// body.
|
||||
///
|
||||
/// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The
|
||||
/// type of `x` is more obvious with the former.
|
||||
///
|
||||
/// **Known problems:** If the argument is dereferenced within the function,
|
||||
/// removing the `ref` will lead to errors. This can be fixed by removing the
|
||||
/// dereferences, e.g. changing `*x` to `x` within the function.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(ref x: u8) -> bool {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for function arguments and let bindings denoted as
|
||||
/// `ref`.
|
||||
///
|
||||
/// **Why is this bad?** The `ref` declaration makes the function take an owned
|
||||
/// value, but turns the argument into a reference (which means that the value
|
||||
/// is destroyed when exiting the function). This adds not much value: either
|
||||
/// take a reference type, or take an owned value and create references in the
|
||||
/// body.
|
||||
///
|
||||
/// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The
|
||||
/// type of `x` is more obvious with the former.
|
||||
///
|
||||
/// **Known problems:** If the argument is dereferenced within the function,
|
||||
/// removing the `ref` will lead to errors. This can be fixed by removing the
|
||||
/// dereferences, e.g. changing `*x` to `x` within the function.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// fn foo(ref x: u8) -> bool {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub TOPLEVEL_REF_ARG,
|
||||
style,
|
||||
"an entire binding declared as `ref`, in a function argument or a `let` statement"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for comparisons to NaN.
|
||||
///
|
||||
/// **Why is this bad?** NaN does not compare meaningfully to anything – not
|
||||
/// even itself – so those comparisons are simply wrong.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x == NAN
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for comparisons to NaN.
|
||||
///
|
||||
/// **Why is this bad?** NaN does not compare meaningfully to anything – not
|
||||
/// even itself – so those comparisons are simply wrong.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// x == NAN
|
||||
/// ```
|
||||
pub CMP_NAN,
|
||||
correctness,
|
||||
"comparisons to NAN, which will always return false, probably not intended"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for (in-)equality comparisons on floating-point
|
||||
/// values (apart from zero), except in functions called `*eq*` (which probably
|
||||
/// implement equality for a type involving floats).
|
||||
///
|
||||
/// **Why is this bad?** Floating point calculations are usually imprecise, so
|
||||
/// asking if two values are *exactly* equal is asking for trouble. For a good
|
||||
/// guide on what to do, see [the floating point
|
||||
/// guide](http://www.floating-point-gui.de/errors/comparison).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// y == 1.23f64
|
||||
/// y != x // where both are floats
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for (in-)equality comparisons on floating-point
|
||||
/// values (apart from zero), except in functions called `*eq*` (which probably
|
||||
/// implement equality for a type involving floats).
|
||||
///
|
||||
/// **Why is this bad?** Floating point calculations are usually imprecise, so
|
||||
/// asking if two values are *exactly* equal is asking for trouble. For a good
|
||||
/// guide on what to do, see [the floating point
|
||||
/// guide](http://www.floating-point-gui.de/errors/comparison).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// y == 1.23f64
|
||||
/// y != x // where both are floats
|
||||
/// ```
|
||||
pub FLOAT_CMP,
|
||||
correctness,
|
||||
"using `==` or `!=` on float values instead of comparing difference with an epsilon"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for conversions to owned values just for the sake
|
||||
/// of a comparison.
|
||||
///
|
||||
/// **Why is this bad?** The comparison can operate on a reference, so creating
|
||||
/// an owned value effectively throws it away directly afterwards, which is
|
||||
/// needlessly consuming code and heap space.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x.to_owned() == y
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for conversions to owned values just for the sake
|
||||
/// of a comparison.
|
||||
///
|
||||
/// **Why is this bad?** The comparison can operate on a reference, so creating
|
||||
/// an owned value effectively throws it away directly afterwards, which is
|
||||
/// needlessly consuming code and heap space.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x.to_owned() == y
|
||||
/// ```
|
||||
pub CMP_OWNED,
|
||||
perf,
|
||||
"creating owned instances for comparing with others, e.g. `x == \"foo\".to_string()`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for getting the remainder of a division by one.
|
||||
///
|
||||
/// **Why is this bad?** The result can only ever be zero. No one will write
|
||||
/// such code deliberately, unless trying to win an Underhanded Rust
|
||||
/// Contest. Even for that contest, it's probably a bad idea. Use something more
|
||||
/// underhanded.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x % 1
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for getting the remainder of a division by one.
|
||||
///
|
||||
/// **Why is this bad?** The result can only ever be zero. No one will write
|
||||
/// such code deliberately, unless trying to win an Underhanded Rust
|
||||
/// Contest. Even for that contest, it's probably a bad idea. Use something more
|
||||
/// underhanded.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// x % 1
|
||||
/// ```
|
||||
pub MODULO_ONE,
|
||||
correctness,
|
||||
"taking a number modulo 1, which always returns 0"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for patterns in the form `name @ _`.
|
||||
///
|
||||
/// **Why is this bad?** It's almost always more readable to just use direct
|
||||
/// bindings.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// match v {
|
||||
/// Some(x) => (),
|
||||
/// y @ _ => (), // easier written as `y`,
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for patterns in the form `name @ _`.
|
||||
///
|
||||
/// **Why is this bad?** It's almost always more readable to just use direct
|
||||
/// bindings.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// match v {
|
||||
/// Some(x) => (),
|
||||
/// y @ _ => (), // easier written as `y`,
|
||||
/// }
|
||||
/// ```
|
||||
pub REDUNDANT_PATTERN,
|
||||
style,
|
||||
"using `name @ _` in a pattern"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for the use of bindings with a single leading
|
||||
/// underscore.
|
||||
///
|
||||
/// **Why is this bad?** A single leading underscore is usually used to indicate
|
||||
/// that a binding will not be used. Using such a binding breaks this
|
||||
/// expectation.
|
||||
///
|
||||
/// **Known problems:** The lint does not work properly with desugaring and
|
||||
/// macro, it has been allowed in the mean time.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let _x = 0;
|
||||
/// let y = _x + 1; // Here we are using `_x`, even though it has a leading
|
||||
/// // underscore. We should rename `_x` to `x`
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the use of bindings with a single leading
|
||||
/// underscore.
|
||||
///
|
||||
/// **Why is this bad?** A single leading underscore is usually used to indicate
|
||||
/// that a binding will not be used. Using such a binding breaks this
|
||||
/// expectation.
|
||||
///
|
||||
/// **Known problems:** The lint does not work properly with desugaring and
|
||||
/// macro, it has been allowed in the mean time.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let _x = 0;
|
||||
/// let y = _x + 1; // Here we are using `_x`, even though it has a leading
|
||||
/// // underscore. We should rename `_x` to `x`
|
||||
/// ```
|
||||
pub USED_UNDERSCORE_BINDING,
|
||||
pedantic,
|
||||
"using a binding which is prefixed with an underscore"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for the use of short circuit boolean conditions as
|
||||
/// a
|
||||
/// statement.
|
||||
///
|
||||
/// **Why is this bad?** Using a short circuit boolean condition as a statement
|
||||
/// may hide the fact that the second part is executed or not depending on the
|
||||
/// outcome of the first part.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// f() && g(); // We should write `if f() { g(); }`.
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the use of short circuit boolean conditions as
|
||||
/// a
|
||||
/// statement.
|
||||
///
|
||||
/// **Why is this bad?** Using a short circuit boolean condition as a statement
|
||||
/// may hide the fact that the second part is executed or not depending on the
|
||||
/// outcome of the first part.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// f() && g(); // We should write `if f() { g(); }`.
|
||||
/// ```
|
||||
pub SHORT_CIRCUIT_STATEMENT,
|
||||
complexity,
|
||||
"using a short circuit boolean condition as a statement"
|
||||
}
|
||||
|
||||
/// **What it does:** Catch casts from `0` to some pointer type
|
||||
///
|
||||
/// **Why is this bad?** This generally means `null` and is better expressed as
|
||||
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// 0 as *const u32
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Catch casts from `0` to some pointer type
|
||||
///
|
||||
/// **Why is this bad?** This generally means `null` and is better expressed as
|
||||
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```ignore
|
||||
/// 0 as *const u32
|
||||
/// ```
|
||||
pub ZERO_PTR,
|
||||
style,
|
||||
"using 0 as *{const, mut} T"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for (in-)equality comparisons on floating-point
|
||||
/// value and constant, except in functions called `*eq*` (which probably
|
||||
/// implement equality for a type involving floats).
|
||||
///
|
||||
/// **Why is this bad?** Floating point calculations are usually imprecise, so
|
||||
/// asking if two values are *exactly* equal is asking for trouble. For a good
|
||||
/// guide on what to do, see [the floating point
|
||||
/// guide](http://www.floating-point-gui.de/errors/comparison).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// const ONE = 1.00f64;
|
||||
/// x == ONE // where both are floats
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for (in-)equality comparisons on floating-point
|
||||
/// value and constant, except in functions called `*eq*` (which probably
|
||||
/// implement equality for a type involving floats).
|
||||
///
|
||||
/// **Why is this bad?** Floating point calculations are usually imprecise, so
|
||||
/// asking if two values are *exactly* equal is asking for trouble. For a good
|
||||
/// guide on what to do, see [the floating point
|
||||
/// guide](http://www.floating-point-gui.de/errors/comparison).
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// const ONE = 1.00f64;
|
||||
/// x == ONE // where both are floats
|
||||
/// ```
|
||||
pub FLOAT_CMP_CONST,
|
||||
restriction,
|
||||
"using `==` or `!=` on float constants instead of comparing difference with an epsilon"
|
||||
|
@ -9,163 +9,164 @@ use syntax::ast::*;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::visit::{walk_expr, FnKind, Visitor};
|
||||
|
||||
/// **What it does:** Checks for structure field patterns bound to wildcards.
|
||||
///
|
||||
/// **Why is this bad?** Using `..` instead is shorter and leaves the focus on
|
||||
/// the fields that are actually bound.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let { a: _, b: ref b, c: _ } = ..
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for structure field patterns bound to wildcards.
|
||||
///
|
||||
/// **Why is this bad?** Using `..` instead is shorter and leaves the focus on
|
||||
/// the fields that are actually bound.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let { a: _, b: ref b, c: _ } = ..
|
||||
/// ```
|
||||
pub UNNEEDED_FIELD_PATTERN,
|
||||
style,
|
||||
"struct fields bound to a wildcard instead of using `..`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for function arguments having the similar names
|
||||
/// differing by an underscore.
|
||||
///
|
||||
/// **Why is this bad?** It affects code readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(a: i32, _a: i32) {}
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for function arguments having the similar names
|
||||
/// differing by an underscore.
|
||||
///
|
||||
/// **Why is this bad?** It affects code readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(a: i32, _a: i32) {}
|
||||
/// ```
|
||||
pub DUPLICATE_UNDERSCORE_ARGUMENT,
|
||||
style,
|
||||
"function arguments having names which only differ by an underscore"
|
||||
}
|
||||
|
||||
/// **What it does:** Detects closures called in the same expression where they
|
||||
/// are defined.
|
||||
///
|
||||
/// **Why is this bad?** It is unnecessarily adding to the expression's
|
||||
/// complexity.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// (|| 42)()
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects closures called in the same expression where they
|
||||
/// are defined.
|
||||
///
|
||||
/// **Why is this bad?** It is unnecessarily adding to the expression's
|
||||
/// complexity.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// (|| 42)()
|
||||
/// ```
|
||||
pub REDUNDANT_CLOSURE_CALL,
|
||||
complexity,
|
||||
"throwaway closures called in the expression they are defined"
|
||||
}
|
||||
|
||||
/// **What it does:** Detects expressions of the form `--x`.
|
||||
///
|
||||
/// **Why is this bad?** It can mislead C/C++ programmers to think `x` was
|
||||
/// decremented.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// --x;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects expressions of the form `--x`.
|
||||
///
|
||||
/// **Why is this bad?** It can mislead C/C++ programmers to think `x` was
|
||||
/// decremented.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut x = 3;
|
||||
/// --x;
|
||||
/// ```
|
||||
pub DOUBLE_NEG,
|
||||
style,
|
||||
"`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns on hexadecimal literals with mixed-case letter
|
||||
/// digits.
|
||||
///
|
||||
/// **Why is this bad?** It looks confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let y = 0x1a9BAcD;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns on hexadecimal literals with mixed-case letter
|
||||
/// digits.
|
||||
///
|
||||
/// **Why is this bad?** It looks confusing.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let y = 0x1a9BAcD;
|
||||
/// ```
|
||||
pub MIXED_CASE_HEX_LITERALS,
|
||||
style,
|
||||
"hex literals whose letter digits are not consistently upper- or lowercased"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns if literal suffixes are not separated by an
|
||||
/// underscore.
|
||||
///
|
||||
/// **Why is this bad?** It is much less readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let y = 123832i32;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if literal suffixes are not separated by an
|
||||
/// underscore.
|
||||
///
|
||||
/// **Why is this bad?** It is much less readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let y = 123832i32;
|
||||
/// ```
|
||||
pub UNSEPARATED_LITERAL_SUFFIX,
|
||||
pedantic,
|
||||
"literals whose suffix is not separated by an underscore"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns if an integral constant literal starts with `0`.
|
||||
///
|
||||
/// **Why is this bad?** In some languages (including the infamous C language
|
||||
/// and most of its
|
||||
/// family), this marks an octal constant. In Rust however, this is a decimal
|
||||
/// constant. This could
|
||||
/// be confusing for both the writer and a reader of the constant.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// In Rust:
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// let a = 0123;
|
||||
/// println!("{}", a);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// prints `123`, while in C:
|
||||
///
|
||||
/// ```c
|
||||
/// #include <stdio.h>
|
||||
///
|
||||
/// int main() {
|
||||
/// int a = 0123;
|
||||
/// printf("%d\n", a);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// prints `83` (as `83 == 0o123` while `123 == 0o173`).
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if an integral constant literal starts with `0`.
|
||||
///
|
||||
/// **Why is this bad?** In some languages (including the infamous C language
|
||||
/// and most of its
|
||||
/// family), this marks an octal constant. In Rust however, this is a decimal
|
||||
/// constant. This could
|
||||
/// be confusing for both the writer and a reader of the constant.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// In Rust:
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// let a = 0123;
|
||||
/// println!("{}", a);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// prints `123`, while in C:
|
||||
///
|
||||
/// ```c
|
||||
/// #include <stdio.h>
|
||||
///
|
||||
/// int main() {
|
||||
/// int a = 0123;
|
||||
/// printf("%d\n", a);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// prints `83` (as `83 == 0o123` while `123 == 0o173`).
|
||||
pub ZERO_PREFIXED_LITERAL,
|
||||
complexity,
|
||||
"integer literals starting with `0`"
|
||||
}
|
||||
|
||||
/// **What it does:** Warns if a generic shadows a built-in type.
|
||||
///
|
||||
/// **Why is this bad?** This gives surprising type errors.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// impl<u32> Foo<u32> {
|
||||
/// fn impl_func(&self) -> u32 {
|
||||
/// 42
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if a generic shadows a built-in type.
|
||||
///
|
||||
/// **Why is this bad?** This gives surprising type errors.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```ignore
|
||||
/// impl<u32> Foo<u32> {
|
||||
/// fn impl_func(&self) -> u32 {
|
||||
/// 42
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub BUILTIN_TYPE_SHADOW,
|
||||
style,
|
||||
"shadowing a builtin type"
|
||||
|
@ -8,51 +8,51 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// **What it does:**
|
||||
///
|
||||
/// Suggests the use of `const` in functions and methods where possible.
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
///
|
||||
/// Not having the function const prevents callers of the function from being const as well.
|
||||
///
|
||||
/// **Known problems:**
|
||||
///
|
||||
/// Const functions are currently still being worked on, with some features only being available
|
||||
/// on nightly. This lint does not consider all edge cases currently and the suggestions may be
|
||||
/// incorrect if you are using this lint on stable.
|
||||
///
|
||||
/// Also, the lint only runs one pass over the code. Consider these two non-const functions:
|
||||
///
|
||||
/// ```rust
|
||||
/// fn a() -> i32 {
|
||||
/// 0
|
||||
/// }
|
||||
/// fn b() -> i32 {
|
||||
/// a()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When running Clippy, the lint will only suggest to make `a` const, because `b` at this time
|
||||
/// can't be const as it calls a non-const function. Making `a` const and running Clippy again,
|
||||
/// will suggest to make `b` const, too.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// fn new() -> Self {
|
||||
/// Self { random_number: 42 }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be a const fn:
|
||||
///
|
||||
/// ```rust
|
||||
/// const fn new() -> Self {
|
||||
/// Self { random_number: 42 }
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:**
|
||||
///
|
||||
/// Suggests the use of `const` in functions and methods where possible.
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
///
|
||||
/// Not having the function const prevents callers of the function from being const as well.
|
||||
///
|
||||
/// **Known problems:**
|
||||
///
|
||||
/// Const functions are currently still being worked on, with some features only being available
|
||||
/// on nightly. This lint does not consider all edge cases currently and the suggestions may be
|
||||
/// incorrect if you are using this lint on stable.
|
||||
///
|
||||
/// Also, the lint only runs one pass over the code. Consider these two non-const functions:
|
||||
///
|
||||
/// ```rust
|
||||
/// fn a() -> i32 {
|
||||
/// 0
|
||||
/// }
|
||||
/// fn b() -> i32 {
|
||||
/// a()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When running Clippy, the lint will only suggest to make `a` const, because `b` at this time
|
||||
/// can't be const as it calls a non-const function. Making `a` const and running Clippy again,
|
||||
/// will suggest to make `b` const, too.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// fn new() -> Self {
|
||||
/// Self { random_number: 42 }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be a const fn:
|
||||
///
|
||||
/// ```rust
|
||||
/// const fn new() -> Self {
|
||||
/// Self { random_number: 42 }
|
||||
/// }
|
||||
/// ```
|
||||
pub MISSING_CONST_FOR_FN,
|
||||
nursery,
|
||||
"Lint functions definitions that could be made `const fn`"
|
||||
|
@ -14,16 +14,16 @@ use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Warns if there is missing doc for any documentable item
|
||||
/// (public or private).
|
||||
///
|
||||
/// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS`
|
||||
/// allowed-by-default lint for
|
||||
/// public members, but has no way to enforce documentation of private items.
|
||||
/// This lint fixes that.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Warns if there is missing doc for any documentable item
|
||||
/// (public or private).
|
||||
///
|
||||
/// **Why is this bad?** Doc is good. *rustc* has a `MISSING_DOCS`
|
||||
/// allowed-by-default lint for
|
||||
/// public members, but has no way to enforce documentation of private items.
|
||||
/// This lint fixes that.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
pub MISSING_DOCS_IN_PRIVATE_ITEMS,
|
||||
restriction,
|
||||
"detects missing documentation for public and private members"
|
||||
|
@ -5,52 +5,52 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** it lints if an exported function, method, trait method with default impl,
|
||||
/// or trait method impl is not `#[inline]`.
|
||||
///
|
||||
/// **Why is this bad?** In general, it is not. Functions can be inlined across
|
||||
/// crates when that's profitable as long as any form of LTO is used. When LTO is disabled,
|
||||
/// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates
|
||||
/// might intend for most of the methods in their public API to be able to be inlined across
|
||||
/// crates even when LTO is disabled. For these types of crates, enabling this lint might make
|
||||
/// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and
|
||||
/// then opt out for specific methods where this might not make sense.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// pub fn foo() {} // missing #[inline]
|
||||
/// fn ok() {} // ok
|
||||
/// #[inline] pub fn bar() {} // ok
|
||||
/// #[inline(always)] pub fn baz() {} // ok
|
||||
///
|
||||
/// pub trait Bar {
|
||||
/// fn bar(); // ok
|
||||
/// fn def_bar() {} // missing #[inline]
|
||||
/// }
|
||||
///
|
||||
/// struct Baz;
|
||||
/// impl Baz {
|
||||
/// fn priv() {} // ok
|
||||
/// }
|
||||
///
|
||||
/// impl Bar for Baz {
|
||||
/// fn bar() {} // ok - Baz is not exported
|
||||
/// }
|
||||
///
|
||||
/// pub struct PubBaz;
|
||||
/// impl PubBaz {
|
||||
/// fn priv() {} // ok
|
||||
/// pub not_ptriv() {} // missing #[inline]
|
||||
/// }
|
||||
///
|
||||
/// impl Bar for PubBaz {
|
||||
/// fn bar() {} // missing #[inline]
|
||||
/// fn def_bar() {} // missing #[inline]
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** it lints if an exported function, method, trait method with default impl,
|
||||
/// or trait method impl is not `#[inline]`.
|
||||
///
|
||||
/// **Why is this bad?** In general, it is not. Functions can be inlined across
|
||||
/// crates when that's profitable as long as any form of LTO is used. When LTO is disabled,
|
||||
/// functions that are not `#[inline]` cannot be inlined across crates. Certain types of crates
|
||||
/// might intend for most of the methods in their public API to be able to be inlined across
|
||||
/// crates even when LTO is disabled. For these types of crates, enabling this lint might make
|
||||
/// sense. It allows the crate to require all exported methods to be `#[inline]` by default, and
|
||||
/// then opt out for specific methods where this might not make sense.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// pub fn foo() {} // missing #[inline]
|
||||
/// fn ok() {} // ok
|
||||
/// #[inline] pub fn bar() {} // ok
|
||||
/// #[inline(always)] pub fn baz() {} // ok
|
||||
///
|
||||
/// pub trait Bar {
|
||||
/// fn bar(); // ok
|
||||
/// fn def_bar() {} // missing #[inline]
|
||||
/// }
|
||||
///
|
||||
/// struct Baz;
|
||||
/// impl Baz {
|
||||
/// fn priv() {} // ok
|
||||
/// }
|
||||
///
|
||||
/// impl Bar for Baz {
|
||||
/// fn bar() {} // ok - Baz is not exported
|
||||
/// }
|
||||
///
|
||||
/// pub struct PubBaz;
|
||||
/// impl PubBaz {
|
||||
/// fn priv() {} // ok
|
||||
/// pub not_ptriv() {} // missing #[inline]
|
||||
/// }
|
||||
///
|
||||
/// impl Bar for PubBaz {
|
||||
/// fn bar() {} // missing #[inline]
|
||||
/// fn def_bar() {} // missing #[inline]
|
||||
/// }
|
||||
/// ```
|
||||
pub MISSING_INLINE_IN_PUBLIC_ITEMS,
|
||||
restriction,
|
||||
"detects missing #[inline] attribute for public callables (functions, trait methods, methods...)"
|
||||
|
@ -8,24 +8,24 @@ use syntax::{ast::*, source_map::DUMMY_SP};
|
||||
use cargo_metadata;
|
||||
use itertools::Itertools;
|
||||
|
||||
/// **What it does:** Checks to see if multiple versions of a crate are being
|
||||
/// used.
|
||||
///
|
||||
/// **Why is this bad?** This bloats the size of targets, and can lead to
|
||||
/// confusing error messages when structs or traits are used interchangeably
|
||||
/// between different versions of a crate.
|
||||
///
|
||||
/// **Known problems:** Because this can be caused purely by the dependencies
|
||||
/// themselves, it's not always possible to fix this issue.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```toml
|
||||
/// # This will pull in both winapi v0.3.4 and v0.2.8, triggering a warning.
|
||||
/// [dependencies]
|
||||
/// ctrlc = "3.1.0"
|
||||
/// ansi_term = "0.11.0"
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks to see if multiple versions of a crate are being
|
||||
/// used.
|
||||
///
|
||||
/// **Why is this bad?** This bloats the size of targets, and can lead to
|
||||
/// confusing error messages when structs or traits are used interchangeably
|
||||
/// between different versions of a crate.
|
||||
///
|
||||
/// **Known problems:** Because this can be caused purely by the dependencies
|
||||
/// themselves, it's not always possible to fix this issue.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```toml
|
||||
/// # This will pull in both winapi v0.3.4 and v0.2.8, triggering a warning.
|
||||
/// [dependencies]
|
||||
/// ctrlc = "3.1.0"
|
||||
/// ansi_term = "0.11.0"
|
||||
/// ```
|
||||
pub MULTIPLE_CRATE_VERSIONS,
|
||||
cargo,
|
||||
"multiple versions of the same crate being used"
|
||||
|
@ -5,19 +5,19 @@ use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintC
|
||||
use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for instances of `mut mut` references.
|
||||
///
|
||||
/// **Why is this bad?** Multiple `mut`s don't add anything meaningful to the
|
||||
/// source. This is either a copy'n'paste error, or it shows a fundamental
|
||||
/// misunderstanding of references.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = &mut &mut y;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for instances of `mut mut` references.
|
||||
///
|
||||
/// **Why is this bad?** Multiple `mut`s don't add anything meaningful to the
|
||||
/// source. This is either a copy'n'paste error, or it shows a fundamental
|
||||
/// misunderstanding of references.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = &mut &mut y;
|
||||
/// ```
|
||||
pub MUT_MUT,
|
||||
pedantic,
|
||||
"usage of double-mut refs, e.g. `&mut &mut ...`"
|
||||
|
@ -5,19 +5,19 @@ use rustc::ty::subst::Subst;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Detects giving a mutable reference to a function that only
|
||||
/// requires an immutable reference.
|
||||
///
|
||||
/// **Why is this bad?** The immutable reference rules out all other references
|
||||
/// to the value. Also the code misleads about the intent of the call site.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// my_vec.push(&mut value)
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects giving a mutable reference to a function that only
|
||||
/// requires an immutable reference.
|
||||
///
|
||||
/// **Why is this bad?** The immutable reference rules out all other references
|
||||
/// to the value. Also the code misleads about the intent of the call site.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// my_vec.push(&mut value)
|
||||
/// ```
|
||||
pub UNNECESSARY_MUT_PASSED,
|
||||
style,
|
||||
"an argument passed as a mutable reference although the callee only demands an immutable reference"
|
||||
|
@ -9,41 +9,41 @@ use rustc::ty::{self, Ty};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
|
||||
/// **What it does:** Checks for usages of `Mutex<X>` where an atomic will do.
|
||||
///
|
||||
/// **Why is this bad?** Using a mutex just to make access to a plain bool or
|
||||
/// reference sequential is shooting flies with cannons.
|
||||
/// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and
|
||||
/// faster.
|
||||
///
|
||||
/// **Known problems:** This lint cannot detect if the mutex is actually used
|
||||
/// for waiting before a critical section.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Mutex::new(&y);
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usages of `Mutex<X>` where an atomic will do.
|
||||
///
|
||||
/// **Why is this bad?** Using a mutex just to make access to a plain bool or
|
||||
/// reference sequential is shooting flies with cannons.
|
||||
/// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and
|
||||
/// faster.
|
||||
///
|
||||
/// **Known problems:** This lint cannot detect if the mutex is actually used
|
||||
/// for waiting before a critical section.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Mutex::new(&y);
|
||||
/// ```
|
||||
pub MUTEX_ATOMIC,
|
||||
perf,
|
||||
"using a mutex where an atomic value could be used instead"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for usages of `Mutex<X>` where `X` is an integral
|
||||
/// type.
|
||||
///
|
||||
/// **Why is this bad?** Using a mutex just to make access to a plain integer
|
||||
/// sequential is
|
||||
/// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.
|
||||
///
|
||||
/// **Known problems:** This lint cannot detect if the mutex is actually used
|
||||
/// for waiting before a critical section.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Mutex::new(0usize);
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usages of `Mutex<X>` where `X` is an integral
|
||||
/// type.
|
||||
///
|
||||
/// **Why is this bad?** Using a mutex just to make access to a plain integer
|
||||
/// sequential is
|
||||
/// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.
|
||||
///
|
||||
/// **Known problems:** This lint cannot detect if the mutex is actually used
|
||||
/// for waiting before a critical section.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Mutex::new(0usize);
|
||||
/// ```
|
||||
pub MUTEX_INTEGER,
|
||||
nursery,
|
||||
"using a mutex for an integer type"
|
||||
|
@ -11,44 +11,44 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Spanned;
|
||||
|
||||
/// **What it does:** Checks for expressions of the form `if c { true } else {
|
||||
/// false }`
|
||||
/// (or vice versa) and suggest using the condition directly.
|
||||
///
|
||||
/// **Why is this bad?** Redundant code.
|
||||
///
|
||||
/// **Known problems:** Maybe false positives: Sometimes, the two branches are
|
||||
/// painstakingly documented (which we of course do not detect), so they *may*
|
||||
/// have some value. Even then, the documentation can be rewritten to match the
|
||||
/// shorter code.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x {
|
||||
/// false
|
||||
/// } else {
|
||||
/// true
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expressions of the form `if c { true } else {
|
||||
/// false }`
|
||||
/// (or vice versa) and suggest using the condition directly.
|
||||
///
|
||||
/// **Why is this bad?** Redundant code.
|
||||
///
|
||||
/// **Known problems:** Maybe false positives: Sometimes, the two branches are
|
||||
/// painstakingly documented (which we of course do not detect), so they *may*
|
||||
/// have some value. Even then, the documentation can be rewritten to match the
|
||||
/// shorter code.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x {
|
||||
/// false
|
||||
/// } else {
|
||||
/// true
|
||||
/// }
|
||||
/// ```
|
||||
pub NEEDLESS_BOOL,
|
||||
complexity,
|
||||
"if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for expressions of the form `x == true`,
|
||||
/// `x != true` and order comparisons such as `x < true` (or vice versa) and
|
||||
/// suggest using the variable directly.
|
||||
///
|
||||
/// **Why is this bad?** Unnecessary code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x == true {} // could be `if x { }`
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expressions of the form `x == true`,
|
||||
/// `x != true` and order comparisons such as `x < true` (or vice versa) and
|
||||
/// suggest using the variable directly.
|
||||
///
|
||||
/// **Why is this bad?** Unnecessary code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x == true {} // could be `if x { }`
|
||||
/// ```
|
||||
pub BOOL_COMPARISON,
|
||||
complexity,
|
||||
"comparing a variable to a boolean, e.g. `if x == true` or `if x != true`"
|
||||
|
@ -11,19 +11,19 @@ use rustc::ty::adjustment::{Adjust, Adjustment};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for address of operations (`&`) that are going to
|
||||
/// be dereferenced immediately by the compiler.
|
||||
///
|
||||
/// **Why is this bad?** Suggests that the receiver of the expression borrows
|
||||
/// the expression.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: &i32 = &&&&&&5;
|
||||
/// ```
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for address of operations (`&`) that are going to
|
||||
/// be dereferenced immediately by the compiler.
|
||||
///
|
||||
/// **Why is this bad?** Suggests that the receiver of the expression borrows
|
||||
/// the expression.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: &i32 = &&&&&&5;
|
||||
/// ```
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
pub NEEDLESS_BORROW,
|
||||
nursery,
|
||||
"taking a reference that is going to be automatically dereferenced"
|
||||
|
@ -9,43 +9,43 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for useless borrowed references.
|
||||
///
|
||||
/// **Why is this bad?** It is mostly useless and make the code look more
|
||||
/// complex than it
|
||||
/// actually is.
|
||||
///
|
||||
/// **Known problems:** It seems that the `&ref` pattern is sometimes useful.
|
||||
/// For instance in the following snippet:
|
||||
/// ```rust
|
||||
/// enum Animal {
|
||||
/// Cat(u64),
|
||||
/// Dog(u64),
|
||||
/// }
|
||||
///
|
||||
/// fn foo(a: &Animal, b: &Animal) {
|
||||
/// match (a, b) {
|
||||
/// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime
|
||||
/// mismatch error
|
||||
/// (&Animal::Dog(ref c), &Animal::Dog(_)) => ()
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// There is a lifetime mismatch error for `k` (indeed a and b have distinct
|
||||
/// lifetime).
|
||||
/// This can be fixed by using the `&ref` pattern.
|
||||
/// However, the code can also be fixed by much cleaner ways
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut v = Vec::<String>::new();
|
||||
/// let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
/// ```
|
||||
/// This closure takes a reference on something that has been matched as a
|
||||
/// reference and
|
||||
/// de-referenced.
|
||||
/// As such, it could just be |a| a.is_empty()
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for useless borrowed references.
|
||||
///
|
||||
/// **Why is this bad?** It is mostly useless and make the code look more
|
||||
/// complex than it
|
||||
/// actually is.
|
||||
///
|
||||
/// **Known problems:** It seems that the `&ref` pattern is sometimes useful.
|
||||
/// For instance in the following snippet:
|
||||
/// ```rust
|
||||
/// enum Animal {
|
||||
/// Cat(u64),
|
||||
/// Dog(u64),
|
||||
/// }
|
||||
///
|
||||
/// fn foo(a: &Animal, b: &Animal) {
|
||||
/// match (a, b) {
|
||||
/// (&Animal::Cat(v), k) | (k, &Animal::Cat(v)) => (), // lifetime
|
||||
/// mismatch error
|
||||
/// (&Animal::Dog(ref c), &Animal::Dog(_)) => ()
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// There is a lifetime mismatch error for `k` (indeed a and b have distinct
|
||||
/// lifetime).
|
||||
/// This can be fixed by using the `&ref` pattern.
|
||||
/// However, the code can also be fixed by much cleaner ways
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let mut v = Vec::<String>::new();
|
||||
/// let _ = v.iter_mut().filter(|&ref a| a.is_empty());
|
||||
/// ```
|
||||
/// This closure takes a reference on something that has been matched as a
|
||||
/// reference and
|
||||
/// de-referenced.
|
||||
/// As such, it could just be |a| a.is_empty()
|
||||
pub NEEDLESS_BORROWED_REFERENCE,
|
||||
complexity,
|
||||
"taking a needless borrowed reference"
|
||||
|
@ -35,66 +35,66 @@ use syntax::source_map::{original_sp, DUMMY_SP};
|
||||
|
||||
use crate::utils::{in_macro, snippet, snippet_block, span_help_and_lint, trim_multiline};
|
||||
|
||||
/// **What it does:** The lint checks for `if`-statements appearing in loops
|
||||
/// that contain a `continue` statement in either their main blocks or their
|
||||
/// `else`-blocks, when omitting the `else`-block possibly with some
|
||||
/// rearrangement of code can make the code easier to understand.
|
||||
///
|
||||
/// **Why is this bad?** Having explicit `else` blocks for `if` statements
|
||||
/// containing `continue` in their THEN branch adds unnecessary branching and
|
||||
/// nesting to the code. Having an else block containing just `continue` can
|
||||
/// also be better written by grouping the statements following the whole `if`
|
||||
/// statement within the THEN block and omitting the else block completely.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// while condition() {
|
||||
/// update_condition();
|
||||
/// if x {
|
||||
/// // ...
|
||||
/// } else {
|
||||
/// continue;
|
||||
/// }
|
||||
/// println!("Hello, world");
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be rewritten as
|
||||
///
|
||||
/// ```rust
|
||||
/// while condition() {
|
||||
/// update_condition();
|
||||
/// if x {
|
||||
/// // ...
|
||||
/// println!("Hello, world");
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// As another example, the following code
|
||||
///
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// if waiting() {
|
||||
/// continue;
|
||||
/// } else {
|
||||
/// // Do something useful
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// Could be rewritten as
|
||||
///
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// if waiting() {
|
||||
/// continue;
|
||||
/// }
|
||||
/// // Do something useful
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** The lint checks for `if`-statements appearing in loops
|
||||
/// that contain a `continue` statement in either their main blocks or their
|
||||
/// `else`-blocks, when omitting the `else`-block possibly with some
|
||||
/// rearrangement of code can make the code easier to understand.
|
||||
///
|
||||
/// **Why is this bad?** Having explicit `else` blocks for `if` statements
|
||||
/// containing `continue` in their THEN branch adds unnecessary branching and
|
||||
/// nesting to the code. Having an else block containing just `continue` can
|
||||
/// also be better written by grouping the statements following the whole `if`
|
||||
/// statement within the THEN block and omitting the else block completely.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// while condition() {
|
||||
/// update_condition();
|
||||
/// if x {
|
||||
/// // ...
|
||||
/// } else {
|
||||
/// continue;
|
||||
/// }
|
||||
/// println!("Hello, world");
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be rewritten as
|
||||
///
|
||||
/// ```rust
|
||||
/// while condition() {
|
||||
/// update_condition();
|
||||
/// if x {
|
||||
/// // ...
|
||||
/// println!("Hello, world");
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// As another example, the following code
|
||||
///
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// if waiting() {
|
||||
/// continue;
|
||||
/// } else {
|
||||
/// // Do something useful
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// Could be rewritten as
|
||||
///
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// if waiting() {
|
||||
/// continue;
|
||||
/// }
|
||||
/// // Do something useful
|
||||
/// }
|
||||
/// ```
|
||||
pub NEEDLESS_CONTINUE,
|
||||
pedantic,
|
||||
"`continue` statements that can be replaced by a rearrangement of code"
|
||||
|
@ -20,30 +20,30 @@ use std::borrow::Cow;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// **What it does:** Checks for functions taking arguments by value, but not
|
||||
/// consuming them in its
|
||||
/// body.
|
||||
///
|
||||
/// **Why is this bad?** Taking arguments by reference is more flexible and can
|
||||
/// sometimes avoid
|
||||
/// unnecessary allocations.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// * This lint suggests taking an argument by reference,
|
||||
/// however sometimes it is better to let users decide the argument type
|
||||
/// (by using `Borrow` trait, for example), depending on how the function is used.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(v: Vec<i32>) {
|
||||
/// assert_eq!(v.len(), 42);
|
||||
/// }
|
||||
/// // should be
|
||||
/// fn foo(v: &[i32]) {
|
||||
/// assert_eq!(v.len(), 42);
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for functions taking arguments by value, but not
|
||||
/// consuming them in its
|
||||
/// body.
|
||||
///
|
||||
/// **Why is this bad?** Taking arguments by reference is more flexible and can
|
||||
/// sometimes avoid
|
||||
/// unnecessary allocations.
|
||||
///
|
||||
/// **Known problems:**
|
||||
/// * This lint suggests taking an argument by reference,
|
||||
/// however sometimes it is better to let users decide the argument type
|
||||
/// (by using `Borrow` trait, for example), depending on how the function is used.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(v: Vec<i32>) {
|
||||
/// assert_eq!(v.len(), 42);
|
||||
/// }
|
||||
/// // should be
|
||||
/// fn foo(v: &[i32]) {
|
||||
/// assert_eq!(v.len(), 42);
|
||||
/// }
|
||||
/// ```
|
||||
pub NEEDLESS_PASS_BY_VALUE,
|
||||
pedantic,
|
||||
"functions taking arguments by value, but not consuming them in its body"
|
||||
|
@ -4,23 +4,23 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::ty;
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for needlessly including a base struct on update
|
||||
/// when all fields are changed anyway.
|
||||
///
|
||||
/// **Why is this bad?** This will cost resources (because the base has to be
|
||||
/// somewhere), and make the code less readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// Point {
|
||||
/// x: 1,
|
||||
/// y: 0,
|
||||
/// ..zero_point
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for needlessly including a base struct on update
|
||||
/// when all fields are changed anyway.
|
||||
///
|
||||
/// **Why is this bad?** This will cost resources (because the base has to be
|
||||
/// somewhere), and make the code less readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// Point {
|
||||
/// x: 1,
|
||||
/// y: 0,
|
||||
/// ..zero_point
|
||||
/// }
|
||||
/// ```
|
||||
pub NEEDLESS_UPDATE,
|
||||
complexity,
|
||||
"using `Foo { ..base }` when there are no missing fields"
|
||||
|
@ -5,38 +5,38 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
use crate::utils::{self, paths, span_lint};
|
||||
|
||||
/// **What it does:**
|
||||
/// Checks for the usage of negated comparison operators on types which only implement
|
||||
/// `PartialOrd` (e.g. `f64`).
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// These operators make it easy to forget that the underlying types actually allow not only three
|
||||
/// potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is
|
||||
/// especially easy to miss if the operator based comparison result is negated.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
/// // Bad
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
///
|
||||
/// let _not_less_or_equal = !(a <= b);
|
||||
///
|
||||
/// // Good
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
///
|
||||
/// let _not_less_or_equal = match a.partial_cmp(&b) {
|
||||
/// None | Some(Ordering::Greater) => true,
|
||||
/// _ => false,
|
||||
/// };
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:**
|
||||
/// Checks for the usage of negated comparison operators on types which only implement
|
||||
/// `PartialOrd` (e.g. `f64`).
|
||||
///
|
||||
/// **Why is this bad?**
|
||||
/// These operators make it easy to forget that the underlying types actually allow not only three
|
||||
/// potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is
|
||||
/// especially easy to miss if the operator based comparison result is negated.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
/// // Bad
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
///
|
||||
/// let _not_less_or_equal = !(a <= b);
|
||||
///
|
||||
/// // Good
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
///
|
||||
/// let _not_less_or_equal = match a.partial_cmp(&b) {
|
||||
/// None | Some(Ordering::Greater) => true,
|
||||
/// _ => false,
|
||||
/// };
|
||||
/// ```
|
||||
pub NEG_CMP_OP_ON_PARTIAL_ORD,
|
||||
complexity,
|
||||
"The use of negated comparison operators on partially ordered types may produce confusing code."
|
||||
|
@ -7,17 +7,17 @@ use syntax::source_map::{Span, Spanned};
|
||||
use crate::consts::{self, Constant};
|
||||
use crate::utils::span_lint;
|
||||
|
||||
/// **What it does:** Checks for multiplication by -1 as a form of negation.
|
||||
///
|
||||
/// **Why is this bad?** It's more readable to just negate.
|
||||
///
|
||||
/// **Known problems:** This only catches integers (for now).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x * -1
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for multiplication by -1 as a form of negation.
|
||||
///
|
||||
/// **Why is this bad?** It's more readable to just negate.
|
||||
///
|
||||
/// **Known problems:** This only catches integers (for now).
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// x * -1
|
||||
/// ```
|
||||
pub NEG_MULTIPLY,
|
||||
style,
|
||||
"multiplying integers with -1"
|
||||
|
@ -11,74 +11,74 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for types with a `fn new() -> Self` method and no
|
||||
/// implementation of
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).
|
||||
///
|
||||
/// It detects both the case when a manual
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)
|
||||
/// implementation is required and also when it can be created with
|
||||
/// `#[derive(Default)]`
|
||||
///
|
||||
/// **Why is this bad?** The user might expect to be able to use
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the
|
||||
/// type can be constructed without arguments.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// struct Foo(Bar);
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Foo(Bar::new())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Instead, use:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct Foo(Bar);
|
||||
///
|
||||
/// impl Default for Foo {
|
||||
/// fn default() -> Self {
|
||||
/// Foo(Bar::new())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Or, if
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)
|
||||
/// can be derived by `#[derive(Default)]`:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Foo
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Instead, use:
|
||||
///
|
||||
/// ```rust
|
||||
/// #[derive(Default)]
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Foo
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You can also have `new()` call `Default::default()`.
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for types with a `fn new() -> Self` method and no
|
||||
/// implementation of
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).
|
||||
///
|
||||
/// It detects both the case when a manual
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)
|
||||
/// implementation is required and also when it can be created with
|
||||
/// `#[derive(Default)]`
|
||||
///
|
||||
/// **Why is this bad?** The user might expect to be able to use
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the
|
||||
/// type can be constructed without arguments.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```ignore
|
||||
/// struct Foo(Bar);
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Foo(Bar::new())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Instead, use:
|
||||
///
|
||||
/// ```ignore
|
||||
/// struct Foo(Bar);
|
||||
///
|
||||
/// impl Default for Foo {
|
||||
/// fn default() -> Self {
|
||||
/// Foo(Bar::new())
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Or, if
|
||||
/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)
|
||||
/// can be derived by `#[derive(Default)]`:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Foo
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Instead, use:
|
||||
///
|
||||
/// ```rust
|
||||
/// #[derive(Default)]
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn new() -> Self {
|
||||
/// Foo
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// You can also have `new()` call `Default::default()`.
|
||||
pub NEW_WITHOUT_DEFAULT,
|
||||
style,
|
||||
"`fn new() -> Self` method without `Default` implementation"
|
||||
|
@ -6,37 +6,37 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use std::ops::Deref;
|
||||
|
||||
/// **What it does:** Checks for statements which have no effect.
|
||||
///
|
||||
/// **Why is this bad?** Similar to dead code, these statements are actually
|
||||
/// executed. However, as they have no effect, all they do is make the code less
|
||||
/// readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// 0;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for statements which have no effect.
|
||||
///
|
||||
/// **Why is this bad?** Similar to dead code, these statements are actually
|
||||
/// executed. However, as they have no effect, all they do is make the code less
|
||||
/// readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// 0;
|
||||
/// ```
|
||||
pub NO_EFFECT,
|
||||
complexity,
|
||||
"statements with no effect"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for expression statements that can be reduced to a
|
||||
/// sub-expression.
|
||||
///
|
||||
/// **Why is this bad?** Expressions by themselves often have no side-effects.
|
||||
/// Having such expressions reduces readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// compute_array()[0];
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expression statements that can be reduced to a
|
||||
/// sub-expression.
|
||||
///
|
||||
/// **Why is this bad?** Expressions by themselves often have no side-effects.
|
||||
/// Having such expressions reduces readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// compute_array()[0];
|
||||
/// ```
|
||||
pub UNNECESSARY_OPERATION,
|
||||
complexity,
|
||||
"outer expressions with no effect"
|
||||
|
@ -14,69 +14,69 @@ use rustc_typeck::hir_ty_to_ty;
|
||||
use std::ptr;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
/// **What it does:** Checks for declaration of `const` items which is interior
|
||||
/// mutable (e.g. contains a `Cell`, `Mutex`, `AtomicXxxx` etc).
|
||||
///
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
|
||||
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
/// these types in the first place.
|
||||
///
|
||||
/// The `const` should better be replaced by a `static` item if a global
|
||||
/// variable is wanted, or replaced by a `const fn` if a constructor is wanted.
|
||||
///
|
||||
/// **Known problems:** A "non-constant" const item is a legacy way to supply an
|
||||
/// initialized value to downstream `static` items (e.g. the
|
||||
/// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
|
||||
/// and this lint should be suppressed.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
///
|
||||
/// // Bad.
|
||||
/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
/// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
|
||||
/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
|
||||
///
|
||||
/// // Good.
|
||||
/// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
|
||||
/// STATIC_ATOM.store(9, SeqCst);
|
||||
/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for declaration of `const` items which is interior
|
||||
/// mutable (e.g. contains a `Cell`, `Mutex`, `AtomicXxxx` etc).
|
||||
///
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
|
||||
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
/// these types in the first place.
|
||||
///
|
||||
/// The `const` should better be replaced by a `static` item if a global
|
||||
/// variable is wanted, or replaced by a `const fn` if a constructor is wanted.
|
||||
///
|
||||
/// **Known problems:** A "non-constant" const item is a legacy way to supply an
|
||||
/// initialized value to downstream `static` items (e.g. the
|
||||
/// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
|
||||
/// and this lint should be suppressed.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
///
|
||||
/// // Bad.
|
||||
/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
/// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
|
||||
/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
|
||||
///
|
||||
/// // Good.
|
||||
/// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);
|
||||
/// STATIC_ATOM.store(9, SeqCst);
|
||||
/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
|
||||
/// ```
|
||||
pub DECLARE_INTERIOR_MUTABLE_CONST,
|
||||
correctness,
|
||||
"declaring const with interior mutability"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks if `const` items which is interior mutable (e.g.
|
||||
/// contains a `Cell`, `Mutex`, `AtomicXxxx` etc) has been borrowed directly.
|
||||
///
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
|
||||
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
/// these types in the first place.
|
||||
///
|
||||
/// The `const` value should be stored inside a `static` item.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
///
|
||||
/// // Bad.
|
||||
/// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
|
||||
/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
|
||||
///
|
||||
/// // Good.
|
||||
/// static STATIC_ATOM: AtomicUsize = CONST_ATOM;
|
||||
/// STATIC_ATOM.store(9, SeqCst);
|
||||
/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks if `const` items which is interior mutable (e.g.
|
||||
/// contains a `Cell`, `Mutex`, `AtomicXxxx` etc) has been borrowed directly.
|
||||
///
|
||||
/// **Why is this bad?** Consts are copied everywhere they are referenced, i.e.
|
||||
/// every time you refer to the const a fresh instance of the `Cell` or `Mutex`
|
||||
/// or `AtomicXxxx` will be created, which defeats the whole purpose of using
|
||||
/// these types in the first place.
|
||||
///
|
||||
/// The `const` value should be stored inside a `static` item.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
|
||||
/// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);
|
||||
///
|
||||
/// // Bad.
|
||||
/// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged
|
||||
/// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct
|
||||
///
|
||||
/// // Good.
|
||||
/// static STATIC_ATOM: AtomicUsize = CONST_ATOM;
|
||||
/// STATIC_ATOM.store(9, SeqCst);
|
||||
/// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
|
||||
/// ```
|
||||
pub BORROW_INTERIOR_MUTABLE_CONST,
|
||||
correctness,
|
||||
"referencing const with interior mutability"
|
||||
|
@ -7,57 +7,57 @@ use syntax::source_map::Span;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::visit::{walk_block, walk_expr, walk_pat, Visitor};
|
||||
|
||||
/// **What it does:** Checks for names that are very similar and thus confusing.
|
||||
///
|
||||
/// **Why is this bad?** It's hard to distinguish between names that differ only
|
||||
/// by a single character.
|
||||
///
|
||||
/// **Known problems:** None?
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let checked_exp = something;
|
||||
/// let checked_expr = something_else;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for names that are very similar and thus confusing.
|
||||
///
|
||||
/// **Why is this bad?** It's hard to distinguish between names that differ only
|
||||
/// by a single character.
|
||||
///
|
||||
/// **Known problems:** None?
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let checked_exp = something;
|
||||
/// let checked_expr = something_else;
|
||||
/// ```
|
||||
pub SIMILAR_NAMES,
|
||||
pedantic,
|
||||
"similarly named items and bindings"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for too many variables whose name consists of a
|
||||
/// single character.
|
||||
///
|
||||
/// **Why is this bad?** It's hard to memorize what a variable means without a
|
||||
/// descriptive name.
|
||||
///
|
||||
/// **Known problems:** None?
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let (a, b, c, d, e, f, g) = (...);
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for too many variables whose name consists of a
|
||||
/// single character.
|
||||
///
|
||||
/// **Why is this bad?** It's hard to memorize what a variable means without a
|
||||
/// descriptive name.
|
||||
///
|
||||
/// **Known problems:** None?
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// let (a, b, c, d, e, f, g) = (...);
|
||||
/// ```
|
||||
pub MANY_SINGLE_CHAR_NAMES,
|
||||
style,
|
||||
"too many single character bindings"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks if you have variables whose name consists of just
|
||||
/// underscores and digits.
|
||||
///
|
||||
/// **Why is this bad?** It's hard to memorize what a variable means without a
|
||||
/// descriptive name.
|
||||
///
|
||||
/// **Known problems:** None?
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let _1 = 1;
|
||||
/// let ___1 = 1;
|
||||
/// let __1___2 = 11;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks if you have variables whose name consists of just
|
||||
/// underscores and digits.
|
||||
///
|
||||
/// **Why is this bad?** It's hard to memorize what a variable means without a
|
||||
/// descriptive name.
|
||||
///
|
||||
/// **Known problems:** None?
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let _1 = 1;
|
||||
/// let ___1 = 1;
|
||||
/// let __1___2 = 11;
|
||||
/// ```
|
||||
pub JUST_UNDERSCORES_AND_DIGITS,
|
||||
style,
|
||||
"unclear name"
|
||||
|
@ -4,31 +4,31 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:*** Checks for unnecessary `ok()` in if let.
|
||||
///
|
||||
/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match
|
||||
/// on `Ok(pat)`
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for result in iter {
|
||||
/// if let Some(bench) = try!(result).parse().ok() {
|
||||
/// vec.push(bench)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// for result in iter {
|
||||
/// if let Ok(bench) = try!(result).parse() {
|
||||
/// vec.push(bench)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:*** Checks for unnecessary `ok()` in if let.
|
||||
///
|
||||
/// **Why is this bad?** Calling `ok()` in if let is unnecessary, instead match
|
||||
/// on `Ok(pat)`
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// for result in iter {
|
||||
/// if let Some(bench) = try!(result).parse().ok() {
|
||||
/// vec.push(bench)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```ignore
|
||||
/// for result in iter {
|
||||
/// if let Ok(bench) = try!(result).parse() {
|
||||
/// vec.push(bench)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub IF_LET_SOME_RESULT,
|
||||
style,
|
||||
"usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead"
|
||||
|
@ -5,19 +5,21 @@ use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::{Span, Spanned};
|
||||
|
||||
/// **What it does:** Checks for duplicate open options as well as combinations
|
||||
/// that make no sense.
|
||||
///
|
||||
/// **Why is this bad?** In the best case, the code will be harder to read than
|
||||
/// necessary. I don't know the worst case.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// OpenOptions::new().read(true).truncate(true)
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for duplicate open options as well as combinations
|
||||
/// that make no sense.
|
||||
///
|
||||
/// **Why is this bad?** In the best case, the code will be harder to read than
|
||||
/// necessary. I don't know the worst case.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::fs::OpenOptions;
|
||||
///
|
||||
/// OpenOptions::new().read(true).truncate(true);
|
||||
/// ```
|
||||
pub NONSENSICAL_OPEN_OPTIONS,
|
||||
correctness,
|
||||
"nonsensical combination of options for opening a file"
|
||||
|
@ -4,18 +4,18 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Detects classic underflow/overflow checks.
|
||||
///
|
||||
/// **Why is this bad?** Most classic C underflow/overflow checks will fail in
|
||||
/// Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + b < a
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Detects classic underflow/overflow checks.
|
||||
///
|
||||
/// **Why is this bad?** Most classic C underflow/overflow checks will fail in
|
||||
/// Rust. Users can use functions like `overflowing_*` and `wrapping_*` instead.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + b < a
|
||||
/// ```
|
||||
pub OVERFLOW_CHECK_CONDITIONAL,
|
||||
complexity,
|
||||
"overflow checks inspired by C which are likely to panic"
|
||||
|
@ -7,36 +7,36 @@ use syntax::ast::LitKind;
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::Span;
|
||||
|
||||
/// **What it does:** Checks for missing parameters in `panic!`.
|
||||
///
|
||||
/// **Why is this bad?** Contrary to the `format!` family of macros, there are
|
||||
/// two forms of `panic!`: if there are no parameters given, the first argument
|
||||
/// is not a format string and used literally. So while `format!("{}")` will
|
||||
/// fail to compile, `panic!("{}")` will not.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// panic!("This `panic!` is probably missing a parameter there: {}");
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for missing parameters in `panic!`.
|
||||
///
|
||||
/// **Why is this bad?** Contrary to the `format!` family of macros, there are
|
||||
/// two forms of `panic!`: if there are no parameters given, the first argument
|
||||
/// is not a format string and used literally. So while `format!("{}")` will
|
||||
/// fail to compile, `panic!("{}")` will not.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// panic!("This `panic!` is probably missing a parameter there: {}");
|
||||
/// ```
|
||||
pub PANIC_PARAMS,
|
||||
style,
|
||||
"missing parameters in `panic!` calls"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for usage of `unimplemented!`.
|
||||
///
|
||||
/// **Why is this bad?** This macro should not be present in production code
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// unimplemented!();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of `unimplemented!`.
|
||||
///
|
||||
/// **Why is this bad?** This macro should not be present in production code
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```no_run
|
||||
/// unimplemented!();
|
||||
/// ```
|
||||
pub UNIMPLEMENTED,
|
||||
restriction,
|
||||
"`unimplemented!` should not be present in production code"
|
||||
|
@ -4,25 +4,25 @@ use rustc::hir::*;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for manual re-implementations of `PartialEq::ne`.
|
||||
///
|
||||
/// **Why is this bad?** `PartialEq::ne` is required to always return the
|
||||
/// negated result of `PartialEq::eq`, which is exactly what the default
|
||||
/// implementation does. Therefore, there should never be any need to
|
||||
/// re-implement it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl PartialEq for Foo {
|
||||
/// fn eq(&self, other: &Foo) -> bool { ... }
|
||||
/// fn ne(&self, other: &Foo) -> bool { !(self == other) }
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for manual re-implementations of `PartialEq::ne`.
|
||||
///
|
||||
/// **Why is this bad?** `PartialEq::ne` is required to always return the
|
||||
/// negated result of `PartialEq::eq`, which is exactly what the default
|
||||
/// implementation does. Therefore, there should never be any need to
|
||||
/// re-implement it.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl PartialEq for Foo {
|
||||
/// fn eq(&self, other: &Foo) -> bool { ... }
|
||||
/// fn ne(&self, other: &Foo) -> bool { !(self == other) }
|
||||
/// }
|
||||
/// ```
|
||||
pub PARTIALEQ_NE_IMPL,
|
||||
complexity,
|
||||
"re-implementing `PartialEq::ne`"
|
||||
|
@ -5,24 +5,24 @@ use rustc_errors::Applicability;
|
||||
use syntax::ast::*;
|
||||
use syntax::source_map::Spanned;
|
||||
|
||||
/// **What it does:** Checks for operations where precedence may be unclear
|
||||
/// and suggests to add parentheses. Currently it catches the following:
|
||||
/// * mixed usage of arithmetic and bit shifting/combining operators without
|
||||
/// parentheses
|
||||
/// * a "negative" numeric literal (which is really a unary `-` followed by a
|
||||
/// numeric literal)
|
||||
/// followed by a method call
|
||||
///
|
||||
/// **Why is this bad?** Not everyone knows the precedence of those operators by
|
||||
/// heart, so expressions like these may trip others trying to reason about the
|
||||
/// code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
|
||||
/// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for operations where precedence may be unclear
|
||||
/// and suggests to add parentheses. Currently it catches the following:
|
||||
/// * mixed usage of arithmetic and bit shifting/combining operators without
|
||||
/// parentheses
|
||||
/// * a "negative" numeric literal (which is really a unary `-` followed by a
|
||||
/// numeric literal)
|
||||
/// followed by a method call
|
||||
///
|
||||
/// **Why is this bad?** Not everyone knows the precedence of those operators by
|
||||
/// heart, so expressions like these may trip others trying to reason about the
|
||||
/// code.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
|
||||
/// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1
|
||||
pub PRECEDENCE,
|
||||
complexity,
|
||||
"operations where precedence may be unclear"
|
||||
|
@ -13,82 +13,82 @@ use std::borrow::Cow;
|
||||
use syntax::source_map::Span;
|
||||
use syntax_pos::MultiSpan;
|
||||
|
||||
/// **What it does:** This lint checks for function arguments of type `&String`
|
||||
/// or `&Vec` unless the references are mutable. It will also suggest you
|
||||
/// replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()`
|
||||
/// calls.
|
||||
///
|
||||
/// **Why is this bad?** Requiring the argument to be of the specific size
|
||||
/// makes the function less useful for no benefit; slices in the form of `&[T]`
|
||||
/// or `&str` usually suffice and can be obtained from other types, too.
|
||||
///
|
||||
/// **Known problems:** The lint does not follow data. So if you have an
|
||||
/// argument `x` and write `let y = x; y.clone()` the lint will not suggest
|
||||
/// changing that `.clone()` to `.to_owned()`.
|
||||
///
|
||||
/// Other functions called from this function taking a `&String` or `&Vec`
|
||||
/// argument may also fail to compile if you change the argument. Applying
|
||||
/// this lint on them will fix the problem, but they may be in other crates.
|
||||
///
|
||||
/// Also there may be `fn(&Vec)`-typed references pointing to your function.
|
||||
/// If you have them, you will get a compiler error after applying this lint's
|
||||
/// suggestions. You then have the choice to undo your changes or change the
|
||||
/// type of the reference.
|
||||
///
|
||||
/// Note that if the function is part of your public interface, there may be
|
||||
/// other crates referencing it you may not be aware. Carefully deprecate the
|
||||
/// function before applying the lint suggestions in this case.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(&Vec<u32>) { .. }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** This lint checks for function arguments of type `&String`
|
||||
/// or `&Vec` unless the references are mutable. It will also suggest you
|
||||
/// replace `.clone()` calls with the appropriate `.to_owned()`/`to_string()`
|
||||
/// calls.
|
||||
///
|
||||
/// **Why is this bad?** Requiring the argument to be of the specific size
|
||||
/// makes the function less useful for no benefit; slices in the form of `&[T]`
|
||||
/// or `&str` usually suffice and can be obtained from other types, too.
|
||||
///
|
||||
/// **Known problems:** The lint does not follow data. So if you have an
|
||||
/// argument `x` and write `let y = x; y.clone()` the lint will not suggest
|
||||
/// changing that `.clone()` to `.to_owned()`.
|
||||
///
|
||||
/// Other functions called from this function taking a `&String` or `&Vec`
|
||||
/// argument may also fail to compile if you change the argument. Applying
|
||||
/// this lint on them will fix the problem, but they may be in other crates.
|
||||
///
|
||||
/// Also there may be `fn(&Vec)`-typed references pointing to your function.
|
||||
/// If you have them, you will get a compiler error after applying this lint's
|
||||
/// suggestions. You then have the choice to undo your changes or change the
|
||||
/// type of the reference.
|
||||
///
|
||||
/// Note that if the function is part of your public interface, there may be
|
||||
/// other crates referencing it you may not be aware. Carefully deprecate the
|
||||
/// function before applying the lint suggestions in this case.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// fn foo(&Vec<u32>) { .. }
|
||||
/// ```
|
||||
pub PTR_ARG,
|
||||
style,
|
||||
"fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for equality comparisons with `ptr::null`
|
||||
///
|
||||
/// **Why is this bad?** It's easier and more readable to use the inherent
|
||||
/// `.is_null()`
|
||||
/// method instead
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x == ptr::null {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** This lint checks for equality comparisons with `ptr::null`
|
||||
///
|
||||
/// **Why is this bad?** It's easier and more readable to use the inherent
|
||||
/// `.is_null()`
|
||||
/// method instead
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if x == ptr::null {
|
||||
/// ..
|
||||
/// }
|
||||
/// ```
|
||||
pub CMP_NULL,
|
||||
style,
|
||||
"comparing a pointer to a null pointer, suggesting to use `.is_null()` instead."
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for functions that take immutable
|
||||
/// references and return
|
||||
/// mutable ones.
|
||||
///
|
||||
/// **Why is this bad?** This is trivially unsound, as one can create two
|
||||
/// mutable references
|
||||
/// from the same (immutable!) source. This
|
||||
/// [error](https://github.com/rust-lang/rust/issues/39465)
|
||||
/// actually lead to an interim Rust release 1.15.1.
|
||||
///
|
||||
/// **Known problems:** To be on the conservative side, if there's at least one
|
||||
/// mutable reference
|
||||
/// with the output lifetime, this lint will not trigger. In practice, this
|
||||
/// case is unlikely anyway.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(&Foo) -> &mut Bar { .. }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** This lint checks for functions that take immutable
|
||||
/// references and return
|
||||
/// mutable ones.
|
||||
///
|
||||
/// **Why is this bad?** This is trivially unsound, as one can create two
|
||||
/// mutable references
|
||||
/// from the same (immutable!) source. This
|
||||
/// [error](https://github.com/rust-lang/rust/issues/39465)
|
||||
/// actually lead to an interim Rust release 1.15.1.
|
||||
///
|
||||
/// **Known problems:** To be on the conservative side, if there's at least one
|
||||
/// mutable reference
|
||||
/// with the output lifetime, this lint will not trigger. In practice, this
|
||||
/// case is unlikely anyway.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// fn foo(&Foo) -> &mut Bar { .. }
|
||||
/// ```
|
||||
pub MUT_FROM_REF,
|
||||
correctness,
|
||||
"fns that create mutable refs from immutable ref args"
|
||||
|
@ -3,37 +3,37 @@ use rustc::{declare_tool_lint, hir, lint, lint_array};
|
||||
use rustc_errors::Applicability;
|
||||
use std::fmt;
|
||||
|
||||
/// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an
|
||||
/// `isize`.
|
||||
///
|
||||
/// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric
|
||||
/// cast by using the `add` method instead.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let vec = vec![b'a', b'b', b'c'];
|
||||
/// let ptr = vec.as_ptr();
|
||||
/// let offset = 1_usize;
|
||||
///
|
||||
/// unsafe {
|
||||
/// ptr.offset(offset as isize);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// let vec = vec![b'a', b'b', b'c'];
|
||||
/// let ptr = vec.as_ptr();
|
||||
/// let offset = 1_usize;
|
||||
///
|
||||
/// unsafe {
|
||||
/// ptr.add(offset);
|
||||
/// }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an
|
||||
/// `isize`.
|
||||
///
|
||||
/// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric
|
||||
/// cast by using the `add` method instead.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let vec = vec![b'a', b'b', b'c'];
|
||||
/// let ptr = vec.as_ptr();
|
||||
/// let offset = 1_usize;
|
||||
///
|
||||
/// unsafe {
|
||||
/// ptr.offset(offset as isize);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// let vec = vec![b'a', b'b', b'c'];
|
||||
/// let ptr = vec.as_ptr();
|
||||
/// let offset = 1_usize;
|
||||
///
|
||||
/// unsafe {
|
||||
/// ptr.add(offset);
|
||||
/// }
|
||||
/// ```
|
||||
pub PTR_OFFSET_WITH_CAST,
|
||||
complexity,
|
||||
"unneeded pointer offset cast"
|
||||
|
@ -10,25 +10,25 @@ use crate::utils::paths::*;
|
||||
use crate::utils::{match_def_path, match_type, span_lint_and_then, SpanlessEq};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
/// **What it does:** Checks for expressions that could be replaced by the question mark operator
|
||||
///
|
||||
/// **Why is this bad?** Question mark usage is more idiomatic
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if option.is_none() {
|
||||
/// return None;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// option?;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for expressions that could be replaced by the question mark operator
|
||||
///
|
||||
/// **Why is this bad?** Question mark usage is more idiomatic
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```ignore
|
||||
/// if option.is_none() {
|
||||
/// return None;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```ignore
|
||||
/// option?;
|
||||
/// ```
|
||||
pub QUESTION_MARK,
|
||||
style,
|
||||
"checks for expressions that could be replaced by the question mark operator"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user