From 53815d675078343b8db59fec5c35a38d0761d429 Mon Sep 17 00:00:00 2001 From: yanglsh Date: Tue, 2 Sep 2025 00:40:54 +0800 Subject: [PATCH] fix: `nonstandard_macro_braces` FN on macros with empty args --- clippy_lints/src/nonstandard_macro_braces.rs | 40 ++++++++++------- .../conf_nonstandard_macro_braces.fixed | 14 ++++++ .../conf_nonstandard_macro_braces.rs | 14 ++++++ .../conf_nonstandard_macro_braces.stderr | 44 ++++++++++++++----- 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs index 3a8a4dd0c713..fd20fa7c8464 100644 --- a/clippy_lints/src/nonstandard_macro_braces.rs +++ b/clippy_lints/src/nonstandard_macro_braces.rs @@ -115,34 +115,42 @@ impl EarlyLintPass for MacroBraces { } fn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBraces) -> Option { - let unnested_or_local = || { - !span.ctxt().outer_expn_data().call_site.from_expansion() + let unnested_or_local = |span: Span| { + !span.from_expansion() || span .macro_backtrace() .last() .is_some_and(|e| e.macro_def_id.is_some_and(DefId::is_local)) }; - let callsite_span = span.ctxt().outer_expn_data().call_site; - if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind + let mut span_expn = span.ctxt().outer_expn_data(); + loop { + if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span_expn.kind && let name = mac_name.as_str() + && let Some(&braces) = mac_braces.macro_braces.get(name) - && let Some(snip) = callsite_span.get_source_text(cx) + + && let Some(snip) = span_expn.call_site.get_source_text(cx) // we must check only invocation sites // https://github.com/rust-lang/rust-clippy/issues/7422 && let Some(macro_args_str) = snip.strip_prefix(name).and_then(|snip| snip.strip_prefix('!')) && let Some(old_open_brace @ ('{' | '(' | '[')) = macro_args_str.trim_start().chars().next() && old_open_brace != braces.0 - && unnested_or_local() - && !mac_braces.done.contains(&callsite_span) - { - Some(MacroInfo { - callsite_span, - callsite_snippet: snip, - old_open_brace, - braces, - }) - } else { - None + && unnested_or_local(span_expn.call_site) + && !mac_braces.done.contains(&span_expn.call_site) + { + return Some(MacroInfo { + callsite_span: span_expn.call_site, + callsite_snippet: snip, + old_open_brace, + braces, + }); + } + + if span_expn.call_site.ctxt().is_root() { + return None; + } + + span_expn = span_expn.call_site.ctxt().outer_expn_data(); } } diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed index 419e62f92f46..3683e826aa92 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed @@ -1,6 +1,7 @@ //@aux-build:proc_macro_derive.rs #![warn(clippy::nonstandard_macro_braces)] +#![allow(clippy::println_empty_string)] extern crate proc_macro_derive; extern crate quote; @@ -75,3 +76,16 @@ fn issue9913() { [0]; // separate statement, not indexing into the result of println. //~^^ nonstandard_macro_braces } + +fn issue15594() { + println!(); + println!(""); + println!(); + //~^ nonstandard_macro_braces + println!(""); + //~^ nonstandard_macro_braces + println!(); + //~^ nonstandard_macro_braces + println!(""); + //~^ nonstandard_macro_braces +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs index b0bbced4ea3c..c1779dceff17 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs @@ -1,6 +1,7 @@ //@aux-build:proc_macro_derive.rs #![warn(clippy::nonstandard_macro_braces)] +#![allow(clippy::println_empty_string)] extern crate proc_macro_derive; extern crate quote; @@ -75,3 +76,16 @@ fn issue9913() { [0]; // separate statement, not indexing into the result of println. //~^^ nonstandard_macro_braces } + +fn issue15594() { + println!(); + println!(""); + println![]; + //~^ nonstandard_macro_braces + println![""]; + //~^ nonstandard_macro_braces + println! {}; + //~^ nonstandard_macro_braces + println! {""}; + //~^ nonstandard_macro_braces +} diff --git a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr index 87325f05c9bc..2488f7fa01e5 100644 --- a/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr +++ b/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr @@ -1,5 +1,5 @@ error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:44:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:45:13 | LL | let _ = vec! {1, 2, 3}; | ^^^^^^^^^^^^^^ help: consider writing: `vec![1, 2, 3]` @@ -8,31 +8,31 @@ LL | let _ = vec! {1, 2, 3}; = help: to override `-D warnings` add `#[allow(clippy::nonstandard_macro_braces)]` error: use of irregular braces for `format!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:46:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:47:13 | LL | let _ = format!["ugh {} stop being such a good compiler", "hello"]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `format!("ugh {} stop being such a good compiler", "hello")` error: use of irregular braces for `matches!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:48:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:49:13 | LL | let _ = matches!{{}, ()}; | ^^^^^^^^^^^^^^^^ help: consider writing: `matches!({}, ())` error: use of irregular braces for `quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:50:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:51:13 | LL | let _ = quote!(let x = 1;); | ^^^^^^^^^^^^^^^^^^ help: consider writing: `quote!{let x = 1;}` error: use of irregular braces for `quote::quote!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:52:13 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:53:13 | LL | let _ = quote::quote!(match match match); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `quote::quote!{match match match}` error: use of irregular braces for `vec!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:18:9 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:19:9 | LL | vec!{0, 0, 0} | ^^^^^^^^^^^^^ help: consider writing: `vec![0, 0, 0]` @@ -43,22 +43,46 @@ LL | let _ = test!(); // trigger when macro def is inside our own crate = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error: use of irregular braces for `type_pos!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:62:12 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:63:12 | LL | let _: type_pos!(usize) = vec![]; | ^^^^^^^^^^^^^^^^ help: consider writing: `type_pos![usize]` error: use of irregular braces for `eprint!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:65:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:66:5 | LL | eprint!("test if user config overrides defaults"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `eprint!["test if user config overrides defaults"]` error: use of irregular braces for `println!` macro - --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:74:5 + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:75:5 | LL | println! {"hello world"} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `println!("hello world");` -error: aborting due to 9 previous errors +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:83:5 + | +LL | println![]; + | ^^^^^^^^^^ help: consider writing: `println!()` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:85:5 + | +LL | println![""]; + | ^^^^^^^^^^^^ help: consider writing: `println!("")` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:87:5 + | +LL | println! {}; + | ^^^^^^^^^^^ help: consider writing: `println!()` + +error: use of irregular braces for `println!` macro + --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:89:5 + | +LL | println! {""}; + | ^^^^^^^^^^^^^ help: consider writing: `println!("")` + +error: aborting due to 13 previous errors