about summary refs log tree commit diff
path: root/clippy_lints/src/methods/sliced_string_as_bytes.rs
blob: 6d4cfdb34f31943f832732e57ef2e8aac938a54e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_lang_item;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem, is_range_literal};
use rustc_lint::LateContext;

use super::SLICED_STRING_AS_BYTES;

pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>) {
    if let ExprKind::Index(indexed, index, _) = recv.kind
        && is_range_literal(index)
        && let ty = cx.typeck_results().expr_ty(indexed).peel_refs()
        && (ty.is_str() || is_type_lang_item(cx, ty, LangItem::String))
    {
        let mut applicability = Applicability::MaybeIncorrect;
        let stringish = snippet_with_applicability(cx, indexed.span, "_", &mut applicability);
        let range = snippet_with_applicability(cx, index.span, "_", &mut applicability);
        span_lint_and_sugg(
            cx,
            SLICED_STRING_AS_BYTES,
            expr.span,
            "calling `as_bytes` after slicing a string",
            "try",
            format!("&{stringish}.as_bytes()[{range}]"),
            applicability,
        );
    }
}