diff --git a/README.md b/README.md index 271b19a18cf..87339f46464 100644 --- a/README.md +++ b/README.md @@ -86,5 +86,12 @@ You can add options to `allow`/`warn`/`deny`: *`deny` produces error instead of warnings* +To have cargo compile your crate with clippy without needing `#![plugin(clippy)]` +in your code, you can use: + +``` +cargo rustc -- -L /path/to/clippy_so -Z extra-plugins=clippy +``` + ##License Licensed under [MPL](https://www.mozilla.org/MPL/2.0/). If you're having issues with the license, let me know and I'll try to change it to something more permissive. diff --git a/src/eta_reduction.rs b/src/eta_reduction.rs index b89eef8c8bb..17dac5930c4 100644 --- a/src/eta_reduction.rs +++ b/src/eta_reduction.rs @@ -18,7 +18,7 @@ impl LintPass for EtaPass { fn check_expr(&mut self, cx: &Context, expr: &Expr) { if let ExprClosure(_, ref decl, ref blk) = expr.node { - if blk.stmts.len() != 0 { + if !blk.stmts.is_empty() { // || {foo(); bar()}; can't be reduced here return; } diff --git a/src/len_zero.rs b/src/len_zero.rs index f2fe21f88ff..35e11dfdcb9 100644 --- a/src/len_zero.rs +++ b/src/len_zero.rs @@ -5,7 +5,7 @@ use std::cell::RefCell; use syntax::ptr::P; use rustc::lint::{Context, LintPass, LintArray, Lint}; use rustc::util::nodemap::DefIdMap; -use rustc::middle::ty::{self, TypeVariants, mt, MethodTraitItemId, ImplOrTraitItemId}; +use rustc::middle::ty::{self, TypeVariants, TypeAndMut, MethodTraitItemId, ImplOrTraitItemId}; use rustc::middle::def::{DefTy, DefStruct, DefTrait}; use syntax::codemap::{Span, Spanned}; use syntax::ast::*; diff --git a/src/misc.rs b/src/misc.rs index ffa16543f25..da2df2cc820 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -36,8 +36,8 @@ impl LintPass for MiscPass { if arms.len() == 2 { if arms[0].guard.is_none() && arms[1].pats.len() == 1 { match arms[1].body.node { - ExprTup(ref v) if v.len() == 0 && arms[1].guard.is_none() => (), - ExprBlock(ref b) if b.stmts.len() == 0 && arms[1].guard.is_none() => (), + ExprTup(ref v) if v.is_empty() && arms[1].guard.is_none() => (), + ExprBlock(ref b) if b.stmts.is_empty() && arms[1].guard.is_none() => (), _ => return } // In some cases, an exhaustive match is preferred to catch situations when diff --git a/src/mut_mut.rs b/src/mut_mut.rs index 10888d99075..cfa040ddb04 100644 --- a/src/mut_mut.rs +++ b/src/mut_mut.rs @@ -1,7 +1,7 @@ use syntax::ptr::P; use syntax::ast::*; use rustc::lint::{Context, LintPass, LintArray, Lint}; -use rustc::middle::ty::{TypeVariants, mt, TyRef}; +use rustc::middle::ty::{TypeVariants, TypeAndMut, TyRef}; use syntax::codemap::{BytePos, ExpnInfo, Span}; use utils::in_macro; @@ -42,7 +42,7 @@ fn check_expr_expd(cx: &Context, expr: &Expr, info: Option<&ExpnInfo>) { cx.span_lint(MUT_MUT, expr.span, "Generally you want to avoid &mut &mut _ if possible.") }).unwrap_or_else(|| { - if let TyRef(_, mt{ty: _, mutbl: MutMutable}) = + if let TyRef(_, TypeAndMut{ty: _, mutbl: MutMutable}) = cx.tcx.expr_ty(e).sty { cx.span_lint(MUT_MUT, expr.span, "This expression mutably borrows a mutable reference. \ diff --git a/src/needless_bool.rs b/src/needless_bool.rs index fe35e6ee3bd..9b52771d8af 100644 --- a/src/needless_bool.rs +++ b/src/needless_bool.rs @@ -10,6 +10,7 @@ use syntax::ast::*; use syntax::ast_util::{is_comparison_binop, binop_to_string}; use syntax::ptr::P; use syntax::codemap::Span; +use utils::de_p; declare_lint! { pub NEEDLESS_BOOL, @@ -28,10 +29,18 @@ impl LintPass for NeedlessBool { fn check_expr(&mut self, cx: &Context, e: &Expr) { if let ExprIf(_, ref then_block, Option::Some(ref else_expr)) = e.node { match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) { - (Option::Some(true), Option::Some(true)) => { cx.span_lint(NEEDLESS_BOOL, e.span, "your if-then-else expression will always return true"); }, - (Option::Some(true), Option::Some(false)) => { cx.span_lint(NEEDLESS_BOOL, e.span, "you can reduce your if-statement to its predicate"); }, - (Option::Some(false), Option::Some(true)) => { cx.span_lint(NEEDLESS_BOOL, e.span, "you can reduce your if-statement to '!' + your predicate"); }, - (Option::Some(false), Option::Some(false)) => { cx.span_lint(NEEDLESS_BOOL, e.span, "your if-then-else expression will always return false"); }, + (Option::Some(true), Option::Some(true)) => { + cx.span_lint(NEEDLESS_BOOL, e.span, + "your if-then-else expression will always return true"); }, + (Option::Some(true), Option::Some(false)) => { + cx.span_lint(NEEDLESS_BOOL, e.span, + "you can reduce your if-statement to its predicate"); }, + (Option::Some(false), Option::Some(true)) => { + cx.span_lint(NEEDLESS_BOOL, e.span, + "you can reduce your if-statement to '!' + your predicate"); }, + (Option::Some(false), Option::Some(false)) => { + cx.span_lint(NEEDLESS_BOOL, e.span, + "your if-then-else expression will always return false"); }, _ => () } } @@ -39,7 +48,9 @@ impl LintPass for NeedlessBool { } fn fetch_bool_block(block: &Block) -> Option { - if block.stmts.is_empty() { block.expr.as_ref().and_then(|e| fetch_bool_expr(e)) } else { Option::None } + if block.stmts.is_empty() { + block.expr.as_ref().map(de_p).and_then(fetch_bool_expr) + } else { Option::None } } fn fetch_bool_expr(expr: &Expr) -> Option { diff --git a/src/utils.rs b/src/utils.rs index 7d61316367b..065c20717a1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,7 @@ use rustc::lint::Context; use syntax::ast::{DefId, Name, Path}; use syntax::codemap::{ExpnInfo, Span}; +use syntax::ptr::P; use rustc::middle::ty; use std::borrow::{Cow, IntoCow}; use std::convert::From; @@ -48,3 +49,6 @@ pub fn match_path(path: &Path, segments: &[&str]) -> bool { pub fn snippet<'a>(cx: &Context, span: Span, default: &'a str) -> Cow<'a, str> { cx.sess().codemap().span_to_snippet(span).map(From::from).unwrap_or(Cow::Borrowed(default)) } + +/// dereference a P and return a ref on the result +pub fn de_p(p: &P) -> &T { &*p }