Merge pull request #202 from birkenfeld/unit_cmp
new lint: comparing unit types (fixes #201)
This commit is contained in:
commit
bbc917fef0
@ -45,6 +45,7 @@ string_add | allow | using `x + ..` where x is a `String`; suggests
|
||||
string_add_assign | allow | using `x = x + ..` where x is a `String`; suggests using `push_str()` instead
|
||||
string_to_string | warn | calling `String.to_string()` which is a no-op
|
||||
toplevel_ref_arg | warn | a function argument is declared `ref` (i.e. `fn foo(ref x: u8)`, but not `fn foo((ref x, ref y): (u8, u8))`)
|
||||
unit_cmp | warn | comparing unit values (which is always `true` or `false`, respectively)
|
||||
zero_width_space | deny | using a zero-width space in a string literal, which is confusing
|
||||
|
||||
To use, add the following lines to your Cargo.toml:
|
||||
|
@ -64,6 +64,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_lint_pass(box returns::ReturnPass as LintPassObject);
|
||||
reg.register_lint_pass(box methods::MethodsPass as LintPassObject);
|
||||
reg.register_lint_pass(box types::LetPass as LintPassObject);
|
||||
reg.register_lint_pass(box types::UnitCmp as LintPassObject);
|
||||
reg.register_lint_pass(box loops::LoopsPass as LintPassObject);
|
||||
reg.register_lint_pass(box lifetimes::LifetimePass as LintPassObject);
|
||||
reg.register_lint_pass(box ranges::StepByZero as LintPassObject);
|
||||
@ -105,6 +106,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||
types::BOX_VEC,
|
||||
types::LET_UNIT_VALUE,
|
||||
types::LINKEDLIST,
|
||||
types::UNIT_CMP,
|
||||
unicode::NON_ASCII_LITERAL,
|
||||
unicode::ZERO_WIDTH_SPACE,
|
||||
]);
|
||||
|
29
src/types.rs
29
src/types.rs
@ -1,6 +1,7 @@
|
||||
use rustc::lint::*;
|
||||
use syntax::ast;
|
||||
use syntax::ast::*;
|
||||
use syntax::ast_util::{is_comparison_binop, binop_to_string};
|
||||
use syntax::ptr::P;
|
||||
use rustc::middle::ty;
|
||||
use syntax::codemap::ExpnInfo;
|
||||
@ -107,3 +108,31 @@ impl LintPass for LetPass {
|
||||
|info| check_let_unit(cx, decl, info));
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint!(pub UNIT_CMP, Warn,
|
||||
"comparing unit values (which is always `true` or `false`, respectively)");
|
||||
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub struct UnitCmp;
|
||||
|
||||
impl LintPass for UnitCmp {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(UNIT_CMP)
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
if let ExprBinary(ref cmp, ref left, _) = expr.node {
|
||||
let op = cmp.node;
|
||||
let sty = &cx.tcx.expr_ty(left).sty;
|
||||
if *sty == ty::TyTuple(vec![]) && is_comparison_binop(op) {
|
||||
let result = match op {
|
||||
BiEq | BiLe | BiGe => "true",
|
||||
_ => "false"
|
||||
};
|
||||
span_lint(cx, UNIT_CMP, expr.span, &format!(
|
||||
"{}-comparison of unit values detected. This will always be {}",
|
||||
binop_to_string(op), result));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
tests/compile-fail/unit_cmp.rs
Executable file
17
tests/compile-fail/unit_cmp.rs
Executable file
@ -0,0 +1,17 @@
|
||||
#![feature(plugin)]
|
||||
#![plugin(clippy)]
|
||||
|
||||
#![deny(unit_cmp)]
|
||||
|
||||
fn main() {
|
||||
// this is fine
|
||||
if true == false {
|
||||
}
|
||||
|
||||
// this warns
|
||||
if { true; } == { false; } { //~ERROR ==-comparison of unit values detected. This will always be true
|
||||
}
|
||||
|
||||
if { true; } > { false; } { //~ERROR >-comparison of unit values detected. This will always be false
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user