From f088e543cb51afa12c05097c131969d7962eca36 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Sun, 2 Oct 2022 06:30:49 +0000
Subject: [PATCH] Delay evaluating lint primary message until after it would be
 suppressed

---
 compiler/rustc_middle/src/lint.rs              |  5 ++++-
 src/test/ui/lint/auxiliary/trivial-cast-ice.rs |  7 +++++++
 src/test/ui/lint/trivial-cast-ice.rs           | 12 ++++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/lint/auxiliary/trivial-cast-ice.rs
 create mode 100644 src/test/ui/lint/trivial-cast-ice.rs

diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 328b7ad6a4954..41b8aeb48524e 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -354,7 +354,6 @@ pub fn struct_lint_level<'s, 'd>(
             (Level::Deny | Level::Forbid, None) => sess.diagnostic().struct_err_lint(""),
         };
 
-        err.set_primary_message(msg);
         err.set_is_lint();
 
         // If this code originates in a foreign macro, aka something that this crate
@@ -379,6 +378,10 @@ pub fn struct_lint_level<'s, 'd>(
             }
         }
 
+        // Delay evaluating and setting the primary message until after we've
+        // suppressed the lint due to macros.
+        err.set_primary_message(msg);
+
         // Lint diagnostics that are covered by the expect level will not be emitted outside
         // the compiler. It is therefore not necessary to add any information for the user.
         // This will therefore directly call the decorate function which will in turn emit
diff --git a/src/test/ui/lint/auxiliary/trivial-cast-ice.rs b/src/test/ui/lint/auxiliary/trivial-cast-ice.rs
new file mode 100644
index 0000000000000..ab2332d065655
--- /dev/null
+++ b/src/test/ui/lint/auxiliary/trivial-cast-ice.rs
@@ -0,0 +1,7 @@
+#[macro_export]
+macro_rules! foo {
+    () => {
+        let x: &Option<i32> = &Some(1);
+        let _y = x as *const Option<i32>;
+    }
+}
diff --git a/src/test/ui/lint/trivial-cast-ice.rs b/src/test/ui/lint/trivial-cast-ice.rs
new file mode 100644
index 0000000000000..f781fab2212cc
--- /dev/null
+++ b/src/test/ui/lint/trivial-cast-ice.rs
@@ -0,0 +1,12 @@
+// aux-build:trivial-cast-ice.rs
+// check-pass
+
+// Demonstrates the ICE in #102561
+
+#![deny(trivial_casts)]
+
+extern crate trivial_cast_ice;
+
+fn main() {
+    trivial_cast_ice::foo!();
+}