Skip to content

Commit 3b8a10c

Browse files
committed
Auto merge of rust-lang#10012 - Jarcho:issue_9885, r=Alexendoo
Don't lint `string_lit_as_bytes` in match scrutinees fixes rust-lang#9885 changelog: `string_lit_as_bytes`: Don't lint in match scrutinees
2 parents d822110 + a21b5b2 commit 3b8a10c

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

clippy_lints/src/strings.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg};
22
use clippy_utils::source::{snippet, snippet_with_applicability};
33
use clippy_utils::ty::is_type_lang_item;
4+
use clippy_utils::{get_expr_use_or_unification_node, peel_blocks, SpanlessEq};
45
use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths};
5-
use clippy_utils::{peel_blocks, SpanlessEq};
66
use if_chain::if_chain;
77
use rustc_errors::Applicability;
88
use rustc_hir::def_id::DefId;
9-
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, QPath};
9+
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, Node, QPath};
1010
use rustc_lint::{LateContext, LateLintPass, LintContext};
1111
use rustc_middle::lint::in_external_macro;
1212
use rustc_middle::ty;
@@ -249,6 +249,7 @@ const MAX_LENGTH_BYTE_STRING_LIT: usize = 32;
249249
declare_lint_pass!(StringLitAsBytes => [STRING_LIT_AS_BYTES, STRING_FROM_UTF8_AS_BYTES]);
250250

251251
impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
252+
#[expect(clippy::too_many_lines)]
252253
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
253254
use rustc_ast::LitKind;
254255

@@ -316,18 +317,27 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
316317
&& lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT
317318
&& !receiver.span.from_expansion()
318319
{
319-
span_lint_and_sugg(
320-
cx,
321-
STRING_LIT_AS_BYTES,
322-
e.span,
323-
"calling `as_bytes()` on a string literal",
324-
"consider using a byte string literal instead",
325-
format!(
326-
"b{}",
327-
snippet_with_applicability(cx, receiver.span, r#""foo""#, &mut applicability)
328-
),
329-
applicability,
330-
);
320+
if let Some((parent, id)) = get_expr_use_or_unification_node(cx.tcx, e)
321+
&& let Node::Expr(parent) = parent
322+
&& let ExprKind::Match(scrutinee, ..) = parent.kind
323+
&& scrutinee.hir_id == id
324+
{
325+
// Don't lint. Byte strings produce `&[u8; N]` whereas `as_bytes()` produces
326+
// `&[u8]`. This change would prevent matching with different sized slices.
327+
} else {
328+
span_lint_and_sugg(
329+
cx,
330+
STRING_LIT_AS_BYTES,
331+
e.span,
332+
"calling `as_bytes()` on a string literal",
333+
"consider using a byte string literal instead",
334+
format!(
335+
"b{}",
336+
snippet_with_applicability(cx, receiver.span, r#""foo""#, &mut applicability)
337+
),
338+
applicability,
339+
);
340+
}
331341
}
332342
}
333343
}

tests/ui/string_lit_as_bytes.fixed

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ fn str_lit_as_bytes() {
2525
let includestr = include_bytes!("string_lit_as_bytes.rs");
2626

2727
let _ = b"string with newline\t\n";
28+
29+
let _ = match "x".as_bytes() {
30+
b"xx" => 0,
31+
[b'x', ..] => 1,
32+
_ => 2,
33+
};
2834
}
2935

3036
fn main() {}

tests/ui/string_lit_as_bytes.rs

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ fn str_lit_as_bytes() {
2525
let includestr = include_str!("string_lit_as_bytes.rs").as_bytes();
2626

2727
let _ = "string with newline\t\n".as_bytes();
28+
29+
let _ = match "x".as_bytes() {
30+
b"xx" => 0,
31+
[b'x', ..] => 1,
32+
_ => 2,
33+
};
2834
}
2935

3036
fn main() {}

0 commit comments

Comments
 (0)