mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Improve docs
This commit is contained in:
parent
26fdd3f2b7
commit
caa76e119b
@ -10,7 +10,10 @@ use utils::span_lint;
|
||||
///
|
||||
/// **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:** `let x = 3.14;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = 3.14;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub APPROX_CONSTANT,
|
||||
Warn,
|
||||
|
@ -12,7 +12,7 @@ use utils::span_lint;
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// a + 1
|
||||
/// ```
|
||||
declare_restriction_lint! {
|
||||
@ -28,7 +28,7 @@ declare_restriction_lint! {
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// a + 1.0
|
||||
/// ```
|
||||
declare_restriction_lint! {
|
||||
|
@ -16,7 +16,7 @@ use utils::{self, higher};
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let x = [1,2,3,4];
|
||||
/// ...
|
||||
/// x[9];
|
||||
@ -38,7 +38,7 @@ declare_lint! {
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// ...
|
||||
/// x[2];
|
||||
/// &x[0..2];
|
||||
|
@ -11,7 +11,7 @@ use utils::{higher, sugg};
|
||||
/// **Known problems:** Types implementing `OpAssign` don't necessarily implement `Op`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// a += 1;
|
||||
/// ```
|
||||
declare_restriction_lint! {
|
||||
@ -27,7 +27,7 @@ declare_restriction_lint! {
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let mut a = 5;
|
||||
/// ...
|
||||
/// a = a + b;
|
||||
|
@ -18,7 +18,7 @@ use utils::paths;
|
||||
/// **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(..) { ... }
|
||||
/// ```
|
||||
@ -34,7 +34,7 @@ declare_lint! {
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// #[deprecated(since = "forever")]
|
||||
/// fn something_else(..) { ... }
|
||||
/// ```
|
||||
|
@ -26,7 +26,10 @@ use utils::span_lint;
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `x & 1 == 2` (also see table above)
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if (x & 1 == 2) { … }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub BAD_BIT_MASK,
|
||||
Warn,
|
||||
@ -45,7 +48,10 @@ declare_lint! {
|
||||
///
|
||||
/// **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:** `x | 1 > 3` (also see table above)
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if (x | 1 > 3) { … }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub INEFFECTIVE_BIT_MASK,
|
||||
Warn,
|
||||
|
@ -8,7 +8,10 @@ use utils::span_lint;
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `let foo = 3.14;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let foo = 3.14;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub BLACKLISTED_NAME,
|
||||
Warn,
|
||||
|
@ -9,7 +9,10 @@ use utils::*;
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `if { true } ..`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if { true } ..
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub BLOCK_IN_IF_CONDITION_EXPR, Warn,
|
||||
"braces can be eliminated in conditions that are expressions, e.g `if { true } ...`"
|
||||
@ -21,7 +24,12 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `if { let x = somefunc(); x } ..` or `if somefunc(|x| { x == 47 }) ..`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if { let x = somefunc(); x } ..
|
||||
/// // or
|
||||
/// if somefunc(|x| { x == 47 }) ..
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub BLOCK_IN_IF_CONDITION_STMT, Warn,
|
||||
"avoid complex blocks in conditions, instead move the block higher and bind it \
|
||||
|
@ -6,11 +6,11 @@ use syntax::codemap::{DUMMY_SP, dummy_spanned};
|
||||
use syntax::util::ThinVec;
|
||||
use utils::{span_lint_and_then, in_macro, snippet_opt, SpanlessEq};
|
||||
|
||||
/// **What it does:** This lint checks for boolean expressions that can be written more concisely
|
||||
/// **What it does:** This lint checks for boolean expressions that can be written more concisely.
|
||||
///
|
||||
/// **Why is this bad?** Readability of boolean expressions suffers from unnecesessary duplication
|
||||
/// **Why is this bad?** Readability of boolean expressions suffers from unnecessary duplication.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuting behavior of `||` and `&&`. Ignores `|`, `&` and `^`.
|
||||
/// **Known problems:** Ignores short circuiting behavior of `||` and `&&`. Ignores `|`, `&` and `^`.
|
||||
///
|
||||
/// **Example:** `if a && true` should be `if a` and `!(a == b)` should be `a != b`
|
||||
declare_lint! {
|
||||
@ -18,11 +18,11 @@ declare_lint! {
|
||||
"checks for boolean expressions that can be written more concisely"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for boolean expressions that contain terminals that can be eliminated
|
||||
/// **What it does:** This lint checks for boolean expressions that contain terminals that can be eliminated.
|
||||
///
|
||||
/// **Why is this bad?** This is most likely a logic bug
|
||||
/// **Why is this bad?** This is most likely a logic bug.
|
||||
///
|
||||
/// **Known problems:** Ignores short circuiting behavior
|
||||
/// **Known problems:** Ignores short circuiting behavior.
|
||||
///
|
||||
/// **Example:** The `b` in `if a && b || a` is unnecessary because the expression is equivalent to `if a`
|
||||
declare_lint! {
|
||||
|
@ -26,14 +26,44 @@ use utils::sugg::Sugg;
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `if x { if y { .. } }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x {
|
||||
/// if y {
|
||||
/// …
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// if x {
|
||||
/// …
|
||||
/// } else {
|
||||
/// if y {
|
||||
/// …
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Should be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// if x && y {
|
||||
/// …
|
||||
/// }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// if x {
|
||||
/// …
|
||||
/// } else if y {
|
||||
/// …
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub COLLAPSIBLE_IF,
|
||||
Warn,
|
||||
"two nested `if`-expressions can be collapsed into one, e.g. `if x { if y { foo() } }` \
|
||||
can be written as `if x && y { foo() }` \
|
||||
and an `else { if .. }` expression can be collapsed to \
|
||||
`else if`"
|
||||
"`if`s that can be collapsed (e.g. `if x { if y { … } }` and `else { if x { … } }`)"
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
|
@ -8,14 +8,30 @@ use syntax::util::small_vector::SmallVector;
|
||||
use utils::{SpanlessEq, SpanlessHash};
|
||||
use utils::{get_parent_expr, in_macro, span_lint_and_then, span_note_and_lint, snippet};
|
||||
|
||||
/// **What it does:** This lint checks for consecutive `ifs` with the same condition. This lint is
|
||||
/// `Warn` by default.
|
||||
/// **What it does:** This lint checks for consecutive `ifs` with the same condition.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:** `if a == b { .. } else if a == b { .. }`
|
||||
/// **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_lint! {
|
||||
pub IFS_SAME_COND,
|
||||
Warn,
|
||||
@ -23,13 +39,20 @@ declare_lint! {
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for `if/else` with the same body as the *then* part and the
|
||||
/// *else* part. This lint is `Warn` by default.
|
||||
/// *else* part.
|
||||
///
|
||||
/// **Why is this bad?** This is probably a copy & paste error.
|
||||
///
|
||||
/// **Known problems:** Hopefully none.
|
||||
///
|
||||
/// **Example:** `if .. { 42 } else { 42 }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let foo = if … {
|
||||
/// 42
|
||||
/// } else {
|
||||
/// 42
|
||||
/// };
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub IF_SAME_THEN_ELSE,
|
||||
Warn,
|
||||
|
@ -6,13 +6,22 @@ use rustc_const_math::*;
|
||||
use rustc::hir::*;
|
||||
use utils::span_lint;
|
||||
|
||||
/// **What it does:** Lints on C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`.
|
||||
/// **What it does:** Lints on 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 32bit architectures, but works fine on 64 bit.
|
||||
/// **Why is this bad?** This will truncate the variant value on 32 bit architectures, but works
|
||||
/// fine on 64 bit.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `#[repr(usize)] enum NonPortable { X = 0x1_0000_0000, Y = 0 }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[repr(usize)]
|
||||
/// enum NonPortable {
|
||||
/// X = 0x1_0000_0000,
|
||||
/// Y = 0
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub ENUM_CLIKE_UNPORTABLE_VARIANT, Warn,
|
||||
"finds C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`"
|
||||
|
@ -9,13 +9,16 @@ use syntax::ast::NodeId;
|
||||
use syntax::codemap::Span;
|
||||
use utils::span_lint;
|
||||
|
||||
/// **What it does:** Warns when `use`ing all variants of an enum
|
||||
/// **What it does:** Warns when `use`ing all variants of an enumeration.
|
||||
///
|
||||
/// **Why is this bad?** It is usually better style to use the prefixed name of an enum variant, rather than importing variants
|
||||
/// **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 enums that prefix the variants are still around
|
||||
/// **Known problems:** Old-style enumerations that prefix the variants are still around
|
||||
///
|
||||
/// **Example:** `use std::cmp::Ordering::*;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// use std::cmp::Ordering::*;
|
||||
/// ```
|
||||
declare_lint! { pub ENUM_GLOB_USE, Allow,
|
||||
"finds use items that import all variants of an enum" }
|
||||
|
||||
|
@ -7,13 +7,21 @@ use syntax::parse::token::InternedString;
|
||||
use utils::{span_help_and_lint, span_lint};
|
||||
use utils::{camel_case_from, camel_case_until, in_macro};
|
||||
|
||||
/// **What it does:** Warns on enum variants that are prefixed or suffixed by the same characters
|
||||
/// **What it does:** Warns on enumeration variants that are prefixed or suffixed by the same
|
||||
/// characters.
|
||||
///
|
||||
/// **Why is this bad?** Enum variant names should specify their variant, not the enum, too.
|
||||
/// **Why is this bad?** Enumeration variant names should specify their variant, not repeat the
|
||||
/// enumeration name.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** enum Cake { BlackForestCake, HummingbirdCake }
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// enum Cake {
|
||||
/// BlackForestCake,
|
||||
/// HummingbirdCake,
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub ENUM_VARIANT_NAMES, Warn,
|
||||
"finds enums where all variants share a prefix/postfix"
|
||||
@ -25,7 +33,12 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** mod cake { struct BlackForestCake; }
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mod cake {
|
||||
/// struct BlackForestCake;
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub STUTTER, Allow,
|
||||
"finds type names prefixed/postfixed with their containing module's name"
|
||||
|
@ -8,9 +8,15 @@ use utils::{SpanlessEq, span_lint};
|
||||
///
|
||||
/// **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.
|
||||
/// **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:** `x + 1 == x + 1`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x + 1 == x + 1
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub EQ_OP,
|
||||
Warn,
|
||||
|
@ -19,7 +19,8 @@ pub struct Pass {
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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
|
||||
///
|
||||
|
@ -7,13 +7,17 @@ use utils::{snippet_opt, span_lint_and_then, is_adjusted};
|
||||
pub struct EtaPass;
|
||||
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **What it does:** This lint 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 just costs heap space and adds code for no benefit.
|
||||
/// **Why is this bad?** Needlessly creating a closure just costs heap space and adds code for no
|
||||
/// benefit.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `xs.map(|x| foo(x))` where `foo(_)` is a plain function that takes the exact argument type of `x`.
|
||||
/// **Example:** `xs.map(|x| foo(x))` where `foo(_)` is a plain function that takes the exact
|
||||
/// argument type of `x`.
|
||||
declare_lint! {
|
||||
pub REDUNDANT_CLOSURE, Warn,
|
||||
"using redundant closures, i.e. `|a| foo(a)` (which can be written as just `foo`)"
|
||||
|
@ -9,7 +9,8 @@ use utils::{is_expn_of, match_path, match_type, span_lint, walk_ptrs_ty};
|
||||
/// **What it does:** This lints about 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!("too")` can be replaced by `"foo".to_owned()` if you really need a `String`. The even worse `&format!("foo")` is often
|
||||
/// **Why is this bad?** There is no point of doing that. `format!("too")` 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()` is `foo: &str`.
|
||||
///
|
||||
|
@ -7,11 +7,15 @@ use rustc_const_math::ConstInt;
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `x / 1 + 0 * 1 - 0 | 0`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x / 1 + 0 * 1 - 0 | 0
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub IDENTITY_OP, Warn,
|
||||
"using identity operations, e.g. `x + 0` or `y / 1`"
|
||||
|
@ -11,7 +11,24 @@ use utils::span_help_and_lint;
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** if !v.is_empty() { a() } else { b() }
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if !v.is_empty() {
|
||||
/// a()
|
||||
/// } else {
|
||||
/// b()
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// if v.is_empty() {
|
||||
/// b()
|
||||
/// } else {
|
||||
/// a()
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub IF_NOT_ELSE, Allow,
|
||||
"finds if branches that could be swapped so no negation operation is necessary on the condition"
|
||||
|
@ -17,6 +17,7 @@ use utils::{in_macro, span_lint};
|
||||
/// fn foo() {
|
||||
/// println!("cake");
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// foo(); // prints "foo"
|
||||
/// fn foo() {
|
||||
|
@ -7,13 +7,19 @@ use syntax::codemap::{Span, Spanned};
|
||||
use syntax::ptr::P;
|
||||
use utils::{get_item_name, in_macro, snippet, span_lint, span_lint_and_then, walk_ptrs_ty};
|
||||
|
||||
/// **What it does:** This lint checks for getting the length of something via `.len()` just to compare to zero, and suggests using `.is_empty()` where applicable.
|
||||
/// **What it does:** This lint 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. 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 comparison.
|
||||
/// **Why is this bad?** Some structures can answer `.is_empty()` much faster than calculating
|
||||
/// their length. 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 comparison.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `if x.len() == 0 { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x.len() == 0 { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub LEN_ZERO, Warn,
|
||||
"checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` \
|
||||
@ -22,12 +28,15 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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 {
|
||||
/// fn len(&self) -> usize { .. }
|
||||
/// }
|
||||
|
@ -7,13 +7,19 @@ use std::collections::{HashSet, HashMap};
|
||||
use syntax::codemap::Span;
|
||||
use utils::{in_external_macro, span_lint};
|
||||
|
||||
/// **What it does:** This lint checks for lifetime annotations which can be removed by relying on lifetime elision.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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.
|
||||
/// **Known problems:** Potential false negatives: we bail out if the function has a `where` clause
|
||||
/// where lifetimes are mentioned.
|
||||
///
|
||||
/// **Example:** `fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { x }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { x }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NEEDLESS_LIFETIMES,
|
||||
Warn,
|
||||
@ -23,11 +29,15 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `fn unused_lifetime<'a>(x: u8) { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn unused_lifetime<'a>(x: u8) { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub UNUSED_LIFETIMES,
|
||||
Warn,
|
||||
|
@ -19,14 +19,16 @@ use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type,
|
||||
walk_ptrs_ty};
|
||||
use utils::paths;
|
||||
|
||||
/// **What it does:** This lint checks for looping over the range of `0..len` of some collection just to get the values by index.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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]);
|
||||
/// }
|
||||
@ -43,7 +45,11 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** False negatives. We currently only warn on some known types.
|
||||
///
|
||||
/// **Example:** `for x in y.iter() { .. }` (where y is a `Vec` or slice)
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // with `y` a `Vec` or slice:
|
||||
/// for x in y.iter() { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub EXPLICIT_ITER_LOOP,
|
||||
Warn,
|
||||
@ -52,11 +58,18 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint 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).
|
||||
/// **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:** `for x in y.next() { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in y.next() { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub ITER_NEXT_LOOP,
|
||||
Warn,
|
||||
@ -69,7 +82,15 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `for x in option { .. }`. This should be `if let Some(x) = option { .. }`.
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in option { .. }
|
||||
/// ```
|
||||
///
|
||||
/// This should be
|
||||
/// ```rust
|
||||
/// if let Some(x) = option { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub FOR_LOOP_OVER_OPTION,
|
||||
Warn,
|
||||
@ -82,14 +103,23 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `for x in result { .. }`. This should be `if let Ok(x) = result { .. }`.
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in result { .. }
|
||||
/// ```
|
||||
///
|
||||
/// This should be
|
||||
/// ```rust
|
||||
/// if let Ok(x) = result { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub FOR_LOOP_OVER_RESULT,
|
||||
Warn,
|
||||
"for-looping over a `Result`, which is more clearly expressed as an `if let`"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint detects `loop + match` combinations that are easier written as a `while let` loop.
|
||||
/// **What it does:** This lint 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
|
||||
///
|
||||
@ -97,7 +127,7 @@ declare_lint! {
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// loop {
|
||||
/// let x = match y {
|
||||
/// Some(x) => x,
|
||||
@ -116,13 +146,17 @@ declare_lint! {
|
||||
"`loop { if let { ... } else break }` can be written as a `while let` loop"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for using `collect()` on an iterator without using the result.
|
||||
/// **What it does:** This lint 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:** `vec.iter().map(|x| /* some operation returning () */).collect::<Vec<_>>();`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// vec.iter().map(|x| /* some operation returning () */).collect::<Vec<_>>();
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub UNUSED_COLLECT,
|
||||
Warn,
|
||||
@ -130,26 +164,40 @@ declare_lint! {
|
||||
written as a for loop"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint 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(_)`.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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.
|
||||
/// **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.
|
||||
///
|
||||
/// **Examples**: `for x in 5..10-5 { .. }` (oops, stray `-`)
|
||||
/// **Examples**:
|
||||
/// ```rust
|
||||
/// for x in 5..10-5 { .. } // oops, stray `-`
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub REVERSE_RANGE_LOOP,
|
||||
Warn,
|
||||
"Iterating over an empty range, such as `10..0` or `5..5`"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks `for` loops over slices with an explicit counter and suggests the use of `.enumerate()`.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `for i in 0..v.len() { foo(v[i]); }` or `for i in 0..v.len() { bar(i, v[i]); }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for i in 0..v.len() { foo(v[i]);
|
||||
/// for i in 0..v.len() { bar(i, v[i]); }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub EXPLICIT_COUNTER_LOOP,
|
||||
Warn,
|
||||
@ -158,11 +206,16 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `loop {}`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// loop {}
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub EMPTY_LOOP,
|
||||
Warn,
|
||||
@ -175,7 +228,10 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `while let Some(val) = iter() { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// while let Some(val) = iter() { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub WHILE_LET_ON_ITERATOR,
|
||||
Warn,
|
||||
@ -194,7 +250,9 @@ declare_lint! {
|
||||
/// ```rust
|
||||
/// for (k, _) in &map { .. }
|
||||
/// ```
|
||||
///
|
||||
/// could be replaced by
|
||||
///
|
||||
/// ```rust
|
||||
/// for k in map.keys() { .. }
|
||||
/// ```
|
||||
|
@ -10,7 +10,10 @@ use utils::{is_adjusted, match_path, match_trait_method, match_type, paths, snip
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `x.map(|e| e.clone());`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x.map(|e| e.clone());
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub MAP_CLONE, Warn,
|
||||
"using `.map(|x| x.clone())` to clone an iterator or option's contents (recommends \
|
||||
|
@ -12,14 +12,15 @@ use utils::paths;
|
||||
use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, in_external_macro, expr_block};
|
||||
use utils::sugg::Sugg;
|
||||
|
||||
/// **What it does:** This lint checks for matches with a single arm where an `if let` will usually suffice.
|
||||
/// **What it does:** This lint 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),
|
||||
/// _ => ()
|
||||
@ -31,14 +32,15 @@ declare_lint! {
|
||||
is `_ => {}`) is used; recommends `if let` instead"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for matches with a two arms where an `if let` will usually suffice.
|
||||
/// **What it does:** This lint checks for matches with a two arms where an `if let` will usually
|
||||
/// suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
|
||||
///
|
||||
/// **Known problems:** Personal style preferences may differ
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// match x {
|
||||
/// Some(ref foo) -> bar(foo),
|
||||
/// _ => bar(other_ref),
|
||||
@ -50,15 +52,18 @@ declare_lint! {
|
||||
recommends `if let` instead"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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(),
|
||||
@ -71,7 +76,8 @@ declare_lint! {
|
||||
dereferenced instead"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for matches where match expression is a `bool`. It suggests to replace the expression with an `if...else` block.
|
||||
/// **What it does:** This lint 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.
|
||||
///
|
||||
@ -79,7 +85,7 @@ declare_lint! {
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let condition: bool = true;
|
||||
/// match condition {
|
||||
/// true => foo(),
|
||||
@ -99,7 +105,7 @@ declare_lint! {
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let x = 5;
|
||||
/// match x {
|
||||
/// 1 ... 10 => println!("1 ... 10"),
|
||||
|
@ -4,11 +4,15 @@ use utils::{match_def_path, paths, span_lint};
|
||||
|
||||
/// **What it does:** This lint 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
|
||||
/// **Why is this bad?** `std::mem::forget(t)` prevents `t` from running its destructor, possibly
|
||||
/// causing leaks
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `mem::forget(Rc::new(55)))`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// mem::forget(Rc::new(55)))
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub MEM_FORGET,
|
||||
Allow,
|
||||
|
@ -22,7 +22,9 @@ pub struct Pass;
|
||||
|
||||
/// **What it does:** This lint checks for `.unwrap()` calls on `Option`s.
|
||||
///
|
||||
/// **Why is this bad?** Usually it is better to handle the `None` case, or to at least call `.expect(_)` with a more helpful message. Still, for a lot of quick-and-dirty code, `unwrap` is a good choice, which is why this lint is `Allow` by default.
|
||||
/// **Why is this bad?** Usually it is better to handle the `None` case, or to at least call
|
||||
/// `.expect(_)` with a more helpful message. Still, for a lot of quick-and-dirty code, `unwrap` is
|
||||
/// a good choice, which is why this lint is `Allow` by default.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
@ -37,9 +39,12 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint checks for `.unwrap()` calls on `Result`s.
|
||||
///
|
||||
/// **Why is this bad?** `result.unwrap()` will let the thread panic on `Err` values. Normally, you want to implement more sophisticated error handling, and propagate errors upwards with `try!`.
|
||||
/// **Why is this bad?** `result.unwrap()` will let the thread panic on `Err` values. Normally, you
|
||||
/// want to implement more sophisticated error handling, and propagate errors upwards with `try!`.
|
||||
///
|
||||
/// Even if you want to panic on errors, not all `Error`s implement good messages on display. Therefore it may be beneficial to look at the places where they may get displayed. Activate this lint to do just that.
|
||||
/// Even if you want to panic on errors, not all `Error`s implement good messages on display.
|
||||
/// Therefore it may be beneficial to look at the places where they may get displayed. Activate
|
||||
/// this lint to do just that.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
@ -52,14 +57,18 @@ declare_lint! {
|
||||
"using `Result.unwrap()`, which might be better handled"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for methods that should live in a trait implementation of a `std` trait (see [llogiq's blog post](http://llogiq.github.io/2015/07/30/traits.html) for further information) instead of an inherent implementation.
|
||||
/// **What it does:** This lint checks for methods that should live in a trait implementation of a
|
||||
/// `std` trait (see [llogiq's blog post](http://llogiq.github.io/2015/07/30/traits.html) for
|
||||
/// further information) instead of an inherent implementation.
|
||||
///
|
||||
/// **Why is this bad?** Implementing the traits improve ergonomics for users of the code, often with very little cost. Also people seeing a `mul(..)` method may expect `*` to work equally, so you should have good reason to disappoint them.
|
||||
/// **Why is this bad?** Implementing the traits improve ergonomics for users of the code, often
|
||||
/// with very little cost. Also people seeing a `mul(..)` method may expect `*` to work equally, so
|
||||
/// you should have good reason to disappoint them.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// struct X;
|
||||
/// impl X {
|
||||
/// fn add(&self, other: &X) -> X { .. }
|
||||
@ -70,7 +79,8 @@ declare_lint! {
|
||||
"defining a method that should be implementing a std trait"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for methods with certain name prefixes and which doesn't match how self is taken. The actual rules are:
|
||||
/// **What it does:** This lint checks for methods with certain name prefixes and which doesn't
|
||||
/// match how self is taken. The actual rules are:
|
||||
///
|
||||
/// |Prefix |`self` taken |
|
||||
/// |-------|----------------------|
|
||||
@ -80,7 +90,8 @@ declare_lint! {
|
||||
/// |`is_` |`&self` or none |
|
||||
/// |`to_` |`&self` |
|
||||
///
|
||||
/// **Why is this bad?** Consistency breeds readability. If you follow the conventions, your users won't be surprised that they, e.g., need to supply a mutable reference to a `as_..` function.
|
||||
/// **Why is this bad?** Consistency breeds readability. If you follow the conventions, your users
|
||||
/// won't be surprised that they, e.g., need to supply a mutable reference to a `as_..` function.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
@ -97,11 +108,14 @@ declare_lint! {
|
||||
`self` with the wrong convention"
|
||||
}
|
||||
|
||||
/// **What it does:** This is the same as [`wrong_self_convention`](#wrong_self_convention), but for public items.
|
||||
/// **What it does:** This is the same as [`wrong_self_convention`](#wrong_self_convention), but
|
||||
/// for public items.
|
||||
///
|
||||
/// **Why is this bad?** See [`wrong_self_convention`](#wrong_self_convention).
|
||||
///
|
||||
/// **Known problems:** Actually *renaming* the function may break clients if the function is part of the public interface. In that case, be mindful of the stability guarantees you've given your users.
|
||||
/// **Known problems:** Actually *renaming* the function may break clients if the function is part
|
||||
/// of the public interface. In that case, be mindful of the stability guarantees you've given your
|
||||
/// users.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
@ -117,7 +131,8 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint checks for usage of `ok().expect(..)`.
|
||||
///
|
||||
/// **Why is this bad?** Because you usually call `expect()` on the `Result` directly to get a good error message.
|
||||
/// **Why is this bad?** Because you usually call `expect()` on the `Result` directly to get a good
|
||||
/// error message.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
@ -178,7 +193,8 @@ declare_lint! {
|
||||
"using `filter(p).next()`, which is more succinctly expressed as `.find(p)`"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint `Warn`s on `_.filter(_).map(_)`, `_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar.
|
||||
/// **What it does:** This lint `Warn`s on `_.filter(_).map(_)`, `_.filter(_).flat_map(_)`,
|
||||
/// `_.filter_map(_).flat_map(_)` and similar.
|
||||
///
|
||||
/// **Why is this bad?** Readability, this can be written more concisely as a single method call
|
||||
///
|
||||
@ -352,7 +368,7 @@ declare_lint! {
|
||||
/// ```rust,ignore
|
||||
/// let c_str = CString::new("foo").unwrap();
|
||||
/// unsafe {
|
||||
/// call_some_ffi_func(c_str.as_ptr());
|
||||
/// call_some_ffi_func(c_str.as_ptr());
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
|
@ -5,13 +5,16 @@ use std::cmp::{PartialOrd, Ordering};
|
||||
use syntax::ptr::P;
|
||||
use utils::{match_def_path, paths, span_lint};
|
||||
|
||||
/// **What it does:** This lint checks for expressions where `std::cmp::min` and `max` are used to clamp values, but switched so that the result is constant.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `min(0, max(100, x))` 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`.
|
||||
/// **Example:** `min(0, max(100, x))` 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_lint! {
|
||||
pub MIN_MAX, Warn,
|
||||
"`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant"
|
||||
|
@ -17,13 +17,22 @@ use utils::sugg::Sugg;
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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.
|
||||
/// 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.
|
||||
/// **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:** `fn foo(ref x: u8) -> bool { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(ref x: u8) -> bool { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub TOPLEVEL_REF_ARG, Warn,
|
||||
"An entire binding was declared as `ref`, in a function argument (`fn foo(ref x: Bar)`), \
|
||||
|
@ -10,7 +10,10 @@ use utils::{span_lint, span_help_and_lint, snippet, span_lint_and_then};
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `let { a: _, b: ref b, c: _ } = ..`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let { a: _, b: ref b, c: _ } = ..
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub UNNEEDED_FIELD_PATTERN, Warn,
|
||||
"Struct fields are bound to a wildcard instead of using `..`"
|
||||
@ -22,7 +25,10 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `fn foo(a: i32, _a: i32) {}`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(a: i32, _a: i32) {}
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub DUPLICATE_UNDERSCORE_ARGUMENT, Warn,
|
||||
"Function arguments having names which only differ by an underscore"
|
||||
@ -34,7 +40,10 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `(|| 42)()`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// (|| 42)()
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub REDUNDANT_CLOSURE_CALL, Warn,
|
||||
"Closures should not be called in the expression they are defined"
|
||||
@ -46,7 +55,10 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `--x;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// --x;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub DOUBLE_NEG, Warn,
|
||||
"`--x` is a double negation of `x` and not a pre-decrement as in C or C++"
|
||||
|
@ -6,16 +6,19 @@ use utils::{higher, in_external_macro, span_lint};
|
||||
|
||||
/// **What it does:** This lint checks for instances of `mut mut` references.
|
||||
///
|
||||
/// **Why is this bad?** Multiple `mut`s don't add anything meaningful to the source.
|
||||
/// **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:** `let x = &mut &mut y;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = &mut &mut y;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub MUT_MUT,
|
||||
Allow,
|
||||
"usage of double-mut refs, e.g. `&mut &mut ...` (either copy'n'paste error, \
|
||||
or shows a fundamental misunderstanding of references)"
|
||||
"usage of double-mut refs, e.g. `&mut &mut ...`"
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
|
@ -4,13 +4,18 @@ use rustc::hir::*;
|
||||
use syntax::ptr::P;
|
||||
use utils::span_lint;
|
||||
|
||||
/// **What it does:** This lint detects giving a mutable reference to a function that only requires an immutable reference.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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** `my_vec.push(&mut value)`
|
||||
/// **Example**
|
||||
/// ```rust
|
||||
/// my_vec.push(&mut value)
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub UNNECESSARY_MUT_PASSED,
|
||||
Warn,
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Checks for uses of Mutex where an atomic value could be used
|
||||
//! Checks for uses of mutex where an atomic value could be used
|
||||
//!
|
||||
//! This lint is **warn** by default
|
||||
|
||||
@ -11,28 +11,37 @@ use utils::{match_type, paths, span_lint};
|
||||
|
||||
/// **What it does:** This lint 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::atomic::AtomicBool` and `std::atomic::AtomicPtr` are leaner and faster.
|
||||
/// **Why is this bad?** Using a mutex just to make access to a plain bool or reference sequential
|
||||
/// is shooting flies with cannons. `std::atomic::AtomicBool` and `std::atomic::AtomicPtr` are
|
||||
/// leaner and faster.
|
||||
///
|
||||
/// **Known problems:** This lint cannot detect if the Mutex is actually used for waiting before a critical section.
|
||||
/// **Known problems:** This lint cannot detect if the mutex is actually used for waiting before a critical section.
|
||||
///
|
||||
/// **Example:** `let x = Mutex::new(&y);`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Mutex::new(&y);
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub MUTEX_ATOMIC,
|
||||
Warn,
|
||||
"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:** This lint 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::atomic::usize` is leaner and faster.
|
||||
/// **Why is this bad?** Using a mutex just to make access to a plain integer sequential is
|
||||
/// shooting flies with cannons. `std::atomic::usize` is leaner and faster.
|
||||
///
|
||||
/// **Known problems:** This lint cannot detect if the Mutex is actually used for waiting before a critical section.
|
||||
/// **Known problems:** This lint cannot detect if the mutex is actually used for waiting before a critical section.
|
||||
///
|
||||
/// **Example:** `let x = Mutex::new(0usize);`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = Mutex::new(0usize);
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub MUTEX_INTEGER,
|
||||
Allow,
|
||||
"using a Mutex for an integer type"
|
||||
"using a mutex for an integer type"
|
||||
}
|
||||
|
||||
impl LintPass for MutexAtomic {
|
||||
|
@ -9,13 +9,19 @@ use syntax::codemap::Spanned;
|
||||
use utils::{span_lint, span_lint_and_then, snippet};
|
||||
use utils::sugg::Sugg;
|
||||
|
||||
/// **What it does:** This lint checks for expressions of the form `if c { true } else { false }` (or vice versa) and suggest using the condition directly.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `if x { false } else { true }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// if x { false } else { true }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NEEDLESS_BOOL,
|
||||
Warn,
|
||||
@ -23,7 +29,8 @@ declare_lint! {
|
||||
`if p { true } else { false }`"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for expressions of the form `x == true` (or vice versa) and suggest using the variable directly.
|
||||
/// **What it does:** This lint checks for expressions of the form `x == true` (or vice versa) and
|
||||
/// suggest using the variable directly.
|
||||
///
|
||||
/// **Why is this bad?** Unnecessary code.
|
||||
///
|
||||
|
@ -8,13 +8,17 @@ use rustc::ty::TyRef;
|
||||
use utils::{span_lint, in_macro};
|
||||
use rustc::ty::adjustment::AutoAdjustment::AdjustDerefRef;
|
||||
|
||||
/// **What it does:** This lint checks for address of operations (`&`) that are going to be dereferenced immediately by the compiler
|
||||
/// **What it does:** This lint 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
|
||||
/// **Why is this bad?** Suggests that the receiver of the expression borrows the expression.
|
||||
///
|
||||
/// **Known problems:**
|
||||
///
|
||||
/// **Example:** `let x: &i32 = &&&&&&5;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x: &i32 = &&&&&&5;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NEEDLESS_BORROW,
|
||||
Warn,
|
||||
|
@ -9,11 +9,14 @@ use utils::span_lint;
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `Point { x: 1, y: 0, ..zero_point }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// Point { x: 1, y: 0, ..zero_point }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NEEDLESS_UPDATE,
|
||||
Warn,
|
||||
"using `{ ..base }` when there are no missing fields"
|
||||
"using `Foo { ..base }` when there are no missing fields"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -11,7 +11,10 @@ use utils::span_lint;
|
||||
///
|
||||
/// **Known problems:** This only catches integers (for now)
|
||||
///
|
||||
/// **Example:** `x * -1`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x * -1
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NEG_MULTIPLY,
|
||||
Warn,
|
||||
|
@ -6,11 +6,15 @@ use std::ops::Deref;
|
||||
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `0;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// 0;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NO_EFFECT,
|
||||
Warn,
|
||||
@ -19,11 +23,15 @@ declare_lint! {
|
||||
|
||||
/// **What it does:** This lint 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 redability.
|
||||
/// **Why is this bad?** Expressions by themselves often have no side-effects. Having such
|
||||
/// expressions reduces readability.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `compute_array()[0];`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// compute_array()[0];
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub UNNECESSARY_OPERATION,
|
||||
Warn,
|
||||
|
@ -4,13 +4,18 @@ use syntax::ast::LitKind;
|
||||
use syntax::codemap::{Span, Spanned};
|
||||
use utils::{match_type, paths, span_lint, walk_ptrs_ty_depth};
|
||||
|
||||
/// **What it does:** This lint checks for duplicate open options as well as combinations that make no sense.
|
||||
/// **What it does:** This lint 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.
|
||||
/// **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:** `OpenOptions::new().read(true).truncate(true)`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// OpenOptions::new().read(true).truncate(true)
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NONSENSICAL_OPEN_OPTIONS,
|
||||
Warn,
|
||||
|
@ -4,11 +4,15 @@ use utils::span_lint;
|
||||
|
||||
/// **What it does:** This lint finds 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.
|
||||
/// **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:** `a + b < a`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a + b < a
|
||||
/// ```
|
||||
|
||||
declare_lint!(pub OVERFLOW_CHECK_CONDITIONAL, Warn,
|
||||
"Using overflow checks which are likely to panic");
|
||||
|
@ -9,7 +9,7 @@ use utils::{is_direct_expn_of, match_path, paths, span_lint};
|
||||
/// this lint will warn.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// panic!("This `panic!` is probably missing a parameter there: {}");
|
||||
/// ```
|
||||
declare_lint! {
|
||||
|
@ -3,11 +3,14 @@ use syntax::ast::*;
|
||||
use syntax::codemap::Spanned;
|
||||
use utils::{span_lint, snippet};
|
||||
|
||||
/// **What it does:** This lint checks for operations where precedence may be unclear and suggests to add parentheses. Currently it catches the following:
|
||||
/// **What it does:** This lint 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
|
||||
/// * a "negative" numeric literal (which is really a unary `-` followed by a numeric literal)
|
||||
/// followed by a method call
|
||||
///
|
||||
/// **Why is this bad?** Because not everyone knows the precedence of those operators by heart, so expressions like these may trip others trying to reason about the code.
|
||||
/// **Why is this bad?** Because 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
|
||||
///
|
||||
@ -16,8 +19,7 @@ use utils::{span_lint, snippet};
|
||||
/// * `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1
|
||||
declare_lint! {
|
||||
pub PRECEDENCE, Warn,
|
||||
"catches operations where precedence may be unclear. See the wiki for a \
|
||||
list of cases caught"
|
||||
"catches operations where precedence may be unclear"
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
|
@ -4,26 +4,34 @@ use rustc::lint::*;
|
||||
use utils::paths;
|
||||
use utils::{is_expn_of, match_path, span_lint};
|
||||
|
||||
/// **What it does:** This lint warns whenever you print on *stdout*. The purpose of this lint is to catch debugging remnants.
|
||||
/// **What it does:** This lint warns whenever you print on *stdout*. The purpose of this lint is
|
||||
/// to catch debugging remnants.
|
||||
///
|
||||
/// **Why is this bad?** People often print on *stdout* while debugging an application and might
|
||||
/// forget to remove those prints afterward.
|
||||
///
|
||||
/// **Known problems:** Only catches `print!` and `println!` calls.
|
||||
///
|
||||
/// **Example:** `println!("Hello world!");`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// println!("Hello world!");
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub PRINT_STDOUT,
|
||||
Allow,
|
||||
"printing on stdout"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint warns whenever you use `Debug` formatting. The purpose of this lint is to catch debugging remnants.
|
||||
/// **What it does:** This lint warns whenever you use `Debug` formatting. The purpose of this lint
|
||||
/// is to catch debugging remnants.
|
||||
///
|
||||
/// **Why is this bad?** The purpose of the `Debug` trait is to facilitate debugging Rust code. It
|
||||
/// should not be used in in user-facing output.
|
||||
///
|
||||
/// **Example:** `println!("{:?}", foo);`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// println!("{:?}", foo);
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub USE_DEBUG,
|
||||
Allow,
|
||||
|
@ -7,13 +7,19 @@ use rustc::ty;
|
||||
use syntax::ast::NodeId;
|
||||
use utils::{match_type, paths, span_lint};
|
||||
|
||||
/// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless the references are mutable.
|
||||
/// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless
|
||||
/// the references are mutable.
|
||||
///
|
||||
/// **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.
|
||||
/// **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:** None
|
||||
///
|
||||
/// **Example:** `fn foo(&Vec<u32>) { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(&Vec<u32>) { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub PTR_ARG,
|
||||
Warn,
|
||||
|
@ -4,13 +4,18 @@ use syntax::codemap::Spanned;
|
||||
use utils::{is_integer_literal, match_type, paths, snippet, span_lint};
|
||||
use utils::higher;
|
||||
|
||||
/// **What it does:** This lint checks for iterating over ranges with a `.step_by(0)`, which never terminates.
|
||||
/// **What it does:** This lint checks for iterating over ranges with a `.step_by(0)`, which never
|
||||
/// terminates.
|
||||
///
|
||||
/// **Why is this bad?** This very much looks like an oversight, since with `loop { .. }` there is an obvious better way to endlessly loop.
|
||||
/// **Why is this bad?** This very much looks like an oversight, since with `loop { .. }` there is
|
||||
/// an obvious better way to endlessly loop.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `for x in (5..5).step_by(0) { .. }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// for x in (5..5).step_by(0) { .. }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub RANGE_STEP_BY_ZERO, Warn,
|
||||
"using Range::step_by(0), which produces an infinite iterator"
|
||||
@ -21,7 +26,10 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `x.iter().zip(0..x.len())`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// x.iter().zip(0..x.len())
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub RANGE_ZIP_WITH_LEN, Warn,
|
||||
"zipping iterator with a range when enumerate() would do"
|
||||
|
@ -14,11 +14,16 @@ use utils::{is_expn_of, match_def_path, match_type, paths, span_lint, span_help_
|
||||
/// **What it does:** This lint checks [regex] creation (with `Regex::new`, `RegexBuilder::new` or
|
||||
/// `RegexSet::new`) for correct regex syntax.
|
||||
///
|
||||
/// [regex]: https://crates.io/crates/regex
|
||||
///
|
||||
/// **Why is this bad?** This will lead to a runtime panic.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `Regex::new("|")`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// Regex::new("|")
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub INVALID_REGEX,
|
||||
Deny,
|
||||
@ -28,27 +33,35 @@ declare_lint! {
|
||||
/// **What it does:** This lint checks for trivial [regex] creation (with `Regex::new`,
|
||||
/// `RegexBuilder::new` or `RegexSet::new`).
|
||||
///
|
||||
/// [regex]: https://crates.io/crates/regex
|
||||
///
|
||||
/// **Why is this bad?** This can likely be replaced by `==` or `str::starts_with`,
|
||||
/// `str::ends_with` or `std::contains` or other `str` methods.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `Regex::new("^foobar")`
|
||||
///
|
||||
/// [regex]: https://crates.io/crates/regex
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// Regex::new("^foobar")
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub TRIVIAL_REGEX,
|
||||
Warn,
|
||||
"finds trivial regular expressions"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for usage of `regex!(_)` which as of now is usually slower than `Regex::new(_)` unless called in a loop (which is a bad idea anyway).
|
||||
/// **What it does:** This lint checks for usage of `regex!(_)` which as of now is usually slower
|
||||
/// than `Regex::new(_)` unless called in a loop (which is a bad idea anyway).
|
||||
///
|
||||
/// **Why is this bad?** Performance, at least for now. The macro version is likely to catch up long-term, but for now the dynamic version is faster.
|
||||
/// **Why is this bad?** Performance, at least for now. The macro version is likely to catch up
|
||||
/// long-term, but for now the dynamic version is faster.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `regex!("foo|bar")`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// regex!("foo|bar")
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub REGEX_MACRO,
|
||||
Warn,
|
||||
|
@ -9,9 +9,14 @@ use utils::{span_note_and_lint, span_lint_and_then, snippet_opt, match_path_ast,
|
||||
///
|
||||
/// **Why is this bad?** Removing the `return` and semicolon will make the code more rusty.
|
||||
///
|
||||
/// **Known problems:** Following this lint's advice may currently run afoul of Rust issue [#31439](https://github.com/rust-lang/rust/issues/31439), so if you get lifetime errors, please roll back the change until that issue is fixed.
|
||||
/// **Known problems:** Following this lint's advice may currently run afoul of Rust issue
|
||||
/// [#31439](https://github.com/rust-lang/rust/issues/31439), so if you get lifetime errors, please
|
||||
/// roll back the change until that issue is fixed.
|
||||
///
|
||||
/// **Example:** `fn foo(x: usize) { return x; }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// fn foo(x: usize) { return x; }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NEEDLESS_RETURN, Warn,
|
||||
"using a return statement like `return expr;` where an expression would suffice"
|
||||
@ -21,9 +26,14 @@ declare_lint! {
|
||||
///
|
||||
/// **Why is this bad?** It is just extraneous code. Remove it to make your code more rusty.
|
||||
///
|
||||
/// **Known problems:** Following this lint's advice may currently run afoul of Rust issue [#31439](https://github.com/rust-lang/rust/issues/31439), so if you get lifetime errors, please roll back the change until that issue is fixed.
|
||||
/// **Known problems:** Following this lint's advice may currently run afoul of Rust issue
|
||||
/// [#31439](https://github.com/rust-lang/rust/issues/31439), so if you get lifetime errors, please
|
||||
/// roll back the change until that issue is fixed.
|
||||
///
|
||||
/// **Example:** `{ let x = ..; x }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// { let x = ..; x }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub LET_AND_RETURN, Warn,
|
||||
"creating a let-binding and then immediately returning it like `let x = expr; x` at \
|
||||
|
@ -7,38 +7,59 @@ use std::ops::Deref;
|
||||
use syntax::codemap::Span;
|
||||
use utils::{higher, in_external_macro, snippet, span_lint_and_then};
|
||||
|
||||
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability.
|
||||
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope,
|
||||
/// while just changing reference level or mutability.
|
||||
///
|
||||
/// **Why is this bad?** Not much, in fact it's a very common pattern in Rust code. Still, some may opt to avoid it in their code base, they can set this lint to `Warn`.
|
||||
/// **Why is this bad?** Not much, in fact it's a very common pattern in Rust code. Still, some may
|
||||
/// opt to avoid it in their code base, they can set this lint to `Warn`.
|
||||
///
|
||||
/// **Known problems:** This lint, as the other shadowing related lints, currently only catches very simple patterns.
|
||||
/// **Known problems:** This lint, as the other shadowing related lints, currently only catches
|
||||
/// very simple patterns.
|
||||
///
|
||||
/// **Example:** `let x = &x;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = &x;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub SHADOW_SAME, Allow,
|
||||
"rebinding a name to itself, e.g. `let mut x = &mut x`"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope, while reusing the original value.
|
||||
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope,
|
||||
/// while reusing the original value.
|
||||
///
|
||||
/// **Why is this bad?** Not too much, in fact it's a common pattern in Rust code. Still, some argue that name shadowing like this hurts readability, because a value may be bound to different things depending on position in the code.
|
||||
/// **Why is this bad?** Not too much, in fact it's a common pattern in Rust code. Still, some
|
||||
/// argue that name shadowing like this hurts readability, because a value may be bound to
|
||||
/// different things depending on position in the code.
|
||||
///
|
||||
/// **Known problems:** This lint, as the other shadowing related lints, currently only catches very simple patterns.
|
||||
/// **Known problems:** This lint, as the other shadowing related lints, currently only catches
|
||||
/// very simple patterns.
|
||||
///
|
||||
/// **Example:** `let x = x + 1;`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = x + 1;
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub SHADOW_REUSE, Allow,
|
||||
"rebinding a name to an expression that re-uses the original value, e.g. \
|
||||
`let x = x + 1`"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope, either without a initialization or with one that does not even use the original value.
|
||||
/// **What it does:** This lint checks for bindings that shadow other bindings already in scope,
|
||||
/// either without a initialization or with one that does not even use the original value.
|
||||
///
|
||||
/// **Why is this bad?** Name shadowing can hurt readability, especially in large code bases, because it is easy to lose track of the active binding at any place in the code. This can be alleviated by either giving more specific names to bindings ore introducing more scopes to contain the bindings.
|
||||
/// **Why is this bad?** Name shadowing can hurt readability, especially in large code bases,
|
||||
/// because it is easy to lose track of the active binding at any place in the code. This can be
|
||||
/// alleviated by either giving more specific names to bindings ore introducing more scopes to
|
||||
/// contain the bindings.
|
||||
///
|
||||
/// **Known problems:** This lint, as the other shadowing related lints, currently only catches very simple patterns.
|
||||
/// **Known problems:** This lint, as the other shadowing related lints, currently only catches
|
||||
/// very simple patterns.
|
||||
///
|
||||
/// **Example:** `let x = y; let x = z; // shadows the earlier binding`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = y; let x = z; // shadows the earlier binding
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub SHADOW_UNRELATED, Allow,
|
||||
"The name is re-bound without even using the original value"
|
||||
|
@ -1,8 +1,3 @@
|
||||
//! This lint catches both string addition and string addition + assignment
|
||||
//!
|
||||
//! Note that since we have two lints where one subsumes the other, we try to
|
||||
//! disable the subsumed lint unless it has a higher level
|
||||
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use syntax::codemap::Spanned;
|
||||
@ -11,13 +6,14 @@ use utils::{match_type, paths, span_lint, span_lint_and_then, walk_ptrs_ty, get_
|
||||
|
||||
/// **What it does:** This lint matches code of the form `x = x + y` (without `let`!).
|
||||
///
|
||||
/// **Why is this bad?** It's not really bad, but some people think that the `.push_str(_)` method is more readable.
|
||||
/// **Why is this bad?** It's not really bad, but some people think that the `.push_str(_)` method
|
||||
/// is more readable.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let mut x = "Hello".to_owned();
|
||||
/// x = x + ", World";
|
||||
/// ```
|
||||
@ -27,17 +23,22 @@ declare_lint! {
|
||||
"using `x = x + ..` where x is a `String`; suggests using `push_str()` instead"
|
||||
}
|
||||
|
||||
/// **What it does:** The `string_add` lint matches all instances of `x + _` where `x` is of type `String`, but only if [`string_add_assign`](#string_add_assign) does *not* match.
|
||||
/// **What it does:** The `string_add` lint matches all instances of `x + _` where `x` is of type
|
||||
/// `String`, but only if [`string_add_assign`](#string_add_assign) does *not* match.
|
||||
///
|
||||
/// **Why is this bad?** It's not bad in and of itself. However, this particular `Add` implementation is asymmetric (the other operand need not be `String`, but `x` does), while addition as mathematically defined is symmetric, also the `String::push_str(_)` function is a perfectly good replacement. Therefore some dislike it and wish not to have it in their code.
|
||||
/// **Why is this bad?** It's not bad in and of itself. However, this particular `Add`
|
||||
/// implementation is asymmetric (the other operand need not be `String`, but `x` does), while
|
||||
/// addition as mathematically defined is symmetric, also the `String::push_str(_)` function is a
|
||||
/// perfectly good replacement. Therefore some dislike it and wish not to have it in their code.
|
||||
///
|
||||
/// That said, other people think that String addition, having a long tradition in other languages is actually fine, which is why we decided to make this particular lint `allow` by default.
|
||||
/// That said, other people think that string addition, having a long tradition in other languages
|
||||
/// is actually fine, which is why we decided to make this particular lint `allow` by default.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let x = "Hello".to_owned();
|
||||
/// x + ", World"
|
||||
/// ```
|
||||
@ -48,13 +49,14 @@ declare_lint! {
|
||||
}
|
||||
|
||||
/// **What it does:** This lint matches the `as_bytes` method called on string
|
||||
/// literals that contain only ascii characters.
|
||||
/// literals that contain only ASCII characters.
|
||||
///
|
||||
/// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used instead. They are shorter but less discoverable than `as_bytes()`.
|
||||
/// **Why is this bad?** Byte string literals (e.g. `b"foo"`) can be used instead. They are shorter
|
||||
/// but less discoverable than `as_bytes()`.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// let bs = "a byte string".as_bytes();
|
||||
/// ```
|
||||
declare_lint! {
|
||||
|
@ -3,13 +3,18 @@ use rustc::hir::{Expr, ExprAssign, ExprField, ExprStruct, ExprTup, ExprTupField}
|
||||
use utils::is_adjusted;
|
||||
use utils::span_lint;
|
||||
|
||||
/// **What it does:** This lint checks for construction of a structure or tuple just to assign a value in it.
|
||||
/// **What it does:** This lint checks for construction of a structure or tuple just to assign a
|
||||
/// value in it.
|
||||
///
|
||||
/// **Why is this bad?** Readability. If the structure is only created to be updated, why not write the structure you want in the first place?
|
||||
/// **Why is this bad?** Readability. If the structure is only created to be updated, why not write
|
||||
/// the structure you want in the first place?
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `(0, 0).0 = 1`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// (0, 0).0 = 1
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub TEMPORARY_ASSIGNMENT,
|
||||
Warn,
|
||||
|
@ -9,22 +9,31 @@ use utils::sugg;
|
||||
///
|
||||
/// **Why is this bad?** It's basically guaranteed to be undefined behaviour
|
||||
///
|
||||
/// **Known problems:** When accessing C, users might want to store pointer sized objects in `extradata` arguments to save an allocation.
|
||||
/// **Known problems:** When accessing C, users might want to store pointer sized objects in
|
||||
/// `extradata` arguments to save an allocation.
|
||||
///
|
||||
/// **Example:** `let ptr: *const T = core::intrinsics::transmute('x')`.
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let ptr: *const T = core::intrinsics::transmute('x')`
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub WRONG_TRANSMUTE,
|
||||
Warn,
|
||||
"transmutes that are confusing at best, undefined behaviour at worst and always useless"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for transmutes to the original type of the object and transmutes that could be a cast.
|
||||
/// **What it does:** This lint checks for transmutes to the original type of the object and
|
||||
/// transmutes that could be a cast.
|
||||
///
|
||||
/// **Why is this bad?** Readability. The code tricks people into thinking that something complex is going on
|
||||
/// **Why is this bad?** Readability. The code tricks people into thinking that something complex
|
||||
/// is going on
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `core::intrinsics::transmute(t)` where the result type is the same as `t`'s.
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// core::intrinsics::transmute(t) // where the result type is the same as `t`'s
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub USELESS_TRANSMUTE,
|
||||
Warn,
|
||||
@ -37,7 +46,10 @@ declare_lint! {
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:** `core::intrinsics::transmute(t)` where the result type is the same as `*t` or `&t`'s.
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// core::intrinsics::transmute(t)` // where the result type is the same as `*t` or `&t`'s
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub CROSSPOINTER_TRANSMUTE,
|
||||
Warn,
|
||||
|
@ -16,27 +16,44 @@ pub struct TypePass;
|
||||
|
||||
/// **What it does:** This lint checks for use of `Box<Vec<_>>` anywhere in the code.
|
||||
///
|
||||
/// **Why is this bad?** `Vec` already keeps its contents in a separate area on the heap. So if you `Box` it, you just add another level of indirection without any benefit whatsoever.
|
||||
/// **Why is this bad?** `Vec` already keeps its contents in a separate area on the heap. So if you
|
||||
/// `Box` it, you just add another level of indirection without any benefit whatsoever.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `struct X { values: Box<Vec<Foo>> }`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// struct X {
|
||||
/// values: Box<Vec<Foo>>,
|
||||
/// }
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub BOX_VEC, Warn,
|
||||
"usage of `Box<Vec<T>>`, vector elements are already on the heap"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for usage of any `LinkedList`, suggesting to use a `Vec` or a `VecDeque` (formerly called `RingBuf`).
|
||||
/// **What it does:** This lint checks for usage of any `LinkedList`, suggesting to use a `Vec` or
|
||||
/// a `VecDeque` (formerly called `RingBuf`).
|
||||
///
|
||||
/// **Why is this bad?** Gankro says:
|
||||
///
|
||||
/// >The TL;DR of `LinkedList` is that it's built on a massive amount of pointers and indirection. It wastes memory, it has terrible cache locality, and is all-around slow. `RingBuf`, while "only" amortized for push/pop, should be faster in the general case for almost every possible workload, and isn't even amortized at all if you can predict the capacity you need.
|
||||
/// > The TL;DR of `LinkedList` is that it's built on a massive amount of pointers and indirection.
|
||||
/// > It wastes memory, it has terrible cache locality, and is all-around slow. `RingBuf`, while
|
||||
/// > "only" amortized for push/pop, should be faster in the general case for almost every possible
|
||||
/// > workload, and isn't even amortized at all if you can predict the capacity you need.
|
||||
/// >
|
||||
/// > `LinkedList`s are only really good if you're doing a lot of merging or splitting of lists. This is because they can just mangle some pointers instead of actually copying the data. Even if you're doing a lot of insertion in the middle of the list, `RingBuf` can still be better because of how expensive it is to seek to the middle of a `LinkedList`.
|
||||
/// > `LinkedList`s are only really good if you're doing a lot of merging or splitting of lists.
|
||||
/// > This is because they can just mangle some pointers instead of actually copying the data. Even
|
||||
/// > if you're doing a lot of insertion in the middle of the list, `RingBuf` can still be better
|
||||
/// > because of how expensive it is to seek to the middle of a `LinkedList`.
|
||||
///
|
||||
/// **Known problems:** False positives – the instances where using a `LinkedList` makes sense are few and far between, but they can still happen.
|
||||
/// **Known problems:** False positives – the instances where using a `LinkedList` makes sense are
|
||||
/// few and far between, but they can still happen.
|
||||
///
|
||||
/// **Example:** `let x = LinkedList::new();`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = LinkedList::new();
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub LINKEDLIST, Warn,
|
||||
"usage of LinkedList, usually a vector is faster, or a more specialized data \
|
||||
|
@ -5,9 +5,10 @@ use syntax::codemap::Span;
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
use utils::{snippet, span_help_and_lint};
|
||||
|
||||
/// **What it does:** This lint checks for the unicode zero-width space in the code.
|
||||
/// **What it does:** This lint checks for the Unicode zero-width space in the code.
|
||||
///
|
||||
/// **Why is this bad?** Having an invisible character in the code makes for all sorts of April fools, but otherwise is very much frowned upon.
|
||||
/// **Why is this bad?** Having an invisible character in the code makes for all sorts of April
|
||||
/// fools, but otherwise is very much frowned upon.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
@ -17,26 +18,34 @@ declare_lint! {
|
||||
"using a zero-width space in a string literal, which is confusing"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for non-ascii characters in string literals.
|
||||
/// **What it does:** This lint checks for non-ASCII characters in string literals.
|
||||
///
|
||||
/// **Why is this bad?** Yeah, we know, the 90's called and wanted their charset back. Even so, there still are editors and other programs out there that don't work well with unicode. So if the code is meant to be used internationally, on multiple operating systems, or has other portability requirements, activating this lint could be useful.
|
||||
/// **Why is this bad?** Yeah, we know, the 90's called and wanted their charset back. Even so,
|
||||
/// there still are editors and other programs out there that don't work well with Unicode. So if
|
||||
/// the code is meant to be used internationally, on multiple operating systems, or has other
|
||||
/// portability requirements, activating this lint could be useful.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:** `let x = "Hä?"`
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let x = "Hä?"
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub NON_ASCII_LITERAL, Allow,
|
||||
"using any literal non-ASCII chars in a string literal; suggests \
|
||||
using the \\u escape instead"
|
||||
using the `\\u` escape instead"
|
||||
}
|
||||
|
||||
/// **What it does:** This lint checks for string literals that contain unicode in a form that is not equal to its [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms).
|
||||
/// **What it does:** This lint checks for string literals that contain Unicode in a form that is
|
||||
/// not equal to its [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms).
|
||||
///
|
||||
/// **Why is this bad?** If such a string is compared to another, the results may be surprising.
|
||||
///
|
||||
/// **Known problems** None
|
||||
///
|
||||
/// **Example:** You may not see it, but "à" and "à" aren't the same string. The former when escaped is actually "a\u{300}" while the latter is "\u{e0}".
|
||||
/// **Example:** You may not see it, but “à” and “à” aren't the same string. The former when
|
||||
/// escaped is actually `"a\u{300}"` while the latter is `"\u{e0}"`.
|
||||
declare_lint! {
|
||||
pub UNICODE_NOT_NFC, Allow,
|
||||
"using a unicode literal not in NFC normal form (see \
|
||||
|
@ -14,7 +14,10 @@ pub struct Pass;
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example** `0.0f32 / 0.0`
|
||||
/// **Example**
|
||||
/// ```rust
|
||||
/// 0.0f32 / 0.0
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub ZERO_DIVIDED_BY_ZERO,
|
||||
Warn,
|
||||
|
Loading…
Reference in New Issue
Block a user