|
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