@@ -18,7 +18,6 @@ use syntax::ast;
1818use syntax:: source_map:: Span ;
1919use syntax:: symbol:: LocalInternedString ;
2020
21- use crate :: utils:: paths;
2221use crate :: utils:: sugg;
2322use crate :: utils:: usage:: mutated_variables;
2423use crate :: utils:: {
@@ -28,6 +27,7 @@ use crate::utils::{
2827 snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_sugg,
2928 span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq ,
3029} ;
30+ use crate :: utils:: { paths, span_help_and_lint} ;
3131
3232declare_clippy_lint ! {
3333 /// **What it does:** Checks for `.unwrap()` calls on `Option`s.
@@ -889,6 +889,24 @@ declare_clippy_lint! {
889889 "using `.into_iter()` on a reference"
890890}
891891
892+ declare_clippy_lint ! {
893+ /// **What it does:** Checks for calls to `map` followed by a `count`.
894+ ///
895+ /// **Why is this bad?** It looks suspicious. Maybe `map` was confused with `filter`.
896+ /// If the `map` call is intentional, this should be rewritten.
897+ ///
898+ /// **Known problems:** None
899+ ///
900+ /// **Example:**
901+ ///
902+ /// ```rust
903+ /// let _ = (0..3).map(|x| x + 2).count();
904+ /// ```
905+ pub SUSPICIOUS_MAP ,
906+ complexity,
907+ "suspicious usage of map"
908+ }
909+
892910declare_lint_pass ! ( Methods => [
893911 OPTION_UNWRAP_USED ,
894912 RESULT_UNWRAP_USED ,
@@ -927,6 +945,7 @@ declare_lint_pass!(Methods => [
927945 UNNECESSARY_FILTER_MAP ,
928946 INTO_ITER_ON_ARRAY ,
929947 INTO_ITER_ON_REF ,
948+ SUSPICIOUS_MAP ,
930949] ) ;
931950
932951impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Methods {
@@ -972,6 +991,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
972991 [ "as_mut" ] => lint_asref ( cx, expr, "as_mut" , arg_lists[ 0 ] ) ,
973992 [ "fold" , ..] => lint_unnecessary_fold ( cx, expr, arg_lists[ 0 ] ) ,
974993 [ "filter_map" , ..] => unnecessary_filter_map:: lint ( cx, expr, arg_lists[ 0 ] ) ,
994+ [ "count" , "map" ] => lint_suspicious_map ( cx, expr) ,
975995 _ => { } ,
976996 }
977997
@@ -2519,6 +2539,16 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_
25192539 }
25202540}
25212541
2542+ fn lint_suspicious_map ( cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr ) {
2543+ span_help_and_lint (
2544+ cx,
2545+ SUSPICIOUS_MAP ,
2546+ expr. span ,
2547+ "this call to `map()` won't have an effect on the call to `count()`" ,
2548+ "make sure you did not confuse `map` with `filter`" ,
2549+ ) ;
2550+ }
2551+
25222552/// Given a `Result<T, E>` type, return its error type (`E`).
25232553fn get_error_type < ' a > ( cx : & LateContext < ' _ , ' _ > , ty : Ty < ' a > ) -> Option < Ty < ' a > > {
25242554 if let ty:: Adt ( _, substs) = ty. sty {
0 commit comments