about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCameron Steffen <cam.steffen94@gmail.com>2021-04-02 08:37:03 -0500
committerCameron Steffen <cam.steffen94@gmail.com>2021-04-02 08:41:05 -0500
commita064534b9e9754e18429a05db79fcba0d70292b9 (patch)
treedc8ead3b5ef48ce60b4d7dc9930153a3951a8d2d
parent1931db20b1733039078a5420aa74417c511e9a4f (diff)
downloadrust-a064534b9e9754e18429a05db79fcba0d70292b9.tar.gz
rust-a064534b9e9754e18429a05db79fcba0d70292b9.zip
Refactor needless_collect
-rw-r--r--clippy_lints/src/loops/needless_collect.rs80
1 files changed, 21 insertions, 59 deletions
diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/loops/needless_collect.rs
index d23d3c508fa..5378b018970 100644
--- a/clippy_lints/src/loops/needless_collect.rs
+++ b/clippy_lints/src/loops/needless_collect.rs
@@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
 fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
     if_chain! {
         if let ExprKind::MethodCall(ref method, _, ref args, _) = expr.kind;
-        if let ExprKind::MethodCall(ref chain_method, _, _, _) = args[0].kind;
+        if let ExprKind::MethodCall(ref chain_method, method0_span, _, _) = args[0].kind;
         if chain_method.ident.name == sym!(collect) && is_trait_method(cx, &args[0], sym::Iterator);
         if let Some(ref generic_args) = chain_method.args;
         if let Some(GenericArg::Type(ref ty)) = generic_args.args.get(0);
@@ -31,55 +31,28 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
             || is_type_diagnostic_item(cx, ty, sym::vecdeque_type)
             || match_type(cx, ty, &paths::BTREEMAP)
             || is_type_diagnostic_item(cx, ty, sym::hashmap_type);
-        then {
-            if method.ident.name == sym!(len) {
-                let span = shorten_needless_collect_span(expr);
-                span_lint_and_sugg(
-                    cx,
-                    NEEDLESS_COLLECT,
-                    span,
-                    NEEDLESS_COLLECT_MSG,
-                    "replace with",
-                    "count()".to_string(),
-                    Applicability::MachineApplicable,
-                );
-            }
-            if method.ident.name == sym!(is_empty) {
-                let span = shorten_needless_collect_span(expr);
-                span_lint_and_sugg(
-                    cx,
-                    NEEDLESS_COLLECT,
-                    span,
-                    NEEDLESS_COLLECT_MSG,
-                    "replace with",
-                    "next().is_none()".to_string(),
-                    Applicability::MachineApplicable,
-                );
-            }
-            if method.ident.name == sym!(contains) {
+        if let Some(sugg) = match &*method.ident.name.as_str() {
+            "len" => Some("count()".to_string()),
+            "is_empty" => Some("next().is_none()".to_string()),
+            "contains" => {
                 let contains_arg = snippet(cx, args[1].span, "??");
-                let span = shorten_needless_collect_span(expr);
-                span_lint_and_then(
-                    cx,
-                    NEEDLESS_COLLECT,
-                    span,
-                    NEEDLESS_COLLECT_MSG,
-                    |diag| {
-                        let (arg, pred) = contains_arg
-                                .strip_prefix('&')
-                                .map_or(("&x", &*contains_arg), |s| ("x", s));
-                        diag.span_suggestion(
-                            span,
-                            "replace with",
-                            format!(
-                                "any(|{}| x == {})",
-                                arg, pred
-                            ),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                );
+                let (arg, pred) = contains_arg
+                    .strip_prefix('&')
+                    .map_or(("&x", &*contains_arg), |s| ("x", s));
+                Some(format!("any(|{}| x == {})", arg, pred))
             }
+            _ => None,
+        };
+        then {
+            span_lint_and_sugg(
+                cx,
+                NEEDLESS_COLLECT,
+                method0_span.with_hi(expr.span.hi()),
+                NEEDLESS_COLLECT_MSG,
+                "replace with",
+                sugg,
+                Applicability::MachineApplicable,
+            );
         }
     }
 }
@@ -269,14 +242,3 @@ fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident)
     visitor.visit_block(block);
     if visitor.seen_other { None } else { Some(visitor.uses) }
 }
-
-fn shorten_needless_collect_span(expr: &Expr<'_>) -> Span {
-    if_chain! {
-        if let ExprKind::MethodCall(.., args, _) = &expr.kind;
-        if let ExprKind::MethodCall(_, span, ..) = &args[0].kind;
-        then {
-            return expr.span.with_lo(span.lo());
-        }
-    }
-    unreachable!();
-}