Skip to content

Commit 0b16881

Browse files
authored
fix: ignore pattern_type_mismatch when external macro owns the match (rust-lang#15306)
Don't trigger the `ignore_type_mismatch` lint when the `match scrutinee` is generated by a macro. If the macro generates ``` match &scrutinee { _ => {}, () => {}, } ``` We don't expect it to hit on `()`. Rust Playground example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=b23aca42440f006660bd7440d02db196 changelog: [`pattern_type_mismatch`]: fix unwanted hit in external macro
2 parents c8e333c + b2c4e6d commit 0b16881

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

clippy_lints/src/pattern_type_mismatch.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
9696

9797
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
9898
if let ExprKind::Match(_, arms, _) = expr.kind {
99+
// if the match is generated by an external macro, the writer does not control
100+
// how the scrutinee (`match &scrutiny { ... }`) is matched
101+
if expr.span.in_external_macro(cx.sess().source_map()) {
102+
return;
103+
}
104+
99105
for arm in arms {
100106
let pat = &arm.pat;
101107
if apply_lint(cx, pat, DerefPossible::Possible) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! **FAKE** external macro crate.
2+
3+
#[macro_export]
4+
macro_rules! macro_with_match {
5+
( $p:pat ) => {
6+
let something = ();
7+
8+
match &something {
9+
$p => true,
10+
_ => false,
11+
}
12+
};
13+
}

tests/ui/pattern_type_mismatch/syntax.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
clippy::single_match
77
)]
88

9+
//@aux-build:external.rs
10+
use external::macro_with_match;
11+
912
fn main() {}
1013

1114
fn syntax_match() {
@@ -159,3 +162,9 @@ fn macro_expansion() {
159162
let value = &Some(23);
160163
matching_macro!(value);
161164
}
165+
166+
fn external_macro_expansion() {
167+
macro_with_match! {
168+
()
169+
};
170+
}

tests/ui/pattern_type_mismatch/syntax.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: type of pattern does not match the expression type
2-
--> tests/ui/pattern_type_mismatch/syntax.rs:16:9
2+
--> tests/ui/pattern_type_mismatch/syntax.rs:19:9
33
|
44
LL | Some(_) => (),
55
| ^^^^^^^
@@ -9,63 +9,63 @@ LL | Some(_) => (),
99
= help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
1010

1111
error: type of pattern does not match the expression type
12-
--> tests/ui/pattern_type_mismatch/syntax.rs:36:12
12+
--> tests/ui/pattern_type_mismatch/syntax.rs:39:12
1313
|
1414
LL | if let Some(_) = ref_value {}
1515
| ^^^^^^^
1616
|
1717
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
1818

1919
error: type of pattern does not match the expression type
20-
--> tests/ui/pattern_type_mismatch/syntax.rs:48:15
20+
--> tests/ui/pattern_type_mismatch/syntax.rs:51:15
2121
|
2222
LL | while let Some(_) = ref_value {
2323
| ^^^^^^^
2424
|
2525
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
2626

2727
error: type of pattern does not match the expression type
28-
--> tests/ui/pattern_type_mismatch/syntax.rs:68:9
28+
--> tests/ui/pattern_type_mismatch/syntax.rs:71:9
2929
|
3030
LL | for (_a, _b) in slice.iter() {}
3131
| ^^^^^^^^
3232
|
3333
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
3434

3535
error: type of pattern does not match the expression type
36-
--> tests/ui/pattern_type_mismatch/syntax.rs:79:9
36+
--> tests/ui/pattern_type_mismatch/syntax.rs:82:9
3737
|
3838
LL | let (_n, _m) = ref_value;
3939
| ^^^^^^^^
4040
|
4141
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
4242

4343
error: type of pattern does not match the expression type
44-
--> tests/ui/pattern_type_mismatch/syntax.rs:89:12
44+
--> tests/ui/pattern_type_mismatch/syntax.rs:92:12
4545
|
4646
LL | fn foo((_a, _b): &(i32, i32)) {}
4747
| ^^^^^^^^
4848
|
4949
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
5050

5151
error: type of pattern does not match the expression type
52-
--> tests/ui/pattern_type_mismatch/syntax.rs:104:10
52+
--> tests/ui/pattern_type_mismatch/syntax.rs:107:10
5353
|
5454
LL | foo(|(_a, _b)| ());
5555
| ^^^^^^^^
5656
|
5757
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
5858

5959
error: type of pattern does not match the expression type
60-
--> tests/ui/pattern_type_mismatch/syntax.rs:121:9
60+
--> tests/ui/pattern_type_mismatch/syntax.rs:124:9
6161
|
6262
LL | Some(_) => (),
6363
| ^^^^^^^
6464
|
6565
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
6666

6767
error: type of pattern does not match the expression type
68-
--> tests/ui/pattern_type_mismatch/syntax.rs:142:17
68+
--> tests/ui/pattern_type_mismatch/syntax.rs:145:17
6969
|
7070
LL | Some(_) => (),
7171
| ^^^^^^^

0 commit comments

Comments
 (0)