|  | 
| 1 |  | -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; | 
|  | 1 | +use clippy_utils::diagnostics::span_lint_and_sugg; | 
| 2 | 2 | use clippy_utils::res::{MaybeDef, MaybeTypeckRes}; | 
| 3 | 3 | use clippy_utils::source::{snippet, snippet_with_applicability}; | 
| 4 | 4 | use clippy_utils::sugg::deref_closure_args; | 
| @@ -34,79 +34,67 @@ pub(super) fn check<'tcx>( | 
| 34 | 34 |     { | 
| 35 | 35 |         let msg = format!("called `{option_check_method}()` after searching an `Iterator` with `{search_method}`"); | 
| 36 | 36 |         let search_snippet = snippet(cx, search_arg.span, ".."); | 
| 37 |  | -        if search_snippet.lines().count() <= 1 { | 
| 38 |  | -            // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` | 
| 39 |  | -            // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` | 
| 40 |  | -            let mut applicability = Applicability::MachineApplicable; | 
| 41 |  | -            let any_search_snippet = if search_method == sym::find | 
| 42 |  | -                && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind | 
| 43 |  | -                && let closure_body = cx.tcx.hir_body(body) | 
| 44 |  | -                && let Some(closure_arg) = closure_body.params.first() | 
| 45 |  | -            { | 
| 46 |  | -                if let PatKind::Ref(..) = closure_arg.pat.kind { | 
| 47 |  | -                    Some(search_snippet.replacen('&', "", 1)) | 
| 48 |  | -                } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind { | 
| 49 |  | -                    // `find()` provides a reference to the item, but `any` does not, | 
| 50 |  | -                    // so we should fix item usages for suggestion | 
| 51 |  | -                    if let Some(closure_sugg) = deref_closure_args(cx, search_arg) { | 
| 52 |  | -                        applicability = closure_sugg.applicability; | 
| 53 |  | -                        Some(closure_sugg.suggestion) | 
| 54 |  | -                    } else { | 
| 55 |  | -                        Some(search_snippet.to_string()) | 
| 56 |  | -                    } | 
|  | 37 | +        // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` | 
|  | 38 | +        // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` | 
|  | 39 | +        let mut applicability = Applicability::MachineApplicable; | 
|  | 40 | +        let any_search_snippet = if search_method == sym::find | 
|  | 41 | +            && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind | 
|  | 42 | +            && let closure_body = cx.tcx.hir_body(body) | 
|  | 43 | +            && let Some(closure_arg) = closure_body.params.first() | 
|  | 44 | +        { | 
|  | 45 | +            if let PatKind::Ref(..) = closure_arg.pat.kind { | 
|  | 46 | +                Some(search_snippet.replacen('&', "", 1)) | 
|  | 47 | +            } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind { | 
|  | 48 | +                // `find()` provides a reference to the item, but `any` does not, | 
|  | 49 | +                // so we should fix item usages for suggestion | 
|  | 50 | +                if let Some(closure_sugg) = deref_closure_args(cx, search_arg) { | 
|  | 51 | +                    applicability = closure_sugg.applicability; | 
|  | 52 | +                    Some(closure_sugg.suggestion) | 
| 57 | 53 |                 } else { | 
| 58 |  | -                    None | 
|  | 54 | +                    Some(search_snippet.to_string()) | 
| 59 | 55 |                 } | 
| 60 | 56 |             } else { | 
| 61 | 57 |                 None | 
| 62 |  | -            }; | 
| 63 |  | -            // add note if not multi-line | 
| 64 |  | -            if is_some { | 
| 65 |  | -                span_lint_and_sugg( | 
| 66 |  | -                    cx, | 
| 67 |  | -                    SEARCH_IS_SOME, | 
| 68 |  | -                    method_span.with_hi(expr.span.hi()), | 
| 69 |  | -                    msg, | 
| 70 |  | -                    "consider using", | 
| 71 |  | -                    format!( | 
| 72 |  | -                        "any({})", | 
| 73 |  | -                        any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) | 
| 74 |  | -                    ), | 
| 75 |  | -                    applicability, | 
| 76 |  | -                ); | 
| 77 |  | -            } else { | 
| 78 |  | -                let iter = snippet(cx, search_recv.span, ".."); | 
| 79 |  | -                let sugg = if is_receiver_of_method_call(cx, expr) { | 
| 80 |  | -                    format!( | 
| 81 |  | -                        "(!{iter}.any({}))", | 
| 82 |  | -                        any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) | 
| 83 |  | -                    ) | 
| 84 |  | -                } else { | 
| 85 |  | -                    format!( | 
| 86 |  | -                        "!{iter}.any({})", | 
| 87 |  | -                        any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) | 
| 88 |  | -                    ) | 
| 89 |  | -                }; | 
| 90 |  | -                span_lint_and_sugg( | 
| 91 |  | -                    cx, | 
| 92 |  | -                    SEARCH_IS_SOME, | 
| 93 |  | -                    expr.span, | 
| 94 |  | -                    msg, | 
| 95 |  | -                    "consider using", | 
| 96 |  | -                    sugg, | 
| 97 |  | -                    applicability, | 
| 98 |  | -                ); | 
| 99 | 58 |             } | 
| 100 | 59 |         } else { | 
| 101 |  | -            let hint = format!( | 
| 102 |  | -                "this is more succinctly expressed by calling `any()`{}", | 
| 103 |  | -                if option_check_method == "is_none" { | 
| 104 |  | -                    " with negation" | 
| 105 |  | -                } else { | 
| 106 |  | -                    "" | 
| 107 |  | -                } | 
|  | 60 | +            None | 
|  | 61 | +        }; | 
|  | 62 | +        // add note if not multi-line | 
|  | 63 | +        if is_some { | 
|  | 64 | +            span_lint_and_sugg( | 
|  | 65 | +                cx, | 
|  | 66 | +                SEARCH_IS_SOME, | 
|  | 67 | +                method_span.with_hi(expr.span.hi()), | 
|  | 68 | +                msg, | 
|  | 69 | +                "consider using", | 
|  | 70 | +                format!( | 
|  | 71 | +                    "any({})", | 
|  | 72 | +                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) | 
|  | 73 | +                ), | 
|  | 74 | +                applicability, | 
|  | 75 | +            ); | 
|  | 76 | +        } else { | 
|  | 77 | +            let iter = snippet(cx, search_recv.span, ".."); | 
|  | 78 | +            let sugg = if is_receiver_of_method_call(cx, expr) { | 
|  | 79 | +                format!( | 
|  | 80 | +                    "(!{iter}.any({}))", | 
|  | 81 | +                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) | 
|  | 82 | +                ) | 
|  | 83 | +            } else { | 
|  | 84 | +                format!( | 
|  | 85 | +                    "!{iter}.any({})", | 
|  | 86 | +                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str) | 
|  | 87 | +                ) | 
|  | 88 | +            }; | 
|  | 89 | +            span_lint_and_sugg( | 
|  | 90 | +                cx, | 
|  | 91 | +                SEARCH_IS_SOME, | 
|  | 92 | +                expr.span, | 
|  | 93 | +                msg, | 
|  | 94 | +                "consider using", | 
|  | 95 | +                sugg, | 
|  | 96 | +                applicability, | 
| 108 | 97 |             ); | 
| 109 |  | -            span_lint_and_help(cx, SEARCH_IS_SOME, expr.span, msg, None, hint); | 
| 110 | 98 |         } | 
| 111 | 99 |     } | 
| 112 | 100 |     // lint if `find()` is called by `String` or `&str` | 
|  | 
0 commit comments