diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index 760f5e3b432..99ca7ef77a5 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -284,6 +284,35 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { } } } + + if_chain! { + if let ExprKind::MethodCall(path, _, [recv], _) = &e.kind; + if path.ident.name == sym!(into_bytes); + if let ExprKind::MethodCall(path, _, [recv], _) = &recv.kind; + if matches!(&*path.ident.name.as_str(), "to_owned" | "to_string"); + if let ExprKind::Lit(lit) = &recv.kind; + if let LitKind::Str(lit_content, _) = &lit.node; + + if lit_content.as_str().is_ascii(); + if lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT; + if !recv.span.from_expansion(); + then { + let mut applicability = Applicability::MachineApplicable; + + span_lint_and_sugg( + cx, + STRING_LIT_AS_BYTES, + e.span, + "calling `into_bytes()` on a string literal", + "consider using a byte string literal instead", + format!( + "b{}.to_vec()", + snippet_with_applicability(cx, recv.span, r#""..""#, &mut applicability) + ), + applicability, + ); + } + } } } diff --git a/tests/ui/string_lit_as_bytes.fixed b/tests/ui/string_lit_as_bytes.fixed index ccf8f61c4a9..dd22bfa5c53 100644 --- a/tests/ui/string_lit_as_bytes.fixed +++ b/tests/ui/string_lit_as_bytes.fixed @@ -8,10 +8,16 @@ fn str_lit_as_bytes() { let bs = br###"raw string with 3# plus " ""###; + let bs = b"lit to string".to_vec(); + let bs = b"lit to owned".to_vec(); + // no warning, because these cannot be written as byte string literals: let ubs = "☃".as_bytes(); let ubs = "hello there! this is a very long string".as_bytes(); + let ubs = "☃".to_string().into_bytes(); + let ubs = "this is also too long and shouldn't be fixed".to_string().into_bytes(); + let strify = stringify!(foobar).as_bytes(); let current_version = env!("CARGO_PKG_VERSION").as_bytes(); diff --git a/tests/ui/string_lit_as_bytes.rs b/tests/ui/string_lit_as_bytes.rs index 178df08e249..d2a710ed6b8 100644 --- a/tests/ui/string_lit_as_bytes.rs +++ b/tests/ui/string_lit_as_bytes.rs @@ -8,10 +8,16 @@ fn str_lit_as_bytes() { let bs = r###"raw string with 3# plus " ""###.as_bytes(); + let bs = "lit to string".to_string().into_bytes(); + let bs = "lit to owned".to_owned().into_bytes(); + // no warning, because these cannot be written as byte string literals: let ubs = "☃".as_bytes(); let ubs = "hello there! this is a very long string".as_bytes(); + let ubs = "☃".to_string().into_bytes(); + let ubs = "this is also too long and shouldn't be fixed".to_string().into_bytes(); + let strify = stringify!(foobar).as_bytes(); let current_version = env!("CARGO_PKG_VERSION").as_bytes(); diff --git a/tests/ui/string_lit_as_bytes.stderr b/tests/ui/string_lit_as_bytes.stderr index 99c512354d5..e0ddb070b50 100644 --- a/tests/ui/string_lit_as_bytes.stderr +++ b/tests/ui/string_lit_as_bytes.stderr @@ -12,17 +12,29 @@ error: calling `as_bytes()` on a string literal LL | let bs = r###"raw string with 3# plus " ""###.as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with 3# plus " ""###` +error: calling `into_bytes()` on a string literal + --> $DIR/string_lit_as_bytes.rs:11:14 + | +LL | let bs = "lit to string".to_string().into_bytes(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to string".to_vec()` + +error: calling `into_bytes()` on a string literal + --> $DIR/string_lit_as_bytes.rs:12:14 + | +LL | let bs = "lit to owned".to_owned().into_bytes(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to owned".to_vec()` + error: calling `as_bytes()` on `include_str!(..)` - --> $DIR/string_lit_as_bytes.rs:19:22 + --> $DIR/string_lit_as_bytes.rs:25:22 | LL | let includestr = include_str!("entry_unfixable.rs").as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("entry_unfixable.rs")` error: calling `as_bytes()` on a string literal - --> $DIR/string_lit_as_bytes.rs:21:13 + --> $DIR/string_lit_as_bytes.rs:27:13 | LL | let _ = "string with newline/t/n".as_bytes(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline/t/n"` -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors