|
1 | 1 | use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg}; |
2 | 2 | use clippy_utils::source::{snippet, snippet_with_applicability}; |
3 | 3 | use clippy_utils::ty::is_type_lang_item; |
| 4 | +use clippy_utils::{get_expr_use_or_unification_node, peel_blocks, SpanlessEq}; |
4 | 5 | use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths}; |
5 | | -use clippy_utils::{peel_blocks, SpanlessEq}; |
6 | 6 | use if_chain::if_chain; |
7 | 7 | use rustc_errors::Applicability; |
8 | 8 | 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}; |
10 | 10 | use rustc_lint::{LateContext, LateLintPass, LintContext}; |
11 | 11 | use rustc_middle::lint::in_external_macro; |
12 | 12 | use rustc_middle::ty; |
@@ -249,6 +249,7 @@ const MAX_LENGTH_BYTE_STRING_LIT: usize = 32; |
249 | 249 | declare_lint_pass!(StringLitAsBytes => [STRING_LIT_AS_BYTES, STRING_FROM_UTF8_AS_BYTES]); |
250 | 250 |
|
251 | 251 | impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { |
| 252 | + #[expect(clippy::too_many_lines)] |
252 | 253 | fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) { |
253 | 254 | use rustc_ast::LitKind; |
254 | 255 |
|
@@ -316,18 +317,27 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { |
316 | 317 | && lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT |
317 | 318 | && !receiver.span.from_expansion() |
318 | 319 | { |
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 | + } |
331 | 341 | } |
332 | 342 | } |
333 | 343 | } |
|
0 commit comments