rust/clippy_lints/src/bytes_count_to_len.rs

55 lines
1.8 KiB
Rust
Raw Normal View History

use clippy_utils::diagnostics::span_lint_and_note;
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
/// ### What it does
/// It checks for `str::bytes().count()` and suggests replacing it with
/// `str::len()`.
///
/// ### Why is this bad?
/// `str::bytes().count()` is longer and may not be as performant as using
/// `str::len()`.
///
/// ### Example
/// ```rust
/// "hello".bytes().count();
/// ```
/// Use instead:
/// ```rust
/// "hello".len();
/// ```
#[clippy::version = "1.60.0"]
pub BYTES_COUNT_TO_LEN,
complexity,
"Using bytest().count() when len() performs the same functionality"
}
declare_lint_pass!(BytesCountToLen => [BYTES_COUNT_TO_LEN]);
impl<'tcx> LateLintPass<'tcx> for BytesCountToLen {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
if_chain! {
//check for method call called "count"
if let hir::ExprKind::MethodCall(count_path, count_args, _) = &expr.kind;
if count_path.ident.name == rustc_span::sym::count;
if let [bytes_expr] = &**count_args;
//check for method call called "bytes" that was linked to "count"
if let hir::ExprKind::MethodCall(bytes_path, _, _) = &bytes_expr.kind;
if bytes_path.ident.name.as_str() == "bytes";
then {
span_lint_and_note(
cx,
BYTES_COUNT_TO_LEN,
expr.span,
"using long and hard to read `.bytes().count()`",
None,
"`.len()` achieves same functionality"
);
}
};
}
}