Added &String matching and renamed to vec_ptr_arg to ptr_arg, also added README section

This commit is contained in:
llogiq 2015-05-04 08:15:24 +02:00
parent 07adeee6e9
commit 8d2328d9a5
5 changed files with 37 additions and 25 deletions

View file

@ -14,6 +14,9 @@ Lints included in this crate:
- `eq_op`: Warns on equal operands on both sides of a comparison or bitwise combination - `eq_op`: Warns on equal operands on both sides of a comparison or bitwise combination
- `bad_bit_mask`: Denies expressions of the form `_ & mask == select` that will only ever return `true` or `false` (because in the example `select` containing bits that `mask` doesn't have) - `bad_bit_mask`: Denies expressions of the form `_ & mask == select` that will only ever return `true` or `false` (because in the example `select` containing bits that `mask` doesn't have)
- `needless_bool` : Warns on if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }` - `needless_bool` : Warns on if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`
- `ptr_arg`: Warns on fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively
In your code, you may add `#![plugin(clippy)]` to use it (you may also need to include a `#![feature(plugin)]` line)
You can allow/warn/deny the whole set using the `clippy` lint group (`#[allow(clippy)]`, etc) You can allow/warn/deny the whole set using the `clippy` lint group (`#[allow(clippy)]`, etc)

View file

@ -18,8 +18,8 @@ pub mod types;
pub mod misc; pub mod misc;
pub mod eq_op; pub mod eq_op;
pub mod bit_mask; pub mod bit_mask;
pub mod ptr_arg;
pub mod needless_bool; pub mod needless_bool;
pub mod vec_ptr_arg;
#[plugin_registrar] #[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) { pub fn plugin_registrar(reg: &mut Registry) {
@ -29,14 +29,13 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_lint_pass(box misc::TopLevelRefPass as LintPassObject); reg.register_lint_pass(box misc::TopLevelRefPass as LintPassObject);
reg.register_lint_pass(box eq_op::EqOp as LintPassObject); reg.register_lint_pass(box eq_op::EqOp as LintPassObject);
reg.register_lint_pass(box bit_mask::BitMask as LintPassObject); reg.register_lint_pass(box bit_mask::BitMask as LintPassObject);
reg.register_lint_pass(box ptr_arg::PtrArg as LintPassObject);
reg.register_lint_pass(box needless_bool::NeedlessBool as LintPassObject); reg.register_lint_pass(box needless_bool::NeedlessBool as LintPassObject);
reg.register_lint_pass(box vec_ptr_arg::VecPtrArg as LintPassObject);
reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST, reg.register_lint_group("clippy", vec![types::BOX_VEC, types::LINKEDLIST,
misc::SINGLE_MATCH, misc::STR_TO_STRING, misc::SINGLE_MATCH, misc::STR_TO_STRING,
misc::TOPLEVEL_REF_ARG, eq_op::EQ_OP, misc::TOPLEVEL_REF_ARG, eq_op::EQ_OP,
bit_mask::BAD_BIT_MASK, bit_mask::BAD_BIT_MASK, ptr_arg::PTR_ARG,
needless_bool::NEEDLESS_BOOL, needless_bool::NEEDLESS_BOOL
vec_ptr_arg::VEC_PTR_ARG
]); ]);
} }

View file

@ -13,18 +13,18 @@ use syntax::codemap::Span;
use types::match_ty_unwrap; use types::match_ty_unwrap;
declare_lint! { declare_lint! {
pub VEC_PTR_ARG, pub PTR_ARG,
Allow, Allow,
"Warn on declaration of a &Vec-typed method argument" "Warn on declaration of a &Vec- or &String-typed method argument"
} }
#[derive(Copy,Clone)] #[derive(Copy,Clone)]
pub struct VecPtrArg; pub struct PtrArg;
impl LintPass for VecPtrArg { impl LintPass for PtrArg {
fn get_lints(&self) -> LintArray { fn get_lints(&self) -> LintArray {
lint_array!(VEC_PTR_ARG) lint_array!(PTR_ARG)
} }
fn check_item(&mut self, cx: &Context, item: &Item) { fn check_item(&mut self, cx: &Context, item: &Item) {
@ -59,7 +59,11 @@ fn check_fn(cx: &Context, decl: &FnDecl) {
fn check_ptr_subtype(cx: &Context, span: Span, ty: &Ty) { fn check_ptr_subtype(cx: &Context, span: Span, ty: &Ty) {
if match_ty_unwrap(ty, &["Vec"]).is_some() { if match_ty_unwrap(ty, &["Vec"]).is_some() {
cx.span_lint(VEC_PTR_ARG, span, cx.span_lint(PTR_ARG, span,
"Writing '&Vec<_>' instead of '&[_]' involves one more reference and cannot be used with non-vec-based slices. Consider changing the type to &[...]"); "Writing '&Vec<_>' instead of '&[_]' involves one more reference and cannot be used with non-vec-based slices. Consider changing the type to &[...]");
} else { if match_ty_unwrap(ty, &["String"]).is_some() {
cx.span_lint(PTR_ARG, span,
"Writing '&String' instead of '&str' involves a new Object where a slices will do. Consider changing the type to &str");
}
} }
} }

View file

@ -0,0 +1,20 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(ptr_arg)]
#[allow(unused)]
fn do_vec(x: &Vec<i64>) { //~ERROR: Writing '&Vec<_>' instead of '&[_]'
//Nothing here
}
#[deny(ptr_arg)]
#[allow(unused)]
fn do_str(x: &String) { //~ERROR
//Nothing here either
}
fn main() {
let x = vec![1i64, 2, 3];
do_vec(&x);
do_str(&"hello".to_owned());
}

View file

@ -1,14 +0,0 @@
#![feature(plugin)]
#![plugin(clippy)]
#[deny(vec_ptr_arg)]
#[allow(unused)]
fn go(x: &Vec<i64>) { //~ERROR: Writing '&Vec<_>' instead of '&[_]'
//Nothing here
}
fn main() {
let x = vec![1i64, 2, 3];
go(&x);
}