]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/methods/search_is_some.rs
Auto merge of #8030 - WaffleLapkin:ignore_trait_assoc_types_type_complexity, r=llogiq
[rust.git] / clippy_lints / src / methods / search_is_some.rs
index 8a94d7f415583b978774c09372d0593a1d9ccba7..5ed4ba94884e26b627874b7253608150eca9a0a9 100644 (file)
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::source::{snippet, snippet_with_applicability};
+use clippy_utils::sugg::deref_closure_args;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{is_trait_method, strip_pat_refs};
 use if_chain::if_chain;
@@ -37,6 +38,7 @@ pub(super) fn check<'tcx>(
         if search_snippet.lines().count() <= 1 {
             // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()`
             // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()`
+            let mut applicability = Applicability::MachineApplicable;
             let any_search_snippet = if_chain! {
                 if search_method == "find";
                 if let hir::ExprKind::Closure(_, _, body_id, ..) = search_arg.kind;
@@ -45,9 +47,15 @@ pub(super) fn check<'tcx>(
                 then {
                     if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
                         Some(search_snippet.replacen('&', "", 1))
-                    } else if let PatKind::Binding(_, _, ident, _) = strip_pat_refs(&closure_arg.pat).kind {
-                        let name = &*ident.name.as_str();
-                        Some(search_snippet.replace(&format!("*{}", name), name))
+                    } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind {
+                        // `find()` provides a reference to the item, but `any` does not,
+                        // so we should fix item usages for suggestion
+                        if let Some(closure_sugg) = deref_closure_args(cx, search_arg) {
+                            applicability = closure_sugg.applicability;
+                            Some(closure_sugg.suggestion)
+                        } else {
+                            Some(search_snippet.to_string())
+                        }
                     } else {
                         None
                     }
@@ -67,7 +75,7 @@ pub(super) fn check<'tcx>(
                         "any({})",
                         any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
                     ),
-                    Applicability::MachineApplicable,
+                    applicability,
                 );
             } else {
                 let iter = snippet(cx, search_recv.span, "..");
@@ -82,7 +90,7 @@ pub(super) fn check<'tcx>(
                         iter,
                         any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
                     ),
-                    Applicability::MachineApplicable,
+                    applicability,
                 );
             }
         } else {
@@ -101,15 +109,15 @@ pub(super) fn check<'tcx>(
     else if search_method == "find" {
         let is_string_or_str_slice = |e| {
             let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
-            if is_type_diagnostic_item(cx, self_ty, sym::string_type) {
+            if is_type_diagnostic_item(cx, self_ty, sym::String) {
                 true
             } else {
                 *self_ty.kind() == ty::Str
             }
         };
         if_chain! {
-            if is_string_or_str_slice(&search_recv);
-            if is_string_or_str_slice(&search_arg);
+            if is_string_or_str_slice(search_recv);
+            if is_string_or_str_slice(search_arg);
             then {
                 let msg = format!("called `{}()` after calling `find()` on a string", option_check_method);
                 match option_check_method {