move lint documentation into macro invocations
This commit is contained in:
parent
a8f61e70a8
commit
fe96ffeac9
132 changed files with 5405 additions and 5390 deletions
|
@ -12,8 +12,9 @@ use walkdir::WalkDir;
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref DEC_CLIPPY_LINT_RE: Regex = Regex::new(
|
static ref DEC_CLIPPY_LINT_RE: Regex = Regex::new(
|
||||||
r#"(?x)
|
r#"(?x)
|
||||||
declare_clippy_lint!\s*[\{(]\s*
|
declare_clippy_lint!\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<cat>[a-z_]+)\s*,\s*
|
(?P<cat>[a-z_]+)\s*,\s*
|
||||||
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
||||||
"#
|
"#
|
||||||
|
@ -22,7 +23,8 @@ lazy_static! {
|
||||||
static ref DEC_DEPRECATED_LINT_RE: Regex = Regex::new(
|
static ref DEC_DEPRECATED_LINT_RE: Regex = Regex::new(
|
||||||
r#"(?x)
|
r#"(?x)
|
||||||
declare_deprecated_lint!\s*[{(]\s*
|
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*[})]
|
"(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,28 +6,28 @@ use std::f64::consts as f64;
|
||||||
use syntax::ast::{FloatTy, Lit, LitKind};
|
use syntax::ast::{FloatTy, Lit, LitKind};
|
||||||
use syntax::symbol;
|
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! {
|
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,
|
pub APPROX_CONSTANT,
|
||||||
correctness,
|
correctness,
|
||||||
"the approximate of a known float constant (in `std::fXX::consts`)"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub INTEGER_ARITHMETIC,
|
||||||
restriction,
|
restriction,
|
||||||
"any integer arithmetic statement"
|
"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! {
|
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,
|
pub FLOAT_ARITHMETIC,
|
||||||
restriction,
|
restriction,
|
||||||
"any floating-point arithmetic statement"
|
"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 crate::utils::{in_macro, is_direct_expn_of, span_help_and_lint};
|
||||||
use if_chain::if_chain;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// assert!(false)
|
||||||
|
/// // or
|
||||||
|
/// assert!(true)
|
||||||
|
/// // or
|
||||||
|
/// const B: bool = false;
|
||||||
|
/// assert!(B)
|
||||||
|
/// ```
|
||||||
pub ASSERTIONS_ON_CONSTANTS,
|
pub ASSERTIONS_ON_CONSTANTS,
|
||||||
style,
|
style,
|
||||||
"assert!(true/false) will be optimized out by the compiler/should probably be replaced by a panic!() or unreachable!()"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let mut a = 5;
|
||||||
|
/// ...
|
||||||
|
/// a = a + b;
|
||||||
|
/// ```
|
||||||
pub ASSIGN_OP_PATTERN,
|
pub ASSIGN_OP_PATTERN,
|
||||||
style,
|
style,
|
||||||
"assigning the result of an operation on a variable to that same variable"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let mut a = 5;
|
||||||
|
/// ...
|
||||||
|
/// a += a + b;
|
||||||
|
/// ```
|
||||||
pub MISREFACTORED_ASSIGN_OP,
|
pub MISREFACTORED_ASSIGN_OP,
|
||||||
complexity,
|
complexity,
|
||||||
"having a variable on both sides of an assign op"
|
"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::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
|
||||||
use syntax::source_map::Span;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// #[inline(always)]
|
||||||
|
/// fn not_quite_hot_code(..) { ... }
|
||||||
|
/// ```
|
||||||
pub INLINE_ALWAYS,
|
pub INLINE_ALWAYS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"use of `#[inline(always)]`"
|
"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! {
|
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:**
|
||||||
|
/// ```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;
|
||||||
|
/// ```
|
||||||
pub USELESS_ATTRIBUTE,
|
pub USELESS_ATTRIBUTE,
|
||||||
correctness,
|
correctness,
|
||||||
"use of lint attributes on `extern crate` items"
|
"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! {
|
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,
|
pub DEPRECATED_SEMVER,
|
||||||
correctness,
|
correctness,
|
||||||
"use of `#[deprecated(since = \"x\")]` where x is not semver"
|
"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! {
|
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,
|
pub EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||||
nursery,
|
nursery,
|
||||||
"empty line after outer attribute"
|
"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! {
|
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,
|
pub UNKNOWN_CLIPPY_LINTS,
|
||||||
style,
|
style,
|
||||||
"unknown_lints for scoped Clippy lints"
|
"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! {
|
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,
|
pub DEPRECATED_CFG_ATTR,
|
||||||
complexity,
|
complexity,
|
||||||
"usage of `cfg_attr(rustfmt)` instead of `tool_attributes`"
|
"usage of `cfg_attr(rustfmt)` instead of `tool_attributes`"
|
||||||
|
|
|
@ -9,83 +9,83 @@ use rustc_errors::Applicability;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if (x & 1 == 2) { … }
|
||||||
|
/// ```
|
||||||
pub BAD_BIT_MASK,
|
pub BAD_BIT_MASK,
|
||||||
correctness,
|
correctness,
|
||||||
"expressions of the form `_ & mask == select` that will only ever return `true` or `false`"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if (x | 1 > 3) { … }
|
||||||
|
/// ```
|
||||||
pub INEFFECTIVE_BIT_MASK,
|
pub INEFFECTIVE_BIT_MASK,
|
||||||
correctness,
|
correctness,
|
||||||
"expressions where a bit mask will be rendered useless by a comparison, e.g. `(x | 1) > 2`"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// x & 0x1111 == 0
|
||||||
|
/// ```
|
||||||
pub VERBOSE_BIT_MASK,
|
pub VERBOSE_BIT_MASK,
|
||||||
style,
|
style,
|
||||||
"expressions where a bit mask is less readable than the corresponding method call"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
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! {
|
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,
|
pub BLACKLISTED_NAME,
|
||||||
style,
|
style,
|
||||||
"usage of a blacklisted/placeholder name"
|
"usage of a blacklisted/placeholder name"
|
||||||
|
|
|
@ -5,38 +5,38 @@ use rustc::hir::*;
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub BLOCK_IN_IF_CONDITION_EXPR,
|
||||||
style,
|
style,
|
||||||
"braces that can be eliminated in conditions, e.g. `if { true } ...`"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if { let x = somefunc(); x } ..
|
||||||
|
/// // or
|
||||||
|
/// if somefunc(|x| { x == 47 }) ..
|
||||||
|
/// ```
|
||||||
pub BLOCK_IN_IF_CONDITION_STMT,
|
pub BLOCK_IN_IF_CONDITION_STMT,
|
||||||
style,
|
style,
|
||||||
"complex blocks in conditions, e.g. `if { let x = true; x } ...`"
|
"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::ast::LitKind;
|
||||||
use syntax::source_map::{dummy_spanned, Span, DUMMY_SP};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if a && true // should be: if a
|
||||||
|
/// if !(a == b) // should be: if a != b
|
||||||
|
/// ```
|
||||||
pub NONMINIMAL_BOOL,
|
pub NONMINIMAL_BOOL,
|
||||||
complexity,
|
complexity,
|
||||||
"boolean expressions that can be written more concisely"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if a && b || a { ... }
|
||||||
|
/// ```
|
||||||
|
/// The `b` is unnecessary, the expression is equivalent to `if a`.
|
||||||
pub LOGIC_BUG,
|
pub LOGIC_BUG,
|
||||||
correctness,
|
correctness,
|
||||||
"boolean expressions that contain terminals which can be eliminated"
|
"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 rustc_errors::Applicability;
|
||||||
use syntax::ast::{Name, UintTy};
|
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! {
|
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,
|
pub NAIVE_BYTECOUNT,
|
||||||
perf,
|
perf,
|
||||||
"use of naive `<slice>.filter(|&x| x == y).count()` to count byte values"
|
"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;
|
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! {
|
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,
|
pub CARGO_COMMON_METADATA,
|
||||||
cargo,
|
cargo,
|
||||||
"common metadata is defined in `Cargo.toml`"
|
"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 crate::utils::{in_macro, snippet_block, snippet_block_with_applicability, span_lint_and_sugg, span_lint_and_then};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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,
|
pub COLLAPSIBLE_IF,
|
||||||
style,
|
style,
|
||||||
"`if`s that can be collapsed (e.g. `if x { if y { ... } }` and `else { if x { ... } }`)"
|
"`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 rustc_errors::Applicability;
|
||||||
use syntax::ast::*;
|
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! {
|
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:**
|
||||||
|
/// ```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)] = &[...]
|
||||||
|
/// ```
|
||||||
pub CONST_STATIC_LIFETIME,
|
pub CONST_STATIC_LIFETIME,
|
||||||
style,
|
style,
|
||||||
"Using explicit `'static` lifetime for constants when elision rules would allow omitting them."
|
"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 std::hash::BuildHasherDefault;
|
||||||
use syntax::symbol::LocalInternedString;
|
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! {
|
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:**
|
||||||
|
/// ```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
|
||||||
|
/// …
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub IFS_SAME_COND,
|
pub IFS_SAME_COND,
|
||||||
correctness,
|
correctness,
|
||||||
"consecutive `ifs` with the same condition"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let foo = if … {
|
||||||
|
/// 42
|
||||||
|
/// } else {
|
||||||
|
/// 42
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub IF_SAME_THEN_ELSE,
|
pub IF_SAME_THEN_ELSE,
|
||||||
correctness,
|
correctness,
|
||||||
"if with the same *then* and *else* blocks"
|
"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! {
|
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,
|
pub MATCH_SAME_ARMS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`match` with identical arm bodies"
|
"`match` with identical arm bodies"
|
||||||
|
|
|
@ -3,27 +3,27 @@ use rustc::hir::{Item, ItemKind};
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub COPY_ITERATOR,
|
||||||
pedantic,
|
pedantic,
|
||||||
"implementing `Iterator` on a `Copy` type"
|
"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};
|
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! {
|
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,
|
pub CYCLOMATIC_COMPLEXITY,
|
||||||
complexity,
|
complexity,
|
||||||
"functions that should be split up into multiple functions"
|
"functions that should be split up into multiple functions"
|
||||||
|
|
|
@ -6,22 +6,22 @@ use syntax::ast;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
use syntax::tokenstream::TokenStream;
|
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! {
|
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,
|
pub DBG_MACRO,
|
||||||
restriction,
|
restriction,
|
||||||
"`dbg!` macro is intended as a debugging tool"
|
"`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};
|
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! {
|
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,
|
pub DEFAULT_TRAIT_ACCESS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"checks for literal calls to Default::default()"
|
"checks for literal calls to Default::default()"
|
||||||
|
|
|
@ -7,56 +7,56 @@ use rustc::ty::{self, Ty};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::source_map::Span;
|
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! {
|
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:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// k1 == k2 ⇒ hash(k1) == hash(k2)
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// ```rust
|
||||||
|
/// #[derive(Hash)]
|
||||||
|
/// struct Foo;
|
||||||
|
///
|
||||||
|
/// impl PartialEq for Foo {
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub DERIVE_HASH_XOR_EQ,
|
pub DERIVE_HASH_XOR_EQ,
|
||||||
correctness,
|
correctness,
|
||||||
"deriving `Hash` but implementing `PartialEq` explicitly"
|
"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! {
|
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,
|
pub EXPL_IMPL_CLONE_ON_COPY,
|
||||||
pedantic,
|
pedantic,
|
||||||
"implementing `Clone` explicitly on `Copy` types"
|
"implementing `Clone` explicitly on `Copy` types"
|
||||||
|
|
|
@ -9,25 +9,25 @@ use syntax::source_map::{BytePos, Span};
|
||||||
use syntax_pos::Pos;
|
use syntax_pos::Pos;
|
||||||
use url::Url;
|
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! {
|
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,
|
pub DOC_MARKDOWN,
|
||||||
pedantic,
|
pedantic,
|
||||||
"presence of `_`, `::` or camel-case outside backticks in documentation"
|
"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};
|
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! {
|
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,
|
pub DOUBLE_COMPARISONS,
|
||||||
complexity,
|
complexity,
|
||||||
"unnecessary double comparisons that can be simplified"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast::*;
|
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! {
|
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,
|
pub DOUBLE_PARENS,
|
||||||
complexity,
|
complexity,
|
||||||
"Warn on unnecessary double parentheses"
|
"Warn on unnecessary double parentheses"
|
||||||
|
|
|
@ -4,29 +4,29 @@ use rustc::hir::*;
|
||||||
use rustc::lint::{LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub DROP_BOUNDS,
|
||||||
correctness,
|
correctness,
|
||||||
"Bounds of the form `T: Drop` are useless"
|
"Bounds of the form `T: Drop` are useless"
|
||||||
|
|
|
@ -5,93 +5,93 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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:**
|
||||||
|
/// ```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();
|
||||||
|
/// ```
|
||||||
pub DROP_REF,
|
pub DROP_REF,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::drop` with a reference instead of an owned value"
|
"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! {
|
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,
|
pub FORGET_REF,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::forget` with a reference instead of an owned value"
|
"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! {
|
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,
|
pub DROP_COPY,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::drop` with a value that implements Copy"
|
"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! {
|
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,
|
pub FORGET_COPY,
|
||||||
correctness,
|
correctness,
|
||||||
"calls to `std::mem::forget` with a value that implements Copy"
|
"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::paths;
|
||||||
use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty};
|
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! {
|
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,
|
pub DURATION_SUBSEC,
|
||||||
complexity,
|
complexity,
|
||||||
"checks for calculation of subsecond microseconds or milliseconds"
|
"checks for calculation of subsecond microseconds or milliseconds"
|
||||||
|
|
|
@ -6,34 +6,34 @@ use syntax::ast::*;
|
||||||
|
|
||||||
use crate::utils::span_help_and_lint;
|
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! {
|
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,
|
pub ELSE_IF_WITHOUT_ELSE,
|
||||||
restriction,
|
restriction,
|
||||||
"if expression with an `else if`, but without a final `else` branch"
|
"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::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub EMPTY_ENUM,
|
||||||
pedantic,
|
pedantic,
|
||||||
"enum with no variants"
|
"enum with no variants"
|
||||||
|
|
|
@ -8,30 +8,30 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub MAP_ENTRY,
|
||||||
perf,
|
perf,
|
||||||
"use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast::{IntTy, UintTy};
|
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! {
|
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,
|
pub ENUM_CLIKE_UNPORTABLE_VARIANT,
|
||||||
correctness,
|
correctness,
|
||||||
"C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub ENUM_GLOB_USE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"use items that import all variants of an enum"
|
"use items that import all variants of an enum"
|
||||||
|
|
|
@ -8,94 +8,94 @@ use syntax::ast::*;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
use syntax::symbol::{InternedString, LocalInternedString};
|
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! {
|
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,
|
pub ENUM_VARIANT_NAMES,
|
||||||
style,
|
style,
|
||||||
"enums where all variants share a prefix/postfix"
|
"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! {
|
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,
|
pub PUB_ENUM_VARIANT_NAMES,
|
||||||
pedantic,
|
pedantic,
|
||||||
"enums where all variants share a prefix/postfix"
|
"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! {
|
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,
|
pub MODULE_NAME_REPETITIONS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"type names prefixed/postfixed with their containing module's name"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// // lib.rs
|
||||||
|
/// mod foo;
|
||||||
|
/// // foo.rs
|
||||||
|
/// mod foo {
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub MODULE_INCEPTION,
|
pub MODULE_INCEPTION,
|
||||||
style,
|
style,
|
||||||
"modules that have the same name as their parent module"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// x + 1 == x + 1
|
||||||
|
/// ```
|
||||||
pub EQ_OP,
|
pub EQ_OP,
|
||||||
correctness,
|
correctness,
|
||||||
"equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// &x == y
|
||||||
|
/// ```
|
||||||
pub OP_REF,
|
pub OP_REF,
|
||||||
style,
|
style,
|
||||||
"taking a reference to satisfy the type constraints on `==`"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::source_map::Span;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// 0 / x;
|
||||||
|
/// 0 * x;
|
||||||
|
/// x & 0
|
||||||
|
/// ```
|
||||||
pub ERASING_OP,
|
pub ERASING_OP,
|
||||||
correctness,
|
correctness,
|
||||||
"using erasing operations, e.g. `x * 0` or `y & 0`"
|
"using erasing operations, e.g. `x * 0` or `y & 0`"
|
||||||
|
|
|
@ -14,24 +14,24 @@ pub struct Pass {
|
||||||
pub too_large_for_stack: u64,
|
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! {
|
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,
|
pub BOXED_LOCAL,
|
||||||
perf,
|
perf,
|
||||||
"using `Box<T>` where unnecessary"
|
"using `Box<T>` where unnecessary"
|
||||||
|
|
|
@ -8,26 +8,26 @@ use rustc_errors::Applicability;
|
||||||
|
|
||||||
pub struct EtaPass;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// xs.map(|x| foo(x))
|
||||||
|
/// ```
|
||||||
|
/// where `foo(_)` is a plain function that takes the exact argument type of
|
||||||
|
/// `x`.
|
||||||
pub REDUNDANT_CLOSURE,
|
pub REDUNDANT_CLOSURE,
|
||||||
style,
|
style,
|
||||||
"redundant closures, i.e. `|a| foo(a)` (which can be written as just `foo`)"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast;
|
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! {
|
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,
|
pub EVAL_ORDER_DEPENDENCE,
|
||||||
complexity,
|
complexity,
|
||||||
"whether a variable read occurs before a write depends on sub-expression evaluation order"
|
"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! {
|
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,
|
pub DIVERGING_SUB_EXPRESSION,
|
||||||
complexity,
|
complexity,
|
||||||
"whether an expression contains a diverging sub expression"
|
"whether an expression contains a diverging sub expression"
|
||||||
|
|
|
@ -11,25 +11,25 @@ use std::fmt;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax_pos::symbol::Symbol;
|
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! {
|
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,
|
pub EXCESSIVE_PRECISION,
|
||||||
style,
|
style,
|
||||||
"excessive precision for float literal"
|
"excessive precision for float literal"
|
||||||
|
|
|
@ -6,19 +6,19 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use syntax::ast::LitKind;
|
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! {
|
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,
|
pub EXPLICIT_WRITE,
|
||||||
complexity,
|
complexity,
|
||||||
"using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax_pos::Span;
|
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! {
|
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,
|
pub FALLIBLE_IMPL_FROM,
|
||||||
nursery,
|
nursery,
|
||||||
"Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`"
|
"Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`"
|
||||||
|
|
|
@ -12,23 +12,23 @@ use rustc_errors::Applicability;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub USELESS_FORMAT,
|
||||||
complexity,
|
complexity,
|
||||||
"useless use of `format!`"
|
"useless use of `format!`"
|
||||||
|
|
|
@ -4,75 +4,75 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ptr::P;
|
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! {
|
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,
|
pub SUSPICIOUS_ASSIGNMENT_FORMATTING,
|
||||||
style,
|
style,
|
||||||
"suspicious formatting of `*=`, `-=` or `!=`"
|
"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! {
|
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,
|
pub SUSPICIOUS_ELSE_FORMATTING,
|
||||||
style,
|
style,
|
||||||
"suspicious formatting of `else`"
|
"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! {
|
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,
|
pub POSSIBLE_MISSING_COMMA,
|
||||||
correctness,
|
correctness,
|
||||||
"possible missing comma in array"
|
"possible missing comma in array"
|
||||||
|
|
|
@ -11,72 +11,72 @@ use rustc_target::spec::abi::Abi;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub TOO_MANY_ARGUMENTS,
|
||||||
complexity,
|
complexity,
|
||||||
"functions with too many arguments"
|
"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! {
|
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,
|
pub TOO_MANY_LINES,
|
||||||
pedantic,
|
pedantic,
|
||||||
"functions with too many lines"
|
"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! {
|
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,
|
pub NOT_UNSAFE_PTR_ARG_DEREF,
|
||||||
correctness,
|
correctness,
|
||||||
"public functions dereferencing raw pointer arguments but not marked `unsafe`"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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,
|
pub IDENTITY_CONVERSION,
|
||||||
complexity,
|
complexity,
|
||||||
"using always-identical `Into`/`From`/`IntoIter` conversions"
|
"using always-identical `Into`/`From`/`IntoIter` conversions"
|
||||||
|
|
|
@ -6,18 +6,18 @@ use rustc::ty;
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub IDENTITY_OP,
|
||||||
complexity,
|
complexity,
|
||||||
"using identity operations, e.g. `x + 0` or `y / 1`"
|
"using identity operations, e.g. `x + 0` or `y / 1`"
|
||||||
|
|
|
@ -7,32 +7,32 @@ use syntax::ast::*;
|
||||||
|
|
||||||
use crate::utils::span_help_and_lint;
|
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! {
|
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,
|
pub IF_NOT_ELSE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`if` branches that could be swapped so no negation operation is necessary on the condition"
|
"`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 rustc_errors::Applicability;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub IMPLICIT_RETURN,
|
||||||
restriction,
|
restriction,
|
||||||
"use a return statement like `return expr` instead of an expression"
|
"use a return statement like `return expr` instead of an expression"
|
||||||
|
|
|
@ -10,75 +10,75 @@ use rustc::ty;
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast::RangeLimits;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let x = [1, 2, 3, 4];
|
||||||
|
///
|
||||||
|
/// // Bad
|
||||||
|
/// x[9];
|
||||||
|
/// &x[2..9];
|
||||||
|
///
|
||||||
|
/// // Good
|
||||||
|
/// x[0];
|
||||||
|
/// x[3];
|
||||||
|
/// ```
|
||||||
pub OUT_OF_BOUNDS_INDEXING,
|
pub OUT_OF_BOUNDS_INDEXING,
|
||||||
correctness,
|
correctness,
|
||||||
"out of bounds constant indexing"
|
"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! {
|
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,
|
pub INDEXING_SLICING,
|
||||||
restriction,
|
restriction,
|
||||||
"indexing/slicing usage"
|
"indexing/slicing usage"
|
||||||
|
|
|
@ -5,36 +5,36 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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,
|
pub INFALLIBLE_DESTRUCTURING_MATCH,
|
||||||
style,
|
style,
|
||||||
"a match statement with a single infallible arm instead of a `let`"
|
"a match statement with a single infallible arm instead of a `let`"
|
||||||
|
|
|
@ -3,36 +3,36 @@ use rustc::hir::*;
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// repeat(1_u8).iter().collect::<Vec<_>>()
|
||||||
|
/// ```
|
||||||
pub INFINITE_ITER,
|
pub INFINITE_ITER,
|
||||||
correctness,
|
correctness,
|
||||||
"infinite iteration"
|
"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! {
|
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,
|
pub MAYBE_INFINITE_ITER,
|
||||||
pedantic,
|
pedantic,
|
||||||
"possible infinite iteration"
|
"possible infinite iteration"
|
||||||
|
|
|
@ -8,33 +8,33 @@ use rustc_data_structures::fx::FxHashMap;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use syntax_pos::Span;
|
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! {
|
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,
|
pub MULTIPLE_INHERENT_IMPL,
|
||||||
restriction,
|
restriction,
|
||||||
"Multiple inherent impl that could be grouped"
|
"Multiple inherent impl that could be grouped"
|
||||||
|
|
|
@ -8,21 +8,21 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use syntax::ast::{Attribute, Name};
|
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! {
|
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,
|
pub INLINE_FN_WITHOUT_BODY,
|
||||||
correctness,
|
correctness,
|
||||||
"use of `#[inline]` on trait methods without bodies"
|
"use of `#[inline]` on trait methods without bodies"
|
||||||
|
|
|
@ -7,24 +7,24 @@ use syntax::ast::*;
|
||||||
|
|
||||||
use crate::utils::{snippet_opt, span_lint_and_then};
|
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! {
|
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,
|
pub INT_PLUS_ONE,
|
||||||
complexity,
|
complexity,
|
||||||
"instead of using x >= y + 1, use x > y"
|
"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::ty;
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let bad_ref: &usize = std::mem::zeroed();
|
||||||
|
/// ```
|
||||||
pub INVALID_REF,
|
pub INVALID_REF,
|
||||||
correctness,
|
correctness,
|
||||||
"creation of invalid reference"
|
"creation of invalid reference"
|
||||||
|
|
|
@ -6,29 +6,29 @@ use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast::*;
|
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! {
|
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,
|
pub ITEMS_AFTER_STATEMENTS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"blocks where an item comes after a statement"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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,
|
pub LARGE_ENUM_VARIANT,
|
||||||
perf,
|
perf,
|
||||||
"large size difference between variants on an enum"
|
"large size difference between variants on an enum"
|
||||||
|
|
|
@ -9,62 +9,61 @@ use rustc_errors::Applicability;
|
||||||
use syntax::ast::{Lit, LitKind, Name};
|
use syntax::ast::{Lit, LitKind, Name};
|
||||||
use syntax::source_map::{Span, Spanned};
|
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! {
|
declare_clippy_lint! {
|
||||||
pub LEN_ZERO,
|
/// **What it does:** Checks for getting the length of something via `.len()`
|
||||||
style,
|
/// just to compare to zero, and suggests using `.is_empty()` where applicable.
|
||||||
"checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` \
|
///
|
||||||
could be used instead"
|
/// **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() {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// impl X {
|
||||||
|
/// pub fn len(&self) -> usize {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub LEN_WITHOUT_IS_EMPTY,
|
pub LEN_WITHOUT_IS_EMPTY,
|
||||||
style,
|
style,
|
||||||
"traits or impls with a public `len` method but no corresponding `is_empty` method"
|
"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 rustc_errors::Applicability;
|
||||||
use syntax::ast;
|
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! {
|
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,
|
pub USELESS_LET_IF_SEQ,
|
||||||
style,
|
style,
|
||||||
"unidiomatic `let mut` declaration followed by initialization in `if`"
|
"unidiomatic `let mut` declaration followed by initialization in `if`"
|
||||||
|
|
|
@ -39,7 +39,7 @@ use toml;
|
||||||
///
|
///
|
||||||
/// Every lint declaration consists of 4 parts:
|
/// 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.
|
/// 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
|
/// 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.
|
/// `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
|
||||||
|
@ -60,22 +60,22 @@ use toml;
|
||||||
/// # use clippy_lints::declare_clippy_lint;
|
/// # use clippy_lints::declare_clippy_lint;
|
||||||
/// use rustc::declare_tool_lint;
|
/// use rustc::declare_tool_lint;
|
||||||
///
|
///
|
||||||
/// /// **What it does:** Checks for ... (describe what the lint matches).
|
|
||||||
/// ///
|
|
||||||
/// /// **Why is this bad?** Supply the reason for linting the code.
|
|
||||||
/// ///
|
|
||||||
/// /// **Known problems:** None. (Or describe where it could go wrong.)
|
|
||||||
/// ///
|
|
||||||
/// /// **Example:**
|
|
||||||
/// ///
|
|
||||||
/// /// ```rust
|
|
||||||
/// /// // Bad
|
|
||||||
/// /// Insert a short example of code that triggers the lint
|
|
||||||
/// ///
|
|
||||||
/// /// // Good
|
|
||||||
/// /// Insert a short example of improved code that doesn't trigger the lint
|
|
||||||
/// /// ```
|
|
||||||
/// declare_clippy_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.
|
||||||
|
/// ///
|
||||||
|
/// /// **Known problems:** None. (Or describe where it could go wrong.)
|
||||||
|
/// ///
|
||||||
|
/// /// **Example:**
|
||||||
|
/// ///
|
||||||
|
/// /// ```rust
|
||||||
|
/// /// // Bad
|
||||||
|
/// /// Insert a short example of code that triggers the lint
|
||||||
|
/// ///
|
||||||
|
/// /// // Good
|
||||||
|
/// /// Insert a short example of improved code that doesn't trigger the lint
|
||||||
|
/// /// ```
|
||||||
/// pub LINT_NAME,
|
/// pub LINT_NAME,
|
||||||
/// pedantic,
|
/// pedantic,
|
||||||
/// "description"
|
/// "description"
|
||||||
|
@ -84,35 +84,55 @@ use toml;
|
||||||
/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
|
/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! declare_clippy_lint {
|
macro_rules! declare_clippy_lint {
|
||||||
{ pub $name:tt, style, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, style, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
$(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, correctness, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, correctness, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Deny, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
$(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, complexity, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, perf, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, perf, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Warn, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, pedantic, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, pedantic, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, restriction, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, restriction, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, cargo, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, cargo, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, nursery, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, nursery, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, internal, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, internal, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
declare_tool_lint! {
|
||||||
|
pub clippy::$name, Allow, $description, report_in_external_macro: true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
{ pub $name:tt, internal_warn, $description:tt } => {
|
{ $(#[$attr:meta])* pub $name:tt, internal_warn, $description:tt } => {
|
||||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
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::source_map::Span;
|
||||||
use syntax::symbol::keywords;
|
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! {
|
declare_clippy_lint! {
|
||||||
pub NEEDLESS_LIFETIMES,
|
/// **What it does:** Checks for lifetime annotations which can be removed by
|
||||||
complexity,
|
/// relying on lifetime elision.
|
||||||
"using explicit lifetimes for references in function arguments when elision rules \
|
///
|
||||||
would allow omitting them"
|
/// **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! {
|
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,
|
pub EXTRA_UNUSED_LIFETIMES,
|
||||||
complexity,
|
complexity,
|
||||||
"unused lifetimes in function definitions"
|
"unused lifetimes in function definitions"
|
||||||
|
|
|
@ -9,95 +9,95 @@ use rustc_errors::Applicability;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax_pos;
|
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! {
|
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
|
||||||
|
/// 61864918973511
|
||||||
|
/// ```
|
||||||
pub UNREADABLE_LITERAL,
|
pub UNREADABLE_LITERAL,
|
||||||
style,
|
style,
|
||||||
"long integer literal without underscores"
|
"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! {
|
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,
|
pub MISTYPED_LITERAL_SUFFIXES,
|
||||||
correctness,
|
correctness,
|
||||||
"mistyped literal suffix"
|
"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! {
|
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
|
||||||
|
/// 618_64_9189_73_511
|
||||||
|
/// ```
|
||||||
pub INCONSISTENT_DIGIT_GROUPING,
|
pub INCONSISTENT_DIGIT_GROUPING,
|
||||||
style,
|
style,
|
||||||
"integer literals with digits grouped inconsistently"
|
"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! {
|
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
|
||||||
|
/// 6186491_8973511
|
||||||
|
/// ```
|
||||||
pub LARGE_DIGIT_GROUPS,
|
pub LARGE_DIGIT_GROUPS,
|
||||||
pedantic,
|
pedantic,
|
||||||
"grouping digits into groups that are too large"
|
"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! {
|
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,
|
pub DECIMAL_LITERAL_REPRESENTATION,
|
||||||
restriction,
|
restriction,
|
||||||
"using decimal representation when hexadecimal would be better"
|
"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,
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for i in 0..src.len() {
|
||||||
|
/// dst[i + 64] = src[i];
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub MANUAL_MEMCPY,
|
pub MANUAL_MEMCPY,
|
||||||
perf,
|
perf,
|
||||||
"manually copying items between slices"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for i in 0..vec.len() {
|
||||||
|
/// println!("{}", vec[i]);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub NEEDLESS_RANGE_LOOP,
|
pub NEEDLESS_RANGE_LOOP,
|
||||||
style,
|
style,
|
||||||
"for-looping over a range of indices where an iterator over items would do"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// // with `y` a `Vec` or slice:
|
||||||
|
/// for x in y.iter() {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// can be rewritten to
|
||||||
|
/// ```rust
|
||||||
|
/// for x in &y {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub EXPLICIT_ITER_LOOP,
|
pub EXPLICIT_ITER_LOOP,
|
||||||
pedantic,
|
pedantic,
|
||||||
"for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// // with `y` a `Vec` or slice:
|
||||||
|
/// for x in y.into_iter() {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// can be rewritten to
|
||||||
|
/// ```rust
|
||||||
|
/// for x in y {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub EXPLICIT_INTO_ITER_LOOP,
|
pub EXPLICIT_INTO_ITER_LOOP,
|
||||||
pedantic,
|
pedantic,
|
||||||
"for-looping over `_.into_iter()` when `_` would do"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for x in y.next() {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub ITER_NEXT_LOOP,
|
pub ITER_NEXT_LOOP,
|
||||||
correctness,
|
correctness,
|
||||||
"for-looping over `_.next()` which is probably not intended"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for x in option {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This should be
|
||||||
|
/// ```rust
|
||||||
|
/// if let Some(x) = option {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub FOR_LOOP_OVER_OPTION,
|
pub FOR_LOOP_OVER_OPTION,
|
||||||
correctness,
|
correctness,
|
||||||
"for-looping over an `Option`, which is more clearly expressed as an `if let`"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for x in result {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This should be
|
||||||
|
/// ```rust
|
||||||
|
/// if let Ok(x) = result {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub FOR_LOOP_OVER_RESULT,
|
pub FOR_LOOP_OVER_RESULT,
|
||||||
correctness,
|
correctness,
|
||||||
"for-looping over a `Result`, which is more clearly expressed as an `if let`"
|
"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! {
|
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,
|
pub WHILE_LET_LOOP,
|
||||||
complexity,
|
complexity,
|
||||||
"`loop { if let { ... } else break }`, which can be written as a `while let` loop"
|
"`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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// vec.iter().map(|x| /* some operation returning () */).collect::<Vec<_>>();
|
||||||
|
/// ```
|
||||||
pub UNUSED_COLLECT,
|
pub UNUSED_COLLECT,
|
||||||
perf,
|
perf,
|
||||||
"`collect()`ing an iterator without using the result; this is usually better written as a for loop"
|
"`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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let len = iterator.collect::<Vec<_>>().len();
|
||||||
|
/// // should be
|
||||||
|
/// let len = iterator.count();
|
||||||
|
/// ```
|
||||||
pub NEEDLESS_COLLECT,
|
pub NEEDLESS_COLLECT,
|
||||||
perf,
|
perf,
|
||||||
"collecting an iterator when collect is not needed"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for x in 5..10 - 5 {
|
||||||
|
/// ..
|
||||||
|
/// } // oops, stray `-`
|
||||||
|
/// ```
|
||||||
pub REVERSE_RANGE_LOOP,
|
pub REVERSE_RANGE_LOOP,
|
||||||
correctness,
|
correctness,
|
||||||
"iteration over an empty range, such as `10..0` or `5..5`"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for i in 0..v.len() { foo(v[i]);
|
||||||
|
/// for i in 0..v.len() { bar(i, v[i]); }
|
||||||
|
/// ```
|
||||||
pub EXPLICIT_COUNTER_LOOP,
|
pub EXPLICIT_COUNTER_LOOP,
|
||||||
complexity,
|
complexity,
|
||||||
"for-looping with an explicit counter when `_.enumerate()` would do"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// loop {}
|
||||||
|
/// ```
|
||||||
pub EMPTY_LOOP,
|
pub EMPTY_LOOP,
|
||||||
style,
|
style,
|
||||||
"empty `loop {}`, which should block or sleep"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// while let Some(val) = iter() {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub WHILE_LET_ON_ITERATOR,
|
pub WHILE_LET_ON_ITERATOR,
|
||||||
style,
|
style,
|
||||||
"using a while-let loop instead of a for loop on an iterator"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// for (k, _) in &map {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// could be replaced by
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// for k in map.keys() {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub FOR_KV_MAP,
|
pub FOR_KV_MAP,
|
||||||
style,
|
style,
|
||||||
"looping on a map using `iter` when `keys` or `values` would do"
|
"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! {
|
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,
|
pub NEVER_LOOP,
|
||||||
correctness,
|
correctness,
|
||||||
"any loop that will always `break` or `return`"
|
"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! {
|
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,
|
pub MUT_RANGE_BOUND,
|
||||||
complexity,
|
complexity,
|
||||||
"for loop over a range where one of the bounds is a mutable variable"
|
"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! {
|
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,
|
pub WHILE_IMMUTABLE_CONDITION,
|
||||||
correctness,
|
correctness,
|
||||||
"variables used within while expression are not mutated in the body"
|
"variables used within while expression are not mutated in the body"
|
||||||
|
|
|
@ -14,29 +14,29 @@ use syntax::source_map::Span;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Pass;
|
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! {
|
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,
|
pub MAP_CLONE,
|
||||||
style,
|
style,
|
||||||
"using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types"
|
"using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types"
|
||||||
|
|
|
@ -11,67 +11,67 @@ use syntax::source_map::Span;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Pass;
|
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! {
|
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,
|
pub OPTION_MAP_UNIT_FN,
|
||||||
complexity,
|
complexity,
|
||||||
"using `option.map(f)`, where f is a function or closure that returns ()"
|
"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! {
|
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,
|
pub RESULT_MAP_UNIT_FN,
|
||||||
complexity,
|
complexity,
|
||||||
"using `result.map(f)`, where f is a function or closure that returns ()"
|
"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::ast::LitKind;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// match x {
|
||||||
|
/// Some(ref foo) => bar(foo),
|
||||||
|
/// _ => (),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub SINGLE_MATCH,
|
pub SINGLE_MATCH,
|
||||||
style,
|
style,
|
||||||
"a match statement with a single nontrivial arm (i.e. where the other arm is `_ => {}`) instead of `if let`"
|
"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! {
|
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`:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// if let Some(ref foo) = x {
|
||||||
|
/// bar(foo);
|
||||||
|
/// } else {
|
||||||
|
/// bar(other_ref);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub SINGLE_MATCH_ELSE,
|
pub SINGLE_MATCH_ELSE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"a match statement with a two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// match x {
|
||||||
|
/// &A(ref y) => foo(y),
|
||||||
|
/// &B => bar(),
|
||||||
|
/// _ => frob(&x),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub MATCH_REF_PATS,
|
pub MATCH_REF_PATS,
|
||||||
style,
|
style,
|
||||||
"a match or `if let` with all arms prefixed with `&` instead of deref-ing the match expression"
|
"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! {
|
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:**
|
||||||
|
/// ```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();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub MATCH_BOOL,
|
pub MATCH_BOOL,
|
||||||
style,
|
style,
|
||||||
"a match on a boolean expression instead of an `if..else` block"
|
"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! {
|
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,
|
pub MATCH_OVERLAPPING_ARM,
|
||||||
style,
|
style,
|
||||||
"a match with overlapping arms"
|
"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! {
|
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,
|
pub MATCH_WILD_ERR_ARM,
|
||||||
style,
|
style,
|
||||||
"a match with `Err(_)` arm and take drastic actions"
|
"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! {
|
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,
|
pub MATCH_AS_REF,
|
||||||
complexity,
|
complexity,
|
||||||
"a match on an Option value instead of using `as_ref()` or `as_mut`"
|
"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! {
|
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,
|
pub WILDCARD_ENUM_MATCH_ARM,
|
||||||
restriction,
|
restriction,
|
||||||
"a wildcard enum match arm using `_`"
|
"a wildcard enum match arm using `_`"
|
||||||
|
|
|
@ -7,19 +7,19 @@ use rustc_errors::Applicability;
|
||||||
|
|
||||||
use std::iter;
|
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! {
|
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
|
||||||
|
/// mem::discriminant(&"hello");
|
||||||
|
/// mem::discriminant(&&Some(2));
|
||||||
|
/// ```
|
||||||
pub MEM_DISCRIMINANT_NON_ENUM,
|
pub MEM_DISCRIMINANT_NON_ENUM,
|
||||||
correctness,
|
correctness,
|
||||||
"calling mem::descriminant on non-enum type"
|
"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::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub MEM_FORGET,
|
||||||
restriction,
|
restriction,
|
||||||
"`mem::forget` usage on `Drop` types, likely to cause memory leaks"
|
"`mem::forget` usage on `Drop` types, likely to cause memory leaks"
|
||||||
|
|
|
@ -5,26 +5,26 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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
|
||||||
|
/// 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,
|
pub MEM_REPLACE_OPTION_WITH_NONE,
|
||||||
style,
|
style,
|
||||||
"replacing an `Option` with `None` instead of `take()`"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use std::cmp::Ordering;
|
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! {
|
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:**
|
||||||
|
/// ```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`.
|
||||||
pub MIN_MAX,
|
pub MIN_MAX,
|
||||||
correctness,
|
correctness,
|
||||||
"`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant"
|
"`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::ast::LitKind;
|
||||||
use syntax::source_map::{ExpnFormat, Span};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// fn foo(ref x: u8) -> bool {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub TOPLEVEL_REF_ARG,
|
pub TOPLEVEL_REF_ARG,
|
||||||
style,
|
style,
|
||||||
"an entire binding declared as `ref`, in a function argument or a `let` statement"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// x == NAN
|
||||||
|
/// ```
|
||||||
pub CMP_NAN,
|
pub CMP_NAN,
|
||||||
correctness,
|
correctness,
|
||||||
"comparisons to NAN, which will always return false, probably not intended"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// y == 1.23f64
|
||||||
|
/// y != x // where both are floats
|
||||||
|
/// ```
|
||||||
pub FLOAT_CMP,
|
pub FLOAT_CMP,
|
||||||
correctness,
|
correctness,
|
||||||
"using `==` or `!=` on float values instead of comparing difference with an epsilon"
|
"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! {
|
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,
|
pub CMP_OWNED,
|
||||||
perf,
|
perf,
|
||||||
"creating owned instances for comparing with others, e.g. `x == \"foo\".to_string()`"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// x % 1
|
||||||
|
/// ```
|
||||||
pub MODULO_ONE,
|
pub MODULO_ONE,
|
||||||
correctness,
|
correctness,
|
||||||
"taking a number modulo 1, which always returns 0"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// match v {
|
||||||
|
/// Some(x) => (),
|
||||||
|
/// y @ _ => (), // easier written as `y`,
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub REDUNDANT_PATTERN,
|
pub REDUNDANT_PATTERN,
|
||||||
style,
|
style,
|
||||||
"using `name @ _` in a pattern"
|
"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! {
|
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,
|
pub USED_UNDERSCORE_BINDING,
|
||||||
pedantic,
|
pedantic,
|
||||||
"using a binding which is prefixed with an underscore"
|
"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! {
|
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,
|
pub SHORT_CIRCUIT_STATEMENT,
|
||||||
complexity,
|
complexity,
|
||||||
"using a short circuit boolean condition as a statement"
|
"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! {
|
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:**
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// 0 as *const u32
|
||||||
|
/// ```
|
||||||
pub ZERO_PTR,
|
pub ZERO_PTR,
|
||||||
style,
|
style,
|
||||||
"using 0 as *{const, mut} T"
|
"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! {
|
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,
|
pub FLOAT_CMP_CONST,
|
||||||
restriction,
|
restriction,
|
||||||
"using `==` or `!=` on float constants instead of comparing difference with an epsilon"
|
"using `==` or `!=` on float constants instead of comparing difference with an epsilon"
|
||||||
|
|
|
@ -9,163 +9,163 @@ use syntax::ast::*;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
use syntax::visit::{walk_expr, FnKind, Visitor};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let { a: _, b: ref b, c: _ } = ..
|
||||||
|
/// ```
|
||||||
pub UNNEEDED_FIELD_PATTERN,
|
pub UNNEEDED_FIELD_PATTERN,
|
||||||
style,
|
style,
|
||||||
"struct fields bound to a wildcard instead of using `..`"
|
"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! {
|
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,
|
pub DUPLICATE_UNDERSCORE_ARGUMENT,
|
||||||
style,
|
style,
|
||||||
"function arguments having names which only differ by an underscore"
|
"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! {
|
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,
|
pub REDUNDANT_CLOSURE_CALL,
|
||||||
complexity,
|
complexity,
|
||||||
"throwaway closures called in the expression they are defined"
|
"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! {
|
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
|
||||||
|
/// --x;
|
||||||
|
/// ```
|
||||||
pub DOUBLE_NEG,
|
pub DOUBLE_NEG,
|
||||||
style,
|
style,
|
||||||
"`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++"
|
"`--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! {
|
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,
|
pub MIXED_CASE_HEX_LITERALS,
|
||||||
style,
|
style,
|
||||||
"hex literals whose letter digits are not consistently upper- or lowercased"
|
"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! {
|
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,
|
pub UNSEPARATED_LITERAL_SUFFIX,
|
||||||
pedantic,
|
pedantic,
|
||||||
"literals whose suffix is not separated by an underscore"
|
"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! {
|
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,
|
pub ZERO_PREFIXED_LITERAL,
|
||||||
complexity,
|
complexity,
|
||||||
"integer literals starting with `0`"
|
"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! {
|
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:**
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// impl<u32> Foo<u32> {
|
||||||
|
/// fn impl_func(&self) -> u32 {
|
||||||
|
/// 42
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub BUILTIN_TYPE_SHADOW,
|
pub BUILTIN_TYPE_SHADOW,
|
||||||
style,
|
style,
|
||||||
"shadowing a builtin type"
|
"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 rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
|
||||||
use syntax_pos::Span;
|
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! {
|
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,
|
pub MISSING_CONST_FOR_FN,
|
||||||
nursery,
|
nursery,
|
||||||
"Lint functions definitions that could be made `const fn`"
|
"Lint functions definitions that could be made `const fn`"
|
||||||
|
|
|
@ -14,16 +14,16 @@ use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub MISSING_DOCS_IN_PRIVATE_ITEMS,
|
||||||
restriction,
|
restriction,
|
||||||
"detects missing documentation for public and private members"
|
"detects missing documentation for public and private members"
|
||||||
|
|
|
@ -5,52 +5,52 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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,
|
pub MISSING_INLINE_IN_PUBLIC_ITEMS,
|
||||||
restriction,
|
restriction,
|
||||||
"detects missing #[inline] attribute for public callables (functions, trait methods, methods...)"
|
"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 cargo_metadata;
|
||||||
use itertools::Itertools;
|
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! {
|
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,
|
pub MULTIPLE_CRATE_VERSIONS,
|
||||||
cargo,
|
cargo,
|
||||||
"multiple versions of the same crate being used"
|
"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::ty;
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub MUT_MUT,
|
||||||
pedantic,
|
pedantic,
|
||||||
"usage of double-mut refs, e.g. `&mut &mut ...`"
|
"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::ty::{self, Ty};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// my_vec.push(&mut value)
|
||||||
|
/// ```
|
||||||
pub UNNECESSARY_MUT_PASSED,
|
pub UNNECESSARY_MUT_PASSED,
|
||||||
style,
|
style,
|
||||||
"an argument passed as a mutable reference although the callee only demands an immutable reference"
|
"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 rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast;
|
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! {
|
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,
|
pub MUTEX_ATOMIC,
|
||||||
perf,
|
perf,
|
||||||
"using a mutex where an atomic value could be used instead"
|
"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! {
|
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,
|
pub MUTEX_INTEGER,
|
||||||
nursery,
|
nursery,
|
||||||
"using a mutex for an integer type"
|
"using a mutex for an integer type"
|
||||||
|
|
|
@ -11,44 +11,44 @@ use rustc_errors::Applicability;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::source_map::Spanned;
|
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! {
|
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,
|
pub NEEDLESS_BOOL,
|
||||||
complexity,
|
complexity,
|
||||||
"if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`"
|
"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! {
|
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,
|
pub BOOL_COMPARISON,
|
||||||
complexity,
|
complexity,
|
||||||
"comparing a variable to a boolean, e.g. `if x == true` or `if x != true`"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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,
|
pub NEEDLESS_BORROW,
|
||||||
nursery,
|
nursery,
|
||||||
"taking a reference that is going to be automatically dereferenced"
|
"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::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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,
|
pub NEEDLESS_BORROWED_REFERENCE,
|
||||||
complexity,
|
complexity,
|
||||||
"taking a needless borrowed reference"
|
"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};
|
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! {
|
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,
|
pub NEEDLESS_CONTINUE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"`continue` statements that can be replaced by a rearrangement of code"
|
"`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::errors::DiagnosticBuilder;
|
||||||
use syntax_pos::Span;
|
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! {
|
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,
|
pub NEEDLESS_PASS_BY_VALUE,
|
||||||
pedantic,
|
pedantic,
|
||||||
"functions taking arguments by value, but not consuming them in its body"
|
"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::ty;
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub NEEDLESS_UPDATE,
|
||||||
complexity,
|
complexity,
|
||||||
"using `Foo { ..base }` when there are no missing fields"
|
"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};
|
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! {
|
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,
|
pub NEG_CMP_OP_ON_PARTIAL_ORD,
|
||||||
complexity,
|
complexity,
|
||||||
"The use of negated comparison operators on partially ordered types may produce confusing code."
|
"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::consts::{self, Constant};
|
||||||
use crate::utils::span_lint;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// x * -1
|
||||||
|
/// ```
|
||||||
pub NEG_MULTIPLY,
|
pub NEG_MULTIPLY,
|
||||||
style,
|
style,
|
||||||
"multiplying integers with -1"
|
"multiplying integers with -1"
|
||||||
|
|
|
@ -11,74 +11,74 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use syntax::source_map::Span;
|
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! {
|
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:**
|
||||||
|
///
|
||||||
|
/// ```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()`.
|
||||||
pub NEW_WITHOUT_DEFAULT,
|
pub NEW_WITHOUT_DEFAULT,
|
||||||
style,
|
style,
|
||||||
"`fn new() -> Self` method without `Default` implementation"
|
"`fn new() -> Self` method without `Default` implementation"
|
||||||
|
|
|
@ -6,37 +6,37 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use std::ops::Deref;
|
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! {
|
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,
|
pub NO_EFFECT,
|
||||||
complexity,
|
complexity,
|
||||||
"statements with no effect"
|
"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! {
|
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,
|
pub UNNECESSARY_OPERATION,
|
||||||
complexity,
|
complexity,
|
||||||
"outer expressions with no effect"
|
"outer expressions with no effect"
|
||||||
|
|
|
@ -14,69 +14,69 @@ use rustc_typeck::hir_ty_to_ty;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
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! {
|
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,
|
pub DECLARE_INTERIOR_MUTABLE_CONST,
|
||||||
correctness,
|
correctness,
|
||||||
"declaring const with interior mutability"
|
"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! {
|
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,
|
pub BORROW_INTERIOR_MUTABLE_CONST,
|
||||||
correctness,
|
correctness,
|
||||||
"referencing const with interior mutability"
|
"referencing const with interior mutability"
|
||||||
|
|
|
@ -7,57 +7,57 @@ use syntax::source_map::Span;
|
||||||
use syntax::symbol::LocalInternedString;
|
use syntax::symbol::LocalInternedString;
|
||||||
use syntax::visit::{walk_block, walk_expr, walk_pat, Visitor};
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let checked_exp = something;
|
||||||
|
/// let checked_expr = something_else;
|
||||||
|
/// ```
|
||||||
pub SIMILAR_NAMES,
|
pub SIMILAR_NAMES,
|
||||||
pedantic,
|
pedantic,
|
||||||
"similarly named items and bindings"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// let (a, b, c, d, e, f, g) = (...);
|
||||||
|
/// ```
|
||||||
pub MANY_SINGLE_CHAR_NAMES,
|
pub MANY_SINGLE_CHAR_NAMES,
|
||||||
style,
|
style,
|
||||||
"too many single character bindings"
|
"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! {
|
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,
|
pub JUST_UNDERSCORES_AND_DIGITS,
|
||||||
style,
|
style,
|
||||||
"unclear name"
|
"unclear name"
|
||||||
|
|
|
@ -4,31 +4,31 @@ use rustc::hir::*;
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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:**
|
||||||
|
/// ```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)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub IF_LET_SOME_RESULT,
|
pub IF_LET_SOME_RESULT,
|
||||||
style,
|
style,
|
||||||
"usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead"
|
"usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead"
|
||||||
|
|
|
@ -5,19 +5,19 @@ use rustc::{declare_tool_lint, lint_array};
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::source_map::{Span, Spanned};
|
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! {
|
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
|
||||||
|
/// OpenOptions::new().read(true).truncate(true)
|
||||||
|
/// ```
|
||||||
pub NONSENSICAL_OPEN_OPTIONS,
|
pub NONSENSICAL_OPEN_OPTIONS,
|
||||||
correctness,
|
correctness,
|
||||||
"nonsensical combination of options for opening a file"
|
"nonsensical combination of options for opening a file"
|
||||||
|
|
|
@ -4,18 +4,18 @@ use rustc::hir::*;
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub OVERFLOW_CHECK_CONDITIONAL,
|
||||||
complexity,
|
complexity,
|
||||||
"overflow checks inspired by C which are likely to panic"
|
"overflow checks inspired by C which are likely to panic"
|
||||||
|
|
|
@ -7,36 +7,36 @@ use syntax::ast::LitKind;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax_pos::Span;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// panic!("This `panic!` is probably missing a parameter there: {}");
|
||||||
|
/// ```
|
||||||
pub PANIC_PARAMS,
|
pub PANIC_PARAMS,
|
||||||
style,
|
style,
|
||||||
"missing parameters in `panic!` calls"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// unimplemented!();
|
||||||
|
/// ```
|
||||||
pub UNIMPLEMENTED,
|
pub UNIMPLEMENTED,
|
||||||
restriction,
|
restriction,
|
||||||
"`unimplemented!` should not be present in production code"
|
"`unimplemented!` should not be present in production code"
|
||||||
|
|
|
@ -4,25 +4,25 @@ use rustc::hir::*;
|
||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::{declare_tool_lint, lint_array};
|
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! {
|
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,
|
pub PARTIALEQ_NE_IMPL,
|
||||||
complexity,
|
complexity,
|
||||||
"re-implementing `PartialEq::ne`"
|
"re-implementing `PartialEq::ne`"
|
||||||
|
|
|
@ -5,24 +5,24 @@ use rustc_errors::Applicability;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::source_map::Spanned;
|
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! {
|
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,
|
pub PRECEDENCE,
|
||||||
complexity,
|
complexity,
|
||||||
"operations where precedence may be unclear"
|
"operations where precedence may be unclear"
|
||||||
|
|
|
@ -13,82 +13,82 @@ use std::borrow::Cow;
|
||||||
use syntax::source_map::Span;
|
use syntax::source_map::Span;
|
||||||
use syntax_pos::MultiSpan;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// fn foo(&Vec<u32>) { .. }
|
||||||
|
/// ```
|
||||||
pub PTR_ARG,
|
pub PTR_ARG,
|
||||||
style,
|
style,
|
||||||
"fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively"
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if x == ptr::null {
|
||||||
|
/// ..
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub CMP_NULL,
|
pub CMP_NULL,
|
||||||
style,
|
style,
|
||||||
"comparing a pointer to a null pointer, suggesting to use `.is_null()` instead."
|
"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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// fn foo(&Foo) -> &mut Bar { .. }
|
||||||
|
/// ```
|
||||||
pub MUT_FROM_REF,
|
pub MUT_FROM_REF,
|
||||||
correctness,
|
correctness,
|
||||||
"fns that create mutable refs from immutable ref args"
|
"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 rustc_errors::Applicability;
|
||||||
use std::fmt;
|
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! {
|
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,
|
pub PTR_OFFSET_WITH_CAST,
|
||||||
complexity,
|
complexity,
|
||||||
"unneeded pointer offset cast"
|
"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 crate::utils::{match_def_path, match_type, span_lint_and_then, SpanlessEq};
|
||||||
use rustc_errors::Applicability;
|
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! {
|
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:**
|
||||||
|
/// ```rust
|
||||||
|
/// if option.is_none() {
|
||||||
|
/// return None;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Could be written:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// option?;
|
||||||
|
/// ```
|
||||||
pub QUESTION_MARK,
|
pub QUESTION_MARK,
|
||||||
style,
|
style,
|
||||||
"checks for expressions that could be replaced by the question mark operator"
|
"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…
Add table
Add a link
Reference in a new issue