Skip to content

Commit 0d25090

Browse files
Improve code and apply suggestions
1 parent 7b06d2b commit 0d25090

File tree

5 files changed

+123
-26
lines changed

5 files changed

+123
-26
lines changed

clippy_lints/src/useless_concat.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::macros::macro_backtrace;
33
use clippy_utils::paths::CONCAT;
44
use clippy_utils::source::snippet_opt;
5-
use clippy_utils::{match_def_path, tokenize_with_text};
5+
use clippy_utils::tokenize_with_text;
66
use rustc_ast::LitKind;
77
use rustc_errors::Applicability;
88
use rustc_hir::{Expr, ExprKind};
@@ -25,7 +25,7 @@ declare_clippy_lint! {
2525
/// ```no_run
2626
/// let x = "a";
2727
/// ```
28-
#[clippy::version = "1.85.0"]
28+
#[clippy::version = "1.89.0"]
2929
pub USELESS_CONCAT,
3030
complexity,
3131
"checks that the `concat` macro has at least two arguments"
@@ -39,11 +39,11 @@ impl LateLintPass<'_> for UselessConcat {
3939
if expr.span.from_expansion()
4040
// Check that it's a string literal.
4141
&& let ExprKind::Lit(lit) = expr.kind
42-
&& let LitKind::Str(_, _) = lit.node
42+
&& let LitKind::Str(lit_s, _) = lit.node
4343
// Get the direct parent of the expression.
4444
&& let Some(macro_call) = macro_backtrace(expr.span).next()
4545
// Check if the `concat` macro from the `core` library.
46-
&& match_def_path(cx, macro_call.def_id, &CONCAT)
46+
&& CONCAT.matches(cx, macro_call.def_id)
4747
// We get the original code to parse it.
4848
&& let Some(original_code) = snippet_opt(cx, macro_call.span)
4949
// This check allows us to ensure that the code snippet:
@@ -68,7 +68,13 @@ impl LateLintPass<'_> for UselessConcat {
6868
}
6969
literal = Some(token_s);
7070
},
71-
TokenKind::Ident => nb_idents += 1,
71+
TokenKind::Ident => {
72+
if token_s == "true" || token_s == "false" {
73+
literal = Some(token_s);
74+
} else {
75+
nb_idents += 1;
76+
}
77+
},
7278
TokenKind::Comma => {
7379
nb_commas += 1;
7480
if nb_commas > 1 {
@@ -81,17 +87,6 @@ impl LateLintPass<'_> for UselessConcat {
8187
_ => {},
8288
}
8389
}
84-
let literal = match literal {
85-
Some(lit) => {
86-
// Literals can also be number, so we need to check this case too.
87-
if lit.starts_with('"') {
88-
lit.to_string()
89-
} else {
90-
format!("\"{lit}\"")
91-
}
92-
},
93-
None => "\"\"".to_string(),
94-
};
9590
// There should always be the ident of the `concat` macro.
9691
if nb_idents == 1 {
9792
span_lint_and_sugg(
@@ -100,7 +95,7 @@ impl LateLintPass<'_> for UselessConcat {
10095
macro_call.span,
10196
"unneeded use of `concat!` macro",
10297
"replace with",
103-
literal,
98+
format!("{lit_s:?}"),
10499
Applicability::MachineApplicable,
105100
);
106101
}

clippy_utils/src/paths.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ path_macros! {
129129
// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
130130
pub static ALIGN_OF: PathLookup = value_path!(core::mem::align_of);
131131
pub static CHAR_TO_DIGIT: PathLookup = value_path!(char::to_digit);
132-
pub static CONCAT: PathLookup = value_path!(core::macros::builtin::concat);
132+
pub static CONCAT: PathLookup = macro_path!(core::concat);
133133
pub static IO_ERROR_NEW: PathLookup = value_path!(std::io::Error::new);
134134
pub static IO_ERRORKIND_OTHER_CTOR: PathLookup = value_path!(std::io::ErrorKind::Other);
135135
pub static ITER_STEP: PathLookup = type_path!(core::iter::Step);

tests/ui/useless_concat.fixed

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
//@aux-build:proc_macros.rs
2+
13
#![warn(clippy::useless_concat)]
24
#![allow(clippy::print_literal)]
35

6+
extern crate proc_macros;
7+
use proc_macros::{external, with_span};
8+
49
macro_rules! my_concat {
510
($fmt:literal $(, $e:expr)*) => {
611
println!(concat!("ERROR: ", $fmt), $($e,)*);
@@ -9,6 +14,16 @@ macro_rules! my_concat {
914

1015
fn main() {
1116
let x = ""; //~ useless_concat
17+
let x = "c"; //~ useless_concat
18+
let x = "\""; //~ useless_concat
19+
let x = "true"; //~ useless_concat
20+
let x = "1"; //~ useless_concat
21+
let x = "1.0000"; //~ useless_concat
22+
let x = "1"; //~ useless_concat
23+
let x = "1"; //~ useless_concat
24+
let x = "1.0000"; //~ useless_concat
25+
let x = "1.0000"; //~ useless_concat
26+
let x = "a😀\n"; //~ useless_concat
1227
let x = "a"; //~ useless_concat
1328
let x = "1"; //~ useless_concat
1429
println!("b: {}", "a"); //~ useless_concat
@@ -17,4 +32,10 @@ fn main() {
1732
let local_i32 = 1;
1833
my_concat!("{}", local_i32);
1934
let x = concat!(file!(), "#L", line!());
35+
36+
external! { concat!(); }
37+
with_span! {
38+
span
39+
concat!();
40+
}
2041
}

tests/ui/useless_concat.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
//@aux-build:proc_macros.rs
2+
13
#![warn(clippy::useless_concat)]
24
#![allow(clippy::print_literal)]
35

6+
extern crate proc_macros;
7+
use proc_macros::{external, with_span};
8+
49
macro_rules! my_concat {
510
($fmt:literal $(, $e:expr)*) => {
611
println!(concat!("ERROR: ", $fmt), $($e,)*);
@@ -9,12 +14,28 @@ macro_rules! my_concat {
914

1015
fn main() {
1116
let x = concat!(); //~ useless_concat
12-
let x = concat!("a"); //~ useless_concat
17+
let x = concat!('c'); //~ useless_concat
18+
let x = concat!('"'); //~ useless_concat
19+
let x = concat!(true); //~ useless_concat
20+
let x = concat!(1f32); //~ useless_concat
21+
let x = concat!(1.0000f32); //~ useless_concat
22+
let x = concat!(1_f32); //~ useless_concat
23+
let x = concat!(1_); //~ useless_concat
24+
let x = concat!(1.0000_f32); //~ useless_concat
25+
let x = concat!(1.0000_); //~ useless_concat
26+
let x = concat!("a\u{1f600}\n"); //~ useless_concat
27+
let x = concat!(r##"a"##); //~ useless_concat
1328
let x = concat!(1); //~ useless_concat
1429
println!("b: {}", concat!("a")); //~ useless_concat
1530
// Should not lint.
1631
let x = concat!("a", "b");
1732
let local_i32 = 1;
1833
my_concat!("{}", local_i32);
1934
let x = concat!(file!(), "#L", line!());
35+
36+
external! { concat!(); }
37+
with_span! {
38+
span
39+
concat!();
40+
}
2041
}

tests/ui/useless_concat.stderr

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unneeded use of `concat!` macro
2-
--> tests/ui/useless_concat.rs:11:13
2+
--> tests/ui/useless_concat.rs:16:13
33
|
44
LL | let x = concat!();
55
| ^^^^^^^^^ help: replace with: `""`
@@ -8,22 +8,82 @@ LL | let x = concat!();
88
= help: to override `-D warnings` add `#[allow(clippy::useless_concat)]`
99

1010
error: unneeded use of `concat!` macro
11-
--> tests/ui/useless_concat.rs:12:13
11+
--> tests/ui/useless_concat.rs:17:13
1212
|
13-
LL | let x = concat!("a");
14-
| ^^^^^^^^^^^^ help: replace with: `"a"`
13+
LL | let x = concat!('c');
14+
| ^^^^^^^^^^^^ help: replace with: `"c"`
1515

1616
error: unneeded use of `concat!` macro
17-
--> tests/ui/useless_concat.rs:13:13
17+
--> tests/ui/useless_concat.rs:18:13
18+
|
19+
LL | let x = concat!('"');
20+
| ^^^^^^^^^^^^ help: replace with: `"\""`
21+
22+
error: unneeded use of `concat!` macro
23+
--> tests/ui/useless_concat.rs:19:13
24+
|
25+
LL | let x = concat!(true);
26+
| ^^^^^^^^^^^^^ help: replace with: `"true"`
27+
28+
error: unneeded use of `concat!` macro
29+
--> tests/ui/useless_concat.rs:20:13
30+
|
31+
LL | let x = concat!(1f32);
32+
| ^^^^^^^^^^^^^ help: replace with: `"1"`
33+
34+
error: unneeded use of `concat!` macro
35+
--> tests/ui/useless_concat.rs:21:13
36+
|
37+
LL | let x = concat!(1.0000f32);
38+
| ^^^^^^^^^^^^^^^^^^ help: replace with: `"1.0000"`
39+
40+
error: unneeded use of `concat!` macro
41+
--> tests/ui/useless_concat.rs:22:13
42+
|
43+
LL | let x = concat!(1_f32);
44+
| ^^^^^^^^^^^^^^ help: replace with: `"1"`
45+
46+
error: unneeded use of `concat!` macro
47+
--> tests/ui/useless_concat.rs:23:13
48+
|
49+
LL | let x = concat!(1_);
50+
| ^^^^^^^^^^^ help: replace with: `"1"`
51+
52+
error: unneeded use of `concat!` macro
53+
--> tests/ui/useless_concat.rs:24:13
54+
|
55+
LL | let x = concat!(1.0000_f32);
56+
| ^^^^^^^^^^^^^^^^^^^ help: replace with: `"1.0000"`
57+
58+
error: unneeded use of `concat!` macro
59+
--> tests/ui/useless_concat.rs:25:13
60+
|
61+
LL | let x = concat!(1.0000_);
62+
| ^^^^^^^^^^^^^^^^ help: replace with: `"1.0000"`
63+
64+
error: unneeded use of `concat!` macro
65+
--> tests/ui/useless_concat.rs:26:13
66+
|
67+
LL | let x = concat!("a\u{1f600}\n");
68+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `"a😀\n"`
69+
70+
error: unneeded use of `concat!` macro
71+
--> tests/ui/useless_concat.rs:27:13
72+
|
73+
LL | let x = concat!(r##"a"##);
74+
| ^^^^^^^^^^^^^^^^^ help: replace with: `"a"`
75+
76+
error: unneeded use of `concat!` macro
77+
--> tests/ui/useless_concat.rs:28:13
1878
|
1979
LL | let x = concat!(1);
2080
| ^^^^^^^^^^ help: replace with: `"1"`
2181

2282
error: unneeded use of `concat!` macro
23-
--> tests/ui/useless_concat.rs:14:23
83+
--> tests/ui/useless_concat.rs:29:23
2484
|
2585
LL | println!("b: {}", concat!("a"));
2686
| ^^^^^^^^^^^^ help: replace with: `"a"`
2787

28-
error: aborting due to 4 previous errors
88+
error: aborting due to 14 previous errors
2989

0 commit comments

Comments
 (0)