about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/macro_metavars_in_unsafe.rs11
-rw-r--r--tests/ui-toml/macro_metavars_in_unsafe/default/test.rs16
2 files changed, 26 insertions, 1 deletions
diff --git a/clippy_lints/src/macro_metavars_in_unsafe.rs b/clippy_lints/src/macro_metavars_in_unsafe.rs
index 006addb987f..0f9d373f0a3 100644
--- a/clippy_lints/src/macro_metavars_in_unsafe.rs
+++ b/clippy_lints/src/macro_metavars_in_unsafe.rs
@@ -5,7 +5,7 @@ use itertools::Itertools;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, Level, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, SyntaxContext, sym};
 use std::collections::BTreeMap;
@@ -249,6 +249,15 @@ impl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe {
             })
             .flatten()
             .copied()
+            .inspect(|&unsafe_block| {
+                if let Level::Expect(id) = cx.tcx.lint_level_at_node(MACRO_METAVARS_IN_UNSAFE, unsafe_block).0 {
+                    // Since we're going to deduplicate expanded unsafe blocks by its enclosing macro definition soon,
+                    // which would lead to unfulfilled `#[expect()]`s in all other unsafe blocks that are filtered out
+                    // except for the one we emit the warning at, we must manually fulfill the lint
+                    // for all unsafe blocks here.
+                    cx.fulfill_expectation(id);
+                }
+            })
             .map(|id| {
                 // Remove the syntax context to hide "in this macro invocation" in the diagnostic.
                 // The invocation doesn't matter. Also we want to dedupe by the unsafe block and not by anything
diff --git a/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs b/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
index 2465fe45645..d3d5b0c103e 100644
--- a/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
+++ b/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
@@ -251,6 +251,16 @@ pub mod issue13219 {
     }
 }
 
+#[macro_export]
+macro_rules! issue14488 {
+    ($e:expr) => {
+        #[expect(clippy::macro_metavars_in_unsafe)]
+        unsafe {
+            $e
+        }
+    };
+}
+
 fn main() {
     allow_works!(1);
     simple!(1);
@@ -271,4 +281,10 @@ fn main() {
     multiple_unsafe_blocks!(1, 1, 1);
     unsafe_from_root_ctxt!(unsafe { 1 });
     nested_macros!(1, 1);
+
+    // These two invocations lead to two expanded unsafe blocks, each with an `#[expect]` on it.
+    // Only of them gets a warning, which used to result in an unfulfilled expectation for the other
+    // expanded unsafe block.
+    issue14488!(1);
+    issue14488!(2);
 }