From 7b06d2b776c401f66190509bd61804956426f9b0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 29 Dec 2024 20:10:51 +0100 Subject: Move `concat` macro path into `clippy_utils::paths` --- clippy_utils/src/paths.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'clippy_utils') diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index e5179e479cc..9c909033447 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -129,6 +129,7 @@ path_macros! { // Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items. pub static ALIGN_OF: PathLookup = value_path!(core::mem::align_of); pub static CHAR_TO_DIGIT: PathLookup = value_path!(char::to_digit); +pub static CONCAT: PathLookup = value_path!(core::macros::builtin::concat); pub static IO_ERROR_NEW: PathLookup = value_path!(std::io::Error::new); pub static IO_ERRORKIND_OTHER_CTOR: PathLookup = value_path!(std::io::ErrorKind::Other); pub static ITER_STEP: PathLookup = type_path!(core::iter::Step); -- cgit 1.4.1-3-g733a5 From 0d25090d262cd506d4c4809f3a534d4d8b318870 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 2 May 2025 17:32:48 +0200 Subject: Improve code and apply suggestions --- clippy_lints/src/useless_concat.rs | 29 +++++++-------- clippy_utils/src/paths.rs | 2 +- tests/ui/useless_concat.fixed | 21 +++++++++++ tests/ui/useless_concat.rs | 23 +++++++++++- tests/ui/useless_concat.stderr | 74 ++++++++++++++++++++++++++++++++++---- 5 files changed, 123 insertions(+), 26 deletions(-) (limited to 'clippy_utils') diff --git a/clippy_lints/src/useless_concat.rs b/clippy_lints/src/useless_concat.rs index 4a818532f17..1ed1fbb3b9c 100644 --- a/clippy_lints/src/useless_concat.rs +++ b/clippy_lints/src/useless_concat.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::macro_backtrace; use clippy_utils::paths::CONCAT; use clippy_utils::source::snippet_opt; -use clippy_utils::{match_def_path, tokenize_with_text}; +use clippy_utils::tokenize_with_text; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; @@ -25,7 +25,7 @@ declare_clippy_lint! { /// ```no_run /// let x = "a"; /// ``` - #[clippy::version = "1.85.0"] + #[clippy::version = "1.89.0"] pub USELESS_CONCAT, complexity, "checks that the `concat` macro has at least two arguments" @@ -39,11 +39,11 @@ impl LateLintPass<'_> for UselessConcat { if expr.span.from_expansion() // Check that it's a string literal. && let ExprKind::Lit(lit) = expr.kind - && let LitKind::Str(_, _) = lit.node + && let LitKind::Str(lit_s, _) = lit.node // Get the direct parent of the expression. && let Some(macro_call) = macro_backtrace(expr.span).next() // Check if the `concat` macro from the `core` library. - && match_def_path(cx, macro_call.def_id, &CONCAT) + && CONCAT.matches(cx, macro_call.def_id) // We get the original code to parse it. && let Some(original_code) = snippet_opt(cx, macro_call.span) // This check allows us to ensure that the code snippet: @@ -68,7 +68,13 @@ impl LateLintPass<'_> for UselessConcat { } literal = Some(token_s); }, - TokenKind::Ident => nb_idents += 1, + TokenKind::Ident => { + if token_s == "true" || token_s == "false" { + literal = Some(token_s); + } else { + nb_idents += 1; + } + }, TokenKind::Comma => { nb_commas += 1; if nb_commas > 1 { @@ -81,17 +87,6 @@ impl LateLintPass<'_> for UselessConcat { _ => {}, } } - let literal = match literal { - Some(lit) => { - // Literals can also be number, so we need to check this case too. - if lit.starts_with('"') { - lit.to_string() - } else { - format!("\"{lit}\"") - } - }, - None => "\"\"".to_string(), - }; // There should always be the ident of the `concat` macro. if nb_idents == 1 { span_lint_and_sugg( @@ -100,7 +95,7 @@ impl LateLintPass<'_> for UselessConcat { macro_call.span, "unneeded use of `concat!` macro", "replace with", - literal, + format!("{lit_s:?}"), Applicability::MachineApplicable, ); } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 9c909033447..9d7f3086b05 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -129,7 +129,7 @@ path_macros! { // Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items. pub static ALIGN_OF: PathLookup = value_path!(core::mem::align_of); pub static CHAR_TO_DIGIT: PathLookup = value_path!(char::to_digit); -pub static CONCAT: PathLookup = value_path!(core::macros::builtin::concat); +pub static CONCAT: PathLookup = macro_path!(core::concat); pub static IO_ERROR_NEW: PathLookup = value_path!(std::io::Error::new); pub static IO_ERRORKIND_OTHER_CTOR: PathLookup = value_path!(std::io::ErrorKind::Other); pub static ITER_STEP: PathLookup = type_path!(core::iter::Step); diff --git a/tests/ui/useless_concat.fixed b/tests/ui/useless_concat.fixed index 0400b1fcd6d..360b6f6ce82 100644 --- a/tests/ui/useless_concat.fixed +++ b/tests/ui/useless_concat.fixed @@ -1,6 +1,11 @@ +//@aux-build:proc_macros.rs + #![warn(clippy::useless_concat)] #![allow(clippy::print_literal)] +extern crate proc_macros; +use proc_macros::{external, with_span}; + macro_rules! my_concat { ($fmt:literal $(, $e:expr)*) => { println!(concat!("ERROR: ", $fmt), $($e,)*); @@ -9,6 +14,16 @@ macro_rules! my_concat { fn main() { let x = ""; //~ useless_concat + let x = "c"; //~ useless_concat + let x = "\""; //~ useless_concat + let x = "true"; //~ useless_concat + let x = "1"; //~ useless_concat + let x = "1.0000"; //~ useless_concat + let x = "1"; //~ useless_concat + let x = "1"; //~ useless_concat + let x = "1.0000"; //~ useless_concat + let x = "1.0000"; //~ useless_concat + let x = "a😀\n"; //~ useless_concat let x = "a"; //~ useless_concat let x = "1"; //~ useless_concat println!("b: {}", "a"); //~ useless_concat @@ -17,4 +32,10 @@ fn main() { let local_i32 = 1; my_concat!("{}", local_i32); let x = concat!(file!(), "#L", line!()); + + external! { concat!(); } + with_span! { + span + concat!(); + } } diff --git a/tests/ui/useless_concat.rs b/tests/ui/useless_concat.rs index 02e68568c10..338d20a48ae 100644 --- a/tests/ui/useless_concat.rs +++ b/tests/ui/useless_concat.rs @@ -1,6 +1,11 @@ +//@aux-build:proc_macros.rs + #![warn(clippy::useless_concat)] #![allow(clippy::print_literal)] +extern crate proc_macros; +use proc_macros::{external, with_span}; + macro_rules! my_concat { ($fmt:literal $(, $e:expr)*) => { println!(concat!("ERROR: ", $fmt), $($e,)*); @@ -9,7 +14,17 @@ macro_rules! my_concat { fn main() { let x = concat!(); //~ useless_concat - let x = concat!("a"); //~ useless_concat + let x = concat!('c'); //~ useless_concat + let x = concat!('"'); //~ useless_concat + let x = concat!(true); //~ useless_concat + let x = concat!(1f32); //~ useless_concat + let x = concat!(1.0000f32); //~ useless_concat + let x = concat!(1_f32); //~ useless_concat + let x = concat!(1_); //~ useless_concat + let x = concat!(1.0000_f32); //~ useless_concat + let x = concat!(1.0000_); //~ useless_concat + let x = concat!("a\u{1f600}\n"); //~ useless_concat + let x = concat!(r##"a"##); //~ useless_concat let x = concat!(1); //~ useless_concat println!("b: {}", concat!("a")); //~ useless_concat // Should not lint. @@ -17,4 +32,10 @@ fn main() { let local_i32 = 1; my_concat!("{}", local_i32); let x = concat!(file!(), "#L", line!()); + + external! { concat!(); } + with_span! { + span + concat!(); + } } diff --git a/tests/ui/useless_concat.stderr b/tests/ui/useless_concat.stderr index 63038b6660b..43d6d9ff579 100644 --- a/tests/ui/useless_concat.stderr +++ b/tests/ui/useless_concat.stderr @@ -1,5 +1,5 @@ error: unneeded use of `concat!` macro - --> tests/ui/useless_concat.rs:11:13 + --> tests/ui/useless_concat.rs:16:13 | LL | let x = concat!(); | ^^^^^^^^^ help: replace with: `""` @@ -8,22 +8,82 @@ LL | let x = concat!(); = help: to override `-D warnings` add `#[allow(clippy::useless_concat)]` error: unneeded use of `concat!` macro - --> tests/ui/useless_concat.rs:12:13 + --> tests/ui/useless_concat.rs:17:13 | -LL | let x = concat!("a"); - | ^^^^^^^^^^^^ help: replace with: `"a"` +LL | let x = concat!('c'); + | ^^^^^^^^^^^^ help: replace with: `"c"` error: unneeded use of `concat!` macro - --> tests/ui/useless_concat.rs:13:13 + --> tests/ui/useless_concat.rs:18:13 + | +LL | let x = concat!('"'); + | ^^^^^^^^^^^^ help: replace with: `"\""` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:19:13 + | +LL | let x = concat!(true); + | ^^^^^^^^^^^^^ help: replace with: `"true"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:20:13 + | +LL | let x = concat!(1f32); + | ^^^^^^^^^^^^^ help: replace with: `"1"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:21:13 + | +LL | let x = concat!(1.0000f32); + | ^^^^^^^^^^^^^^^^^^ help: replace with: `"1.0000"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:22:13 + | +LL | let x = concat!(1_f32); + | ^^^^^^^^^^^^^^ help: replace with: `"1"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:23:13 + | +LL | let x = concat!(1_); + | ^^^^^^^^^^^ help: replace with: `"1"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:24:13 + | +LL | let x = concat!(1.0000_f32); + | ^^^^^^^^^^^^^^^^^^^ help: replace with: `"1.0000"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:25:13 + | +LL | let x = concat!(1.0000_); + | ^^^^^^^^^^^^^^^^ help: replace with: `"1.0000"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:26:13 + | +LL | let x = concat!("a\u{1f600}\n"); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `"a😀\n"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:27:13 + | +LL | let x = concat!(r##"a"##); + | ^^^^^^^^^^^^^^^^^ help: replace with: `"a"` + +error: unneeded use of `concat!` macro + --> tests/ui/useless_concat.rs:28:13 | LL | let x = concat!(1); | ^^^^^^^^^^ help: replace with: `"1"` error: unneeded use of `concat!` macro - --> tests/ui/useless_concat.rs:14:23 + --> tests/ui/useless_concat.rs:29:23 | LL | println!("b: {}", concat!("a")); | ^^^^^^^^^^^^ help: replace with: `"a"` -error: aborting due to 4 previous errors +error: aborting due to 14 previous errors -- cgit 1.4.1-3-g733a5