Implement lint 'suspicious_map'

This commit is contained in:
Jeremy Stucki 2019-08-15 22:56:16 +02:00
parent f95c87ecea
commit f4f31a4ff4
No known key found for this signature in database
GPG key ID: 8F548A5A2ED13F58
5 changed files with 39 additions and 2 deletions

View file

@ -1152,6 +1152,7 @@ Released 2018-09-13
[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl [`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl
[`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_assignment_formatting [`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_assignment_formatting
[`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting [`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting
[`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map
[`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl [`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl
[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment [`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment
[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr [`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr

View file

@ -6,7 +6,7 @@
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
[There are 309 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) [There are 310 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:

View file

@ -657,6 +657,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
methods::OPTION_MAP_UNWRAP_OR, methods::OPTION_MAP_UNWRAP_OR,
methods::OPTION_MAP_UNWRAP_OR_ELSE, methods::OPTION_MAP_UNWRAP_OR_ELSE,
methods::RESULT_MAP_UNWRAP_OR_ELSE, methods::RESULT_MAP_UNWRAP_OR_ELSE,
methods::SUSPICIOUS_MAP,
misc::USED_UNDERSCORE_BINDING, misc::USED_UNDERSCORE_BINDING,
misc_early::UNSEPARATED_LITERAL_SUFFIX, misc_early::UNSEPARATED_LITERAL_SUFFIX,
mut_mut::MUT_MUT, mut_mut::MUT_MUT,

View file

@ -889,6 +889,23 @@ declare_clippy_lint! {
"using `.into_iter()` on a reference" "using `.into_iter()` on a reference"
} }
declare_clippy_lint! {
/// **What it does:** Checks for calls to `map` followed by a `count`.
///
/// **Why is this bad?** It looks suspicious. Maybe `map` was confused with `filter`.
///
/// **Known problems:** None
///
/// **Example:**
///
/// ```rust
/// let _ = (0..3).map(|x| x + 2).count();
/// ```
pub SUSPICIOUS_MAP,
pedantic,
"suspicious usage of map"
}
declare_lint_pass!(Methods => [ declare_lint_pass!(Methods => [
OPTION_UNWRAP_USED, OPTION_UNWRAP_USED,
RESULT_UNWRAP_USED, RESULT_UNWRAP_USED,
@ -927,6 +944,7 @@ declare_lint_pass!(Methods => [
UNNECESSARY_FILTER_MAP, UNNECESSARY_FILTER_MAP,
INTO_ITER_ON_ARRAY, INTO_ITER_ON_ARRAY,
INTO_ITER_ON_REF, INTO_ITER_ON_REF,
SUSPICIOUS_MAP,
]); ]);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
@ -972,6 +990,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]), ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]),
["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0]), ["fold", ..] => lint_unnecessary_fold(cx, expr, arg_lists[0]),
["filter_map", ..] => unnecessary_filter_map::lint(cx, expr, arg_lists[0]), ["filter_map", ..] => unnecessary_filter_map::lint(cx, expr, arg_lists[0]),
["count", "map"] => lint_suspicious_map(cx, expr),
_ => {}, _ => {},
} }
@ -2519,6 +2538,15 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_
} }
} }
fn lint_suspicious_map(cx: &LateContext<'_, '_>, expr: &hir::Expr) {
span_lint(
cx,
SUSPICIOUS_MAP,
expr.span,
"Make sure you did not confuse `map` with `filter`.",
);
}
/// Given a `Result<T, E>` type, return its error type (`E`). /// Given a `Result<T, E>` type, return its error type (`E`).
fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option<Ty<'a>> { fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option<Ty<'a>> {
if let ty::Adt(_, substs) = ty.sty { if let ty::Adt(_, substs) = ty.sty {

View file

@ -6,7 +6,7 @@ pub use lint::Lint;
pub use lint::LINT_LEVELS; pub use lint::LINT_LEVELS;
// begin lint list, do not remove this comment, its used in `update_lints` // begin lint list, do not remove this comment, its used in `update_lints`
pub const ALL_LINTS: [Lint; 309] = [ pub const ALL_LINTS: [Lint; 310] = [
Lint { Lint {
name: "absurd_extreme_comparisons", name: "absurd_extreme_comparisons",
group: "correctness", group: "correctness",
@ -1736,6 +1736,13 @@ pub const ALL_LINTS: [Lint; 309] = [
deprecation: None, deprecation: None,
module: "formatting", module: "formatting",
}, },
Lint {
name: "suspicious_map",
group: "pedantic",
desc: "suspicious usage of map",
deprecation: None,
module: "methods",
},
Lint { Lint {
name: "suspicious_op_assign_impl", name: "suspicious_op_assign_impl",
group: "correctness", group: "correctness",