Skip to content

Commit abd2c1e

Browse files
committed
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
2 parents c4f2c48 + 14a6fa4 commit abd2c1e

File tree

5 files changed

+54
-7
lines changed

5 files changed

+54
-7
lines changed

clippy_lints/src/strings.rs

+1
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
292292
}
293293

294294
if_chain! {
295+
if !in_external_macro(cx.sess(), e.span);
295296
if let ExprKind::MethodCall(path, receiver, ..) = &e.kind;
296297
if path.ident.name == sym!(as_bytes);
297298
if let ExprKind::Lit(lit) = &receiver.kind;

tests/ui/auxiliary/macro_rules.rs

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ macro_rules! string_add {
2121
};
2222
}
2323

24+
#[macro_export]
25+
macro_rules! string_lit_as_bytes {
26+
($s:literal) => {
27+
const C: &[u8] = $s.as_bytes();
28+
};
29+
}
30+
2431
#[macro_export]
2532
macro_rules! mut_mut {
2633
() => {

tests/ui/string_lit_as_bytes.fixed

+14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
//@run-rustfix
2+
//@aux-build:macro_rules.rs
23

34
#![allow(dead_code, unused_variables)]
45
#![warn(clippy::string_lit_as_bytes)]
56

7+
#[macro_use]
8+
extern crate macro_rules;
9+
10+
macro_rules! b {
11+
($b:literal) => {
12+
const B: &[u8] = b"warning";
13+
};
14+
}
15+
616
fn str_lit_as_bytes() {
717
let bs = b"hello there";
818

@@ -11,6 +21,10 @@ fn str_lit_as_bytes() {
1121
let bs = b"lit to string".to_vec();
1222
let bs = b"lit to owned".to_vec();
1323

24+
b!("warning");
25+
26+
string_lit_as_bytes!("no warning");
27+
1428
// no warning, because these cannot be written as byte string literals:
1529
let ubs = "☃".as_bytes();
1630
let ubs = "hello there! this is a very long string".as_bytes();

tests/ui/string_lit_as_bytes.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
//@run-rustfix
2+
//@aux-build:macro_rules.rs
23

34
#![allow(dead_code, unused_variables)]
45
#![warn(clippy::string_lit_as_bytes)]
56

7+
#[macro_use]
8+
extern crate macro_rules;
9+
10+
macro_rules! b {
11+
($b:literal) => {
12+
const B: &[u8] = $b.as_bytes();
13+
};
14+
}
15+
616
fn str_lit_as_bytes() {
717
let bs = "hello there".as_bytes();
818

@@ -11,6 +21,10 @@ fn str_lit_as_bytes() {
1121
let bs = "lit to string".to_string().into_bytes();
1222
let bs = "lit to owned".to_owned().into_bytes();
1323

24+
b!("warning");
25+
26+
string_lit_as_bytes!("no warning");
27+
1428
// no warning, because these cannot be written as byte string literals:
1529
let ubs = "☃".as_bytes();
1630
let ubs = "hello there! this is a very long string".as_bytes();

tests/ui/string_lit_as_bytes.stderr

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,51 @@
11
error: calling `as_bytes()` on a string literal
2-
--> $DIR/string_lit_as_bytes.rs:7:14
2+
--> $DIR/string_lit_as_bytes.rs:17:14
33
|
44
LL | let bs = "hello there".as_bytes();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"hello there"`
66
|
77
= note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`
88

99
error: calling `as_bytes()` on a string literal
10-
--> $DIR/string_lit_as_bytes.rs:9:14
10+
--> $DIR/string_lit_as_bytes.rs:19:14
1111
|
1212
LL | let bs = r###"raw string with 3# plus " ""###.as_bytes();
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###"raw string with 3# plus " ""###`
1414

1515
error: calling `into_bytes()` on a string literal
16-
--> $DIR/string_lit_as_bytes.rs:11:14
16+
--> $DIR/string_lit_as_bytes.rs:21:14
1717
|
1818
LL | let bs = "lit to string".to_string().into_bytes();
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to string".to_vec()`
2020

2121
error: calling `into_bytes()` on a string literal
22-
--> $DIR/string_lit_as_bytes.rs:12:14
22+
--> $DIR/string_lit_as_bytes.rs:22:14
2323
|
2424
LL | let bs = "lit to owned".to_owned().into_bytes();
2525
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"lit to owned".to_vec()`
2626

27+
error: calling `as_bytes()` on a string literal
28+
--> $DIR/string_lit_as_bytes.rs:12:26
29+
|
30+
LL | const B: &[u8] = $b.as_bytes();
31+
| ^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"warning"`
32+
...
33+
LL | b!("warning");
34+
| ------------- in this macro invocation
35+
|
36+
= note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
37+
2738
error: calling `as_bytes()` on `include_str!(..)`
28-
--> $DIR/string_lit_as_bytes.rs:25:22
39+
--> $DIR/string_lit_as_bytes.rs:39:22
2940
|
3041
LL | let includestr = include_str!("string_lit_as_bytes.rs").as_bytes();
3142
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!("string_lit_as_bytes.rs")`
3243

3344
error: calling `as_bytes()` on a string literal
34-
--> $DIR/string_lit_as_bytes.rs:27:13
45+
--> $DIR/string_lit_as_bytes.rs:41:13
3546
|
3647
LL | let _ = "string with newline/t/n".as_bytes();
3748
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b"string with newline/t/n"`
3849

39-
error: aborting due to 6 previous errors
50+
error: aborting due to 7 previous errors
4051

0 commit comments

Comments
 (0)