New lint: precedence, see issue #41
This commit is contained in:
parent
ac151bb1f0
commit
17bcf0e865
4 changed files with 63 additions and 1 deletions
|
|
@ -35,6 +35,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
reg.register_lint_pass(box needless_bool::NeedlessBool as LintPassObject);
|
||||
reg.register_lint_pass(box approx_const::ApproxConstant as LintPassObject);
|
||||
reg.register_lint_pass(box misc::FloatCmp as LintPassObject);
|
||||
reg.register_lint_pass(box misc::Precedence as LintPassObject);
|
||||
|
||||
reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST,
|
||||
misc::SINGLE_MATCH, misc::STR_TO_STRING,
|
||||
|
|
@ -43,5 +44,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
needless_bool::NEEDLESS_BOOL,
|
||||
approx_const::APPROX_CONSTANT,
|
||||
misc::CMP_NAN, misc::FLOAT_CMP,
|
||||
misc::PRECEDENCE,
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
46
src/misc.rs
46
src/misc.rs
|
|
@ -5,7 +5,7 @@ use syntax::ast_util::{is_comparison_binop, binop_to_string};
|
|||
use syntax::visit::{FnKind};
|
||||
use rustc::lint::{Context, LintPass, LintArray, Lint, Level};
|
||||
use rustc::middle::ty::{self, expr_ty, ty_str, ty_ptr, ty_rptr, ty_float};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap::{Span, Spanned};
|
||||
|
||||
|
||||
use types::span_note_and_lint;
|
||||
|
|
@ -169,3 +169,47 @@ impl LintPass for FloatCmp {
|
|||
fn is_float(cx: &Context, expr: &Expr) -> bool {
|
||||
if let ty_float(_) = walk_ty(expr_ty(cx.tcx, expr)).sty { true } else { false }
|
||||
}
|
||||
|
||||
declare_lint!(pub PRECEDENCE, Warn,
|
||||
"Warn on mixing bit ops with integer arithmetic without parenthesis");
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
pub struct Precedence;
|
||||
|
||||
impl LintPass for Precedence {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(PRECEDENCE)
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node {
|
||||
if is_bit_op(op) {
|
||||
if let ExprBinary(Spanned { node: lop, ..}, _, _) = left.node {
|
||||
if is_arith_op(lop) {
|
||||
cx.span_lint(PRECEDENCE, expr.span, "Operator precedence can trip the unwary. Please consider adding parenthesis to the subexpression to make the meaning more clear.");
|
||||
}
|
||||
} else {
|
||||
if let ExprBinary(Spanned { node: rop, ..}, _, _) = right.node {
|
||||
if is_arith_op(rop) {
|
||||
cx.span_lint(PRECEDENCE, expr.span, "Operator precedence can trip the unwary. Please consider adding parenthesis to the subexpression to make the meaning more clear.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_bit_op(op : BinOp_) -> bool {
|
||||
match op {
|
||||
BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_arith_op(op : BinOp_) -> bool {
|
||||
match op {
|
||||
BiAdd | BiSub | BiMul | BiDiv | BiRem => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue