From 1d110f8c2e2221f1ea6a8c51d1d79cc8a3b65115 Mon Sep 17 00:00:00 2001
From: Devin Ragotzy <devin.ragotzy@gmail.com>
Date: Sun, 4 Jul 2021 07:06:23 -0400
Subject: [PATCH] Fix emitting in nested (proc_)macros for
 nonstandard_macro_braces lint

---
 clippy_lints/src/nonstandard_macro_braces.rs  | 12 +++++---
 .../auxiliary/proc_macro_derive.rs            | 18 ++++++++++++
 .../conf_nonstandard_macro_braces.rs          |  8 ++++++
 .../conf_nonstandard_macro_braces.stderr      | 28 +++++++++----------
 4 files changed, 48 insertions(+), 18 deletions(-)
 create mode 100644 tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs

diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs
index c62b5e6d007..043e7fa30d6 100644
--- a/clippy_lints/src/nonstandard_macro_braces.rs
+++ b/clippy_lints/src/nonstandard_macro_braces.rs
@@ -92,14 +92,18 @@ impl EarlyLintPass for MacroBraces {
     }
 }
 
-fn is_offending_macro<'a>(cx: &EarlyContext<'_>, span: Span, this: &'a MacroBraces) -> Option<MacroInfo<'a>> {
+fn is_offending_macro<'a>(cx: &EarlyContext<'_>, span: Span, mac_braces: &'a MacroBraces) -> Option<MacroInfo<'a>> {
     if_chain! {
         if in_macro(span);
-        if let Some((name, braces)) = find_matching_macro(span, &this.macro_braces);
+        if let Some((name, braces)) = find_matching_macro(span, &mac_braces.macro_braces);
         if let Some(snip) = snippet_opt(cx, span.ctxt().outer_expn_data().call_site);
-        let c = snip.replace(" ", ""); // make formatting consistent
+        // we must check only invocation sites
+        // https://github.com/rust-lang/rust-clippy/issues/7422
+        if snip.starts_with(name);
+        // make formatting consistent
+        let c = snip.replace(" ", "");
         if !c.starts_with(&format!("{}!{}", name, braces.0));
-        if !this.done.contains(&span.ctxt().outer_expn_data().call_site);
+        if !mac_braces.done.contains(&span.ctxt().outer_expn_data().call_site);
         then {
             Some((name, braces, snip))
         } else {
diff --git a/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs b/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs
new file mode 100644
index 00000000000..6452189a461
--- /dev/null
+++ b/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs
@@ -0,0 +1,18 @@
+// compile-flags: --emit=link
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(DeriveSomething)]
+pub fn derive(_: TokenStream) -> TokenStream {
+    "fn _f() -> Vec<u8> { vec![] }".parse().unwrap()
+}
+
+#[proc_macro]
+pub fn foo_bar(_: TokenStream) -> TokenStream {
+    "fn issue_7422() { eprintln!(); }".parse().unwrap()
+}
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 770c65aa602..e9f042ddefc 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,9 +1,17 @@
+// aux-build:proc_macro_derive.rs
+
 #![warn(clippy::nonstandard_macro_braces)]
 
+extern crate proc_macro_derive;
 extern crate quote;
 
 use quote::quote;
 
+#[derive(proc_macro_derive::DeriveSomething)]
+pub struct S;
+
+proc_macro_derive::foo_bar!();
+
 #[rustfmt::skip]
 macro_rules! test {
     () => {
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 7bcd1829524..86063a08280 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,54 +1,54 @@
 error: use of irregular braces for `vec!` macro
-  --> $DIR/conf_nonstandard_macro_braces.rs:29:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:37:13
    |
 LL |     let _ = vec! {1, 2, 3};
    |             ^^^^^^^^^^^^^^
    |
    = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings`
 help: consider writing `vec![1, 2, 3]`
-  --> $DIR/conf_nonstandard_macro_braces.rs:29:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:37:13
    |
 LL |     let _ = vec! {1, 2, 3};
    |             ^^^^^^^^^^^^^^
 
 error: use of irregular braces for `format!` macro
-  --> $DIR/conf_nonstandard_macro_braces.rs:30:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:38:13
    |
 LL |     let _ = format!["ugh {} stop being such a good compiler", "hello"];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider writing `format!("ugh () stop being such a good compiler", "hello")`
-  --> $DIR/conf_nonstandard_macro_braces.rs:30:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:38:13
    |
 LL |     let _ = format!["ugh {} stop being such a good compiler", "hello"];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: use of irregular braces for `quote!` macro
-  --> $DIR/conf_nonstandard_macro_braces.rs:31:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:39:13
    |
 LL |     let _ = quote!(let x = 1;);
    |             ^^^^^^^^^^^^^^^^^^
    |
 help: consider writing `quote! {let x = 1;}`
-  --> $DIR/conf_nonstandard_macro_braces.rs:31:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:39:13
    |
 LL |     let _ = quote!(let x = 1;);
    |             ^^^^^^^^^^^^^^^^^^
 
 error: use of irregular braces for `quote::quote!` macro
-  --> $DIR/conf_nonstandard_macro_braces.rs:32:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:40:13
    |
 LL |     let _ = quote::quote!(match match match);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider writing `quote::quote! {match match match}`
-  --> $DIR/conf_nonstandard_macro_braces.rs:32:13
+  --> $DIR/conf_nonstandard_macro_braces.rs:40:13
    |
 LL |     let _ = quote::quote!(match match match);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: use of irregular braces for `vec!` macro
-  --> $DIR/conf_nonstandard_macro_braces.rs:10:9
+  --> $DIR/conf_nonstandard_macro_braces.rs:18:9
    |
 LL |         vec!{0, 0, 0}
    |         ^^^^^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = test!();
    |             ------- in this macro invocation
    |
 help: consider writing `vec![0, 0, 0]`
-  --> $DIR/conf_nonstandard_macro_braces.rs:10:9
+  --> $DIR/conf_nonstandard_macro_braces.rs:18:9
    |
 LL |         vec!{0, 0, 0}
    |         ^^^^^^^^^^^^^
@@ -67,25 +67,25 @@ LL |     let _ = test!();
    = 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
-  --> $DIR/conf_nonstandard_macro_braces.rs:41:12
+  --> $DIR/conf_nonstandard_macro_braces.rs:49:12
    |
 LL |     let _: type_pos!(usize) = vec![];
    |            ^^^^^^^^^^^^^^^^
    |
 help: consider writing `type_pos![usize]`
-  --> $DIR/conf_nonstandard_macro_braces.rs:41:12
+  --> $DIR/conf_nonstandard_macro_braces.rs:49:12
    |
 LL |     let _: type_pos!(usize) = vec![];
    |            ^^^^^^^^^^^^^^^^
 
 error: use of irregular braces for `eprint!` macro
-  --> $DIR/conf_nonstandard_macro_braces.rs:43:5
+  --> $DIR/conf_nonstandard_macro_braces.rs:51:5
    |
 LL |     eprint!("test if user config overrides defaults");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider writing `eprint!["test if user config overrides defaults"];`
-  --> $DIR/conf_nonstandard_macro_braces.rs:43:5
+  --> $DIR/conf_nonstandard_macro_braces.rs:51:5
    |
 LL |     eprint!("test if user config overrides defaults");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^