about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKristof Mattei <864376+Kristof-Mattei@users.noreply.github.com>2025-07-17 15:44:30 -0700
committerKristof Mattei <864376+Kristof-Mattei@users.noreply.github.com>2025-07-17 16:47:44 -0700
commitb2c4e6de2fbcd8dccd60acc6cfbd0492e983dd6c (patch)
treed35fcdebe7ad4a492134fe3e57693f1c696593f9
parente62e27bf5bbae5d0ba596ae43356a7c9c988a067 (diff)
downloadrust-b2c4e6de2fbcd8dccd60acc6cfbd0492e983dd6c.tar.gz
rust-b2c4e6de2fbcd8dccd60acc6cfbd0492e983dd6c.zip
fix: ignore pattern_type_mismatch when external macro owns the match
changelog: [`pattern_type_mismatch`]: fix unwanted hit in external macro
-rw-r--r--clippy_lints/src/pattern_type_mismatch.rs6
-rw-r--r--tests/ui/pattern_type_mismatch/auxiliary/external.rs13
-rw-r--r--tests/ui/pattern_type_mismatch/syntax.rs9
-rw-r--r--tests/ui/pattern_type_mismatch/syntax.stderr18
4 files changed, 37 insertions, 9 deletions
diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs
index 19d9acfc930..4197680dd04 100644
--- a/clippy_lints/src/pattern_type_mismatch.rs
+++ b/clippy_lints/src/pattern_type_mismatch.rs
@@ -96,6 +96,12 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if let ExprKind::Match(_, arms, _) = expr.kind {
+            // if the match is generated by an external macro, the writer does not control
+            // how the scrutinee (`match &scrutiny { ... }`) is matched
+            if expr.span.in_external_macro(cx.sess().source_map()) {
+                return;
+            }
+
             for arm in arms {
                 let pat = &arm.pat;
                 if apply_lint(cx, pat, DerefPossible::Possible) {
diff --git a/tests/ui/pattern_type_mismatch/auxiliary/external.rs b/tests/ui/pattern_type_mismatch/auxiliary/external.rs
new file mode 100644
index 00000000000..cd27c5c74aa
--- /dev/null
+++ b/tests/ui/pattern_type_mismatch/auxiliary/external.rs
@@ -0,0 +1,13 @@
+//! **FAKE** external macro crate.
+
+#[macro_export]
+macro_rules! macro_with_match {
+    ( $p:pat ) => {
+        let something = ();
+
+        match &something {
+            $p => true,
+            _ => false,
+        }
+    };
+}
diff --git a/tests/ui/pattern_type_mismatch/syntax.rs b/tests/ui/pattern_type_mismatch/syntax.rs
index 49ea1d3f7a6..aa988a577df 100644
--- a/tests/ui/pattern_type_mismatch/syntax.rs
+++ b/tests/ui/pattern_type_mismatch/syntax.rs
@@ -6,6 +6,9 @@
     clippy::single_match
 )]
 
+//@aux-build:external.rs
+use external::macro_with_match;
+
 fn main() {}
 
 fn syntax_match() {
@@ -159,3 +162,9 @@ fn macro_expansion() {
     let value = &Some(23);
     matching_macro!(value);
 }
+
+fn external_macro_expansion() {
+    macro_with_match! {
+        ()
+    };
+}
diff --git a/tests/ui/pattern_type_mismatch/syntax.stderr b/tests/ui/pattern_type_mismatch/syntax.stderr
index cd604d604c1..636841e0a21 100644
--- a/tests/ui/pattern_type_mismatch/syntax.stderr
+++ b/tests/ui/pattern_type_mismatch/syntax.stderr
@@ -1,5 +1,5 @@
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:16:9
+  --> tests/ui/pattern_type_mismatch/syntax.rs:19:9
    |
 LL |         Some(_) => (),
    |         ^^^^^^^
@@ -9,7 +9,7 @@ LL |         Some(_) => (),
    = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:36:12
+  --> tests/ui/pattern_type_mismatch/syntax.rs:39:12
    |
 LL |     if let Some(_) = ref_value {}
    |            ^^^^^^^
@@ -17,7 +17,7 @@ LL |     if let Some(_) = ref_value {}
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:48:15
+  --> tests/ui/pattern_type_mismatch/syntax.rs:51:15
    |
 LL |     while let Some(_) = ref_value {
    |               ^^^^^^^
@@ -25,7 +25,7 @@ LL |     while let Some(_) = ref_value {
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:68:9
+  --> tests/ui/pattern_type_mismatch/syntax.rs:71:9
    |
 LL |     for (_a, _b) in slice.iter() {}
    |         ^^^^^^^^
@@ -33,7 +33,7 @@ LL |     for (_a, _b) in slice.iter() {}
    = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:79:9
+  --> tests/ui/pattern_type_mismatch/syntax.rs:82:9
    |
 LL |     let (_n, _m) = ref_value;
    |         ^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let (_n, _m) = ref_value;
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:89:12
+  --> tests/ui/pattern_type_mismatch/syntax.rs:92:12
    |
 LL |     fn foo((_a, _b): &(i32, i32)) {}
    |            ^^^^^^^^
@@ -49,7 +49,7 @@ LL |     fn foo((_a, _b): &(i32, i32)) {}
    = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:104:10
+  --> tests/ui/pattern_type_mismatch/syntax.rs:107:10
    |
 LL |     foo(|(_a, _b)| ());
    |          ^^^^^^^^
@@ -57,7 +57,7 @@ LL |     foo(|(_a, _b)| ());
    = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:121:9
+  --> tests/ui/pattern_type_mismatch/syntax.rs:124:9
    |
 LL |         Some(_) => (),
    |         ^^^^^^^
@@ -65,7 +65,7 @@ LL |         Some(_) => (),
    = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
 
 error: type of pattern does not match the expression type
-  --> tests/ui/pattern_type_mismatch/syntax.rs:142:17
+  --> tests/ui/pattern_type_mismatch/syntax.rs:145:17
    |
 LL |                 Some(_) => (),
    |                 ^^^^^^^