| use clippy_utils::diagnostics::span_lint_and_then; | |
| use clippy_utils::is_from_proc_macro; | |
| use clippy_utils::msrvs::{self, Msrv}; | |
| use clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes}; | |
| use clippy_utils::source::SpanRangeExt; | |
| use itertools::Itertools; | |
| use rustc_ast::LitKind; | |
| use rustc_errors::Applicability; | |
| use rustc_hir::{BinOpKind, Expr, ExprKind, Param, PatKind}; | |
| use rustc_lint::LateContext; | |
| use rustc_span::sym; | |
| use super::STRING_LIT_CHARS_ANY; | |
| pub(super) fn check<'tcx>( | |
| cx: &LateContext<'tcx>, | |
| expr: &'tcx Expr<'tcx>, | |
| recv: &Expr<'_>, | |
| param: &'tcx Param<'tcx>, | |
| body: &Expr<'_>, | |
| msrv: Msrv, | |
| ) { | |
| if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) | |
| && let PatKind::Binding(_, arg, _, _) = param.pat.kind | |
| && let ExprKind::Lit(lit_kind) = recv.kind | |
| && let LitKind::Str(val, _) = lit_kind.node | |
| && let ExprKind::Binary(kind, lhs, rhs) = body.kind | |
| && let BinOpKind::Eq = kind.node | |
| && let Some(lhs_path) = lhs.res_local_id() | |
| && let Some(rhs_path) = rhs.res_local_id() | |
| && let scrutinee = match (lhs_path == arg, rhs_path == arg) { | |
| (true, false) => rhs, | |
| (false, true) => lhs, | |
| _ => return, | |
| } | |
| && msrv.meets(cx, msrvs::MATCHES_MACRO) | |
| && !is_from_proc_macro(cx, expr) | |
| && let Some(scrutinee_snip) = scrutinee.span.get_source_text(cx) | |
| { | |
| // Normalize the char using `map` so `join` doesn't use `Display`, if we don't then | |
| // something like `r"\"` will become `'\'`, which is of course invalid | |
| let pat_snip = val.as_str().chars().map(|c| format!("{c:?}")).join(" | "); | |
| span_lint_and_then( | |
| cx, | |
| STRING_LIT_CHARS_ANY, | |
| expr.span, | |
| "usage of `.chars().any(...)` to check if a char matches any from a string literal", | |
| |diag| { | |
| diag.span_suggestion_verbose( | |
| expr.span, | |
| "use `matches!(...)` instead", | |
| format!("matches!({scrutinee_snip}, {pat_snip})"), | |
| Applicability::MachineApplicable, | |
| ); | |
| }, | |
| ); | |
| } | |
| } |