Skip to content

Commit 4d678b4

Browse files
committed
add checking type
1 parent c131612 commit 4d678b4

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

clippy_lints/src/bytes_count_to_len.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
use clippy_utils::diagnostics::span_lint_and_note;
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::ty::is_type_diagnostic_item;
24
use if_chain::if_chain;
5+
use rustc_errors::Applicability;
36
use rustc_hir as hir;
47
use rustc_lint::{LateContext, LateLintPass};
8+
use rustc_middle::ty;
59
use rustc_session::{declare_lint_pass, declare_tool_lint};
10+
use rustc_span::sym;
611

712
declare_clippy_lint! {
813
/// ### What it does
@@ -16,37 +21,45 @@ declare_clippy_lint! {
1621
/// ### Example
1722
/// ```rust
1823
/// "hello".bytes().count();
24+
/// String::from("hello").bytes().count();
1925
/// ```
2026
/// Use instead:
2127
/// ```rust
22-
/// "hello".len();
28+
/// "hello".len()
29+
/// String::from("hello").len();
2330
/// ```
24-
#[clippy::version = "1.60.0"]
31+
#[clippy::version = "1.62.0"]
2532
pub BYTES_COUNT_TO_LEN,
2633
complexity,
27-
"Using bytest().count() when len() performs the same functionality"
34+
"Using bytes().count() when len() performs the same functionality"
2835
}
2936

3037
declare_lint_pass!(BytesCountToLen => [BYTES_COUNT_TO_LEN]);
3138

3239
impl<'tcx> LateLintPass<'tcx> for BytesCountToLen {
3340
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
3441
if_chain! {
35-
//check for method call called "count"
36-
if let hir::ExprKind::MethodCall(count_path, count_args, _) = &expr.kind;
37-
if count_path.ident.name == rustc_span::sym::count;
38-
if let [bytes_expr] = &**count_args;
39-
//check for method call called "bytes" that was linked to "count"
40-
if let hir::ExprKind::MethodCall(bytes_path, _, _) = &bytes_expr.kind;
41-
if bytes_path.ident.name.as_str() == "bytes";
42+
if let hir::ExprKind::MethodCall(expr_method, expr_args, _) = &expr.kind;
43+
if expr_method.ident.name == rustc_span::sym::count;
44+
45+
if let [bytes_expr] = &**expr_args;
46+
if let hir::ExprKind::MethodCall(bytes_method, bytes_args, _) = &bytes_expr.kind;
47+
if bytes_method.ident.name.as_str() == "bytes";
48+
49+
if let [str_expr] = &**bytes_args;
50+
let ty = cx.typeck_results().expr_ty(str_expr).peel_refs();
51+
52+
if is_type_diagnostic_item(cx, ty, sym::String) || ty.kind() == &ty::Str;
4253
then {
43-
span_lint_and_note(
54+
let mut applicability = Applicability::MachineApplicable;
55+
span_lint_and_sugg(
4456
cx,
4557
BYTES_COUNT_TO_LEN,
4658
expr.span,
4759
"using long and hard to read `.bytes().count()`",
48-
None,
49-
"`.len()` achieves same functionality"
60+
"consider calling `.len` instead:",
61+
format!("{}.len()", snippet_with_applicability(cx, str_expr.span, "..", &mut applicability)),
62+
applicability
5063
);
5164
}
5265
};

0 commit comments

Comments
 (0)