Use the authoring tool to create a new lint

This commit is contained in:
Oliver Schneider 2017-07-03 16:07:04 +02:00
parent 3a61b452a2
commit 7102442a4b
No known key found for this signature in database
GPG Key ID: A69F8D225B3AD7D9
5 changed files with 76 additions and 5 deletions

View File

@ -4,7 +4,8 @@ use rustc::lint::*;
use rustc_const_eval::lookup_const_by_id;
use syntax::ast::LitKind;
use syntax::codemap::Span;
use utils::span_lint;
use utils::{span_lint, span_lint_and_then};
use utils::sugg::Sugg;
/// **What it does:** Checks for incompatible bit masks in comparisons.
///
@ -70,12 +71,29 @@ declare_lint! {
"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:** None
///
/// **Example:**
/// ```rust
/// x & 0x1111 == 0
/// ```
declare_lint! {
pub VERBOSE_BIT_MASK,
Warn,
"expressions where a bit mask is less readable than the corresponding method call"
}
#[derive(Copy,Clone)]
pub struct BitMask;
impl LintPass for BitMask {
fn get_lints(&self) -> LintArray {
lint_array!(BAD_BIT_MASK, INEFFECTIVE_BIT_MASK)
lint_array!(BAD_BIT_MASK, INEFFECTIVE_BIT_MASK, VERBOSE_BIT_MASK)
}
}
@ -90,6 +108,26 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BitMask {
}
}
}
if_let_chain!{[
let Expr_::ExprBinary(ref op, ref left, ref right) = e.node,
BinOp_::BiEq == op.node,
let Expr_::ExprBinary(ref op1, ref left1, ref right1) = left.node,
BinOp_::BiBitAnd == op1.node,
let Expr_::ExprLit(ref lit) = right1.node,
let LitKind::Int(n, _) = lit.node,
let Expr_::ExprLit(ref lit1) = right.node,
let LitKind::Int(0, _) = lit1.node,
n.leading_zeros() == n.count_zeros(),
], {
span_lint_and_then(cx,
VERBOSE_BIT_MASK,
e.span,
"bit mask could be simplified with a call to `trailing_zeros`",
|db| {
let sugg = Sugg::hir(cx, left1, "...").maybe_par();
db.span_suggestion(e.span, "try", format!("{}.trailing_zeros() > {}", sugg, n.count_ones()));
});
}}
}
}

View File

@ -380,6 +380,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
attrs::USELESS_ATTRIBUTE,
bit_mask::BAD_BIT_MASK,
bit_mask::INEFFECTIVE_BIT_MASK,
bit_mask::VERBOSE_BIT_MASK,
blacklisted_name::BLACKLISTED_NAME,
block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,
block_in_if_condition::BLOCK_IN_IF_CONDITION_STMT,

View File

@ -6,6 +6,20 @@ error: &-masking with zero
|
= note: `-D bad-bit-mask` implied by `-D warnings`
error: bit mask could be simplified with a call to `trailing_zeros`
--> bit_masks.rs:12:5
|
12 | x & 0 == 0;
| ^^^^^^^^^^ help: try `x.trailing_zeros() > 0`
|
= note: `-D verbose-bit-mask` implied by `-D warnings`
error: bit mask could be simplified with a call to `trailing_zeros`
--> bit_masks.rs:14:5
|
14 | x & 1 == 0; //ok, compared with zero
| ^^^^^^^^^^ help: try `x.trailing_zeros() > 1`
error: incompatible bit mask: `_ & 2` can never be equal to `1`
--> bit_masks.rs:15:5
|
@ -92,7 +106,7 @@ error: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared
55 | x | 1 >= 8;
| ^^^^^^^^^^
error: aborting due to 15 previous errors
error: aborting due to 17 previous errors
To learn more, run the command again with --verbose.

View File

@ -0,0 +1,18 @@
error: bit mask could be simplified with a call to `trailing_zeros`
--> trailing_zeros.rs:7:31
|
7 | let _ = #[clippy(author)] (x & 0b1111 == 0); // suggest trailing_zeros
| ^^^^^^^^^^^^^^^^^ help: try `x.trailing_zeros() > 4`
|
= note: `-D verbose-bit-mask` implied by `-D warnings`
error: bit mask could be simplified with a call to `trailing_zeros`
--> trailing_zeros.rs:8:13
|
8 | let _ = x & 0b11111 == 0; // suggest trailing_zeros
| ^^^^^^^^^^^^^^^^ help: try `x.trailing_zeros() > 5`
error: aborting due to 2 previous errors
To learn more, run the command again with --verbose.

View File

@ -9,6 +9,6 @@ if_let_chain!{[
let LitKind::Int(15, _) = lit.node,
let Expr_::ExprLit(ref lit1) = right.node,
let LitKind::Int(0, _) = lit1.node,
]} {
], {
// report your lint here
}
}}