parent
bbc917fef0
commit
98d24b5b56
@ -39,7 +39,13 @@ declare_lint! {
|
||||
/// This lint is **deny** by default
|
||||
///
|
||||
/// There is also a lint that warns on ineffective masks that is *warn*
|
||||
/// by default
|
||||
/// by default.
|
||||
///
|
||||
/// |Comparison|Bit-Op |Example |equals |Formula|
|
||||
/// |`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|`¹ && m <= c`|
|
||||
/// |`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|`¹ && m < c` |
|
||||
///
|
||||
/// `¹ power_of_two(c + 1)`
|
||||
#[derive(Copy,Clone)]
|
||||
pub struct BitMask;
|
||||
|
||||
@ -127,12 +133,10 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
||||
"incompatible bit mask: `_ | {}` will never be lower than `{}`",
|
||||
mask_value, cmp_value));
|
||||
} else {
|
||||
if mask_value < cmp_value {
|
||||
span_lint(cx, INEFFECTIVE_BIT_MASK, *span, &format!(
|
||||
"ineffective bit mask: `x | {}` compared to `{}` is the same as x compared directly",
|
||||
mask_value, cmp_value));
|
||||
}
|
||||
check_ineffective_lt(cx, *span, mask_value, cmp_value, "|");
|
||||
},
|
||||
BiBitXor =>
|
||||
check_ineffective_lt(cx, *span, mask_value, cmp_value, "^"),
|
||||
_ => ()
|
||||
},
|
||||
BiLe | BiGt => match bit_op {
|
||||
@ -151,18 +155,32 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
||||
"incompatible bit mask: `_ | {}` will always be higher than `{}`",
|
||||
mask_value, cmp_value));
|
||||
} else {
|
||||
if mask_value < cmp_value {
|
||||
span_lint(cx, INEFFECTIVE_BIT_MASK, *span, &format!(
|
||||
"ineffective bit mask: `x | {}` compared to `{}` is the same as x compared directly",
|
||||
mask_value, cmp_value));
|
||||
}
|
||||
check_ineffective_gt(cx, *span, mask_value, cmp_value, "|");
|
||||
},
|
||||
BiBitXor =>
|
||||
check_ineffective_gt(cx, *span, mask_value, cmp_value, "^"),
|
||||
_ => ()
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ineffective_lt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||
if c.is_power_of_two() && m < c {
|
||||
span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
||||
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
||||
op, m, c));
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ineffective_gt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||
if (c + 1).is_power_of_two() && m <= c {
|
||||
span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
||||
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
||||
op, m, c));
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_int_literal(cx: &Context, lit : &Expr) -> Option<u64> {
|
||||
match &lit.node {
|
||||
&ExprLit(ref lit_ptr) => {
|
||||
|
@ -46,8 +46,13 @@ fn main() {
|
||||
fn ineffective() {
|
||||
let x = 5;
|
||||
|
||||
x | 1 > 2; //~ERROR ineffective bit mask
|
||||
x | 1 < 3; //~ERROR ineffective bit mask
|
||||
x | 1 > 3; //~ERROR ineffective bit mask
|
||||
x | 1 < 4; //~ERROR ineffective bit mask
|
||||
x | 1 <= 3; //~ERROR ineffective bit mask
|
||||
x | 1 >= 2; //~ERROR ineffective bit mask
|
||||
x | 1 >= 8; //~ERROR ineffective bit mask
|
||||
|
||||
x | 1 > 2; // not an error (yet), better written as x >= 2
|
||||
x | 1 >= 7; // not an error (yet), better written as x >= 6
|
||||
x | 3 > 4; // not an error (yet), better written as x >= 4
|
||||
x | 4 <= 19;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user