1 use clippy_utils
::diagnostics
::span_lint_and_sugg
;
2 use clippy_utils
::source
::snippet_with_applicability
;
3 use clippy_utils
::ty
::match_type
;
4 use clippy_utils
::visitors
::is_local_used
;
5 use clippy_utils
::{path_to_local_id, paths, peel_blocks, peel_ref_operators, strip_pat_refs}
;
6 use if_chain
::if_chain
;
7 use rustc_errors
::Applicability
;
8 use rustc_hir
::{BinOpKind, Closure, Expr, ExprKind, PatKind}
;
9 use rustc_lint
::LateContext
;
10 use rustc_middle
::ty
::{self, UintTy}
;
13 use super::NAIVE_BYTECOUNT
;
15 pub(super) fn check
<'tcx
>(
16 cx
: &LateContext
<'tcx
>,
18 filter_recv
: &'tcx Expr
<'_
>,
19 filter_arg
: &'tcx Expr
<'_
>,
22 if let ExprKind
::Closure(&Closure { body, .. }
) = filter_arg
.kind
;
23 let body
= cx
.tcx
.hir().body(body
);
24 if let [param
] = body
.params
;
25 if let PatKind
::Binding(_
, arg_id
, _
, _
) = strip_pat_refs(param
.pat
).kind
;
26 if let ExprKind
::Binary(ref op
, l
, r
) = body
.value
.kind
;
27 if op
.node
== BinOpKind
::Eq
;
29 cx
.typeck_results().expr_ty(filter_recv
).peel_refs(),
31 let operand_is_arg
= |expr
| {
32 let expr
= peel_ref_operators(cx
, peel_blocks(expr
));
33 path_to_local_id(expr
, arg_id
)
35 let needle
= if operand_is_arg(l
) {
37 } else if operand_is_arg(r
) {
42 if ty
::Uint(UintTy
::U8
) == *cx
.typeck_results().expr_ty(needle
).peel_refs().kind();
43 if !is_local_used(cx
, needle
, arg_id
);
45 let haystack
= if let ExprKind
::MethodCall(path
, receiver
, [], _
) =
47 let p
= path
.ident
.name
;
48 if p
== sym
::iter
|| p
== sym
::iter_mut
{
56 let mut applicability
= Applicability
::MaybeIncorrect
;
61 "you appear to be counting bytes the naive way",
62 "consider using the bytecount crate",
63 format
!("bytecount::count({}, {})",
64 snippet_with_applicability(cx
, haystack
.span
, "..", &mut applicability
),
65 snippet_with_applicability(cx
, needle
.span
, "..", &mut applicability
)),