@@ -18,7 +18,6 @@ use syntax::ast;
18
18
use syntax:: source_map:: Span ;
19
19
use syntax:: symbol:: LocalInternedString ;
20
20
21
- use crate :: utils:: paths;
22
21
use crate :: utils:: sugg;
23
22
use crate :: utils:: usage:: mutated_variables;
24
23
use crate :: utils:: {
@@ -28,6 +27,7 @@ use crate::utils::{
28
27
snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_sugg,
29
28
span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq ,
30
29
} ;
30
+ use crate :: utils:: { paths, span_help_and_lint} ;
31
31
32
32
declare_clippy_lint ! {
33
33
/// **What it does:** Checks for `.unwrap()` calls on `Option`s.
@@ -889,6 +889,24 @@ declare_clippy_lint! {
889
889
"using `.into_iter()` on a reference"
890
890
}
891
891
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
+
892
910
declare_lint_pass ! ( Methods => [
893
911
OPTION_UNWRAP_USED ,
894
912
RESULT_UNWRAP_USED ,
@@ -927,6 +945,7 @@ declare_lint_pass!(Methods => [
927
945
UNNECESSARY_FILTER_MAP ,
928
946
INTO_ITER_ON_ARRAY ,
929
947
INTO_ITER_ON_REF ,
948
+ SUSPICIOUS_MAP ,
930
949
] ) ;
931
950
932
951
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Methods {
@@ -972,6 +991,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
972
991
[ "as_mut" ] => lint_asref ( cx, expr, "as_mut" , arg_lists[ 0 ] ) ,
973
992
[ "fold" , ..] => lint_unnecessary_fold ( cx, expr, arg_lists[ 0 ] ) ,
974
993
[ "filter_map" , ..] => unnecessary_filter_map:: lint ( cx, expr, arg_lists[ 0 ] ) ,
994
+ [ "count" , "map" ] => lint_suspicious_map ( cx, expr) ,
975
995
_ => { } ,
976
996
}
977
997
@@ -2519,6 +2539,16 @@ fn lint_into_iter(cx: &LateContext<'_, '_>, expr: &hir::Expr, self_ref_ty: Ty<'_
2519
2539
}
2520
2540
}
2521
2541
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
+
2522
2552
/// Given a `Result<T, E>` type, return its error type (`E`).
2523
2553
fn get_error_type < ' a > ( cx : & LateContext < ' _ , ' _ > , ty : Ty < ' a > ) -> Option < Ty < ' a > > {
2524
2554
if let ty:: Adt ( _, substs) = ty. sty {
0 commit comments