Use the authoring tool to create a new lint
This commit is contained in:
parent
3a61b452a2
commit
7102442a4b
@ -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()));
|
||||
});
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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.
|
@ -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
|
||||
}
|
||||
}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user