Auto merge of #10665 - Centri3:string_lit_as_bytes_changes, r=giraffate

Don't apply `string_lit_as_bytes` if in macro expansion

The following code will emit a warning on both w! and h!, despite there being nothing the user (or library author) could do about it:
```rust
#![warn(clippy::string_lit_as_bytes)]

use windows::w;
use windows::h;

fn main() {
    let _w = w!("example");
    let _h = h!("example");
}
```
This is because windows-rs will create a binding `const INPUT: &[u8] = $s.as_bytes()`, and changing this to b"$s" is, well, suboptimal. I don't know enough about Rust to know if this is something that can be detected though if it can be I'm happy with closing this in favor of implementing that.

I'm not sure whether this is how it should be done though, as this simply tells clippy to not invoke this even if it's applicable (this also affects the other string lints, but didn't cause any tests to fail).

changelog: [`string_lit_as_bytes`]: Don't lint if in external macro
This commit is contained in:
bors 2023-04-25 13:02:52 +00:00
commit abd2c1e8e4
5 changed files with 54 additions and 7 deletions

View File

@ -292,6 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
}
if_chain! {
if !in_external_macro(cx.sess(), e.span);
if let ExprKind::MethodCall(path, receiver, ..) = &e.kind;
if path.ident.name == sym!(as_bytes);
if let ExprKind::Lit(lit) = &receiver.kind;

View File

@ -21,6 +21,13 @@ macro_rules! string_add {
};
}
#[macro_export]
macro_rules! string_lit_as_bytes {
($s:literal) => {
const C: &[u8] = $s.as_bytes();
};
}
#[macro_export]
macro_rules! mut_mut {
() => {

View File

@ -1,8 +1,18 @@
//@run-rustfix
//@aux-build:macro_rules.rs
#![allow(dead_code, unused_variables)]
#![warn(clippy::string_lit_as_bytes)]
#[macro_use]
extern crate macro_rules;
macro_rules! b {
($b:literal) => {
const B: &[u8] = b"warning";
};
}
fn str_lit_as_bytes() {
let bs = b"hello there";
@ -11,6 +21,10 @@ fn str_lit_as_bytes() {
let bs = b"lit to string".to_vec();
let bs = b"lit to owned".to_vec();
b!("warning");
string_lit_as_bytes!("no warning");
// 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();

View File

@ -1,8 +1,18 @@
//@run-rustfix
//@aux-build:macro_rules.rs
#![allow(dead_code, unused_variables)]
#![warn(clippy::string_lit_as_bytes)]
#[macro_use]
extern crate macro_rules;
macro_rules! b {
($b:literal) => {
const B: &[u8] = $b.as_bytes();
};
}
fn str_lit_as_bytes() {
let bs = "hello there".as_bytes();
@ -11,6 +21,10 @@ fn str_lit_as_bytes() {
let bs = "lit to string".to_string().into_bytes();
let bs = "lit to owned".to_owned().into_bytes();
b!("warning");
string_lit_as_bytes!("no warning");
// 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();

View File

@ -1,5 +1,5 @@
error: calling `as_bytes()` on a string literal
--> $DIR/string_lit_as_bytes.rs:7:14
--> $DIR/string_lit_as_bytes.rs:17:14
|
LL | let bs = "hello there".as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"hello there"`
@ -7,34 +7,45 @@ LL | let bs = "hello there".as_bytes();
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
error: calling `as_bytes()` on a string literal
--> $DIR/string_lit_as_bytes.rs:9:14
--> $DIR/string_lit_as_bytes.rs:19:14
|
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
--> $DIR/string_lit_as_bytes.rs:21: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
--> $DIR/string_lit_as_bytes.rs:22: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 a string literal
--> $DIR/string_lit_as_bytes.rs:12:26
|
LL | const B: &[u8] = $b.as_bytes();
| ^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"warning"`
...
LL | b!("warning");
| ------------- in this macro invocation
|
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
error: calling `as_bytes()` on `include_str!(..)`
--> $DIR/string_lit_as_bytes.rs:25:22
--> $DIR/string_lit_as_bytes.rs:39:22
|
LL | let includestr = include_str!("string_lit_as_bytes.rs").as_bytes();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("string_lit_as_bytes.rs")`
error: calling `as_bytes()` on a string literal
--> $DIR/string_lit_as_bytes.rs:27:13
--> $DIR/string_lit_as_bytes.rs:41: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 6 previous errors
error: aborting due to 7 previous errors