Skip to content

Commit a37af06

Browse files
committed
Removing false positive for the match_single_binding lint
* Applying suggested changes from the PR
1 parent 18c5ea4 commit a37af06

File tree

4 files changed

+93
-3
lines changed

4 files changed

+93
-3
lines changed

clippy_lints/src/matches.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::utils::usage::is_unused;
44
use crate::utils::{
55
expr_block, get_arg_name, get_parent_expr, in_macro, indent_of, is_allowed, is_expn_of, is_refutable,
66
is_type_diagnostic_item, is_wild, match_qpath, match_type, match_var, meets_msrv, multispan_sugg, remove_blocks,
7-
snippet, snippet_block, snippet_with_applicability, span_lint_and_help, span_lint_and_note, span_lint_and_sugg,
8-
span_lint_and_then,
7+
snippet, snippet_block, snippet_opt, snippet_with_applicability, span_lint_and_help, span_lint_and_note,
8+
span_lint_and_sugg, span_lint_and_then,
99
};
1010
use crate::utils::{paths, search_same, SpanlessEq, SpanlessHash};
1111
use if_chain::if_chain;
@@ -1237,6 +1237,24 @@ fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[A
12371237
if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
12381238
return;
12391239
}
1240+
1241+
// HACK:
1242+
// This is a hack to deal with arms that are excluded by macros like `#[cfg]`. It is only used here
1243+
// to prevent false positives as there is currently no better way to detect if code was excluded by
1244+
// a macro. See PR #6435
1245+
if_chain! {
1246+
if let Some(match_snippet) = snippet_opt(cx, expr.span);
1247+
if let Some(arm_snippet) = snippet_opt(cx, arms[0].span);
1248+
if let Some(ex_snippet) = snippet_opt(cx, ex.span);
1249+
let rest_snippet = match_snippet.replace(&arm_snippet, "").replace(&ex_snippet, "");
1250+
if rest_snippet.contains("=>");
1251+
then {
1252+
// The code it self contains another thick arrow "=>"
1253+
// -> Either another arm or a comment
1254+
return;
1255+
}
1256+
}
1257+
12401258
let matched_vars = ex.span;
12411259
let bind_names = arms[0].pat.span;
12421260
let match_body = remove_blocks(&arms[0].body);

tests/ui/match_single_binding.fixed

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,32 @@ fn main() {
8787
unwrapped
8888
})
8989
.collect::<Vec<u8>>();
90+
// Ok
91+
let x = 1;
92+
match x {
93+
#[cfg(disabled_feature)]
94+
0 => println!("Disabled branch"),
95+
_ => println!("Enabled branch"),
96+
}
97+
// Lint
98+
let x = 1;
99+
let y = 1;
100+
println!("Single branch");
101+
// Ok
102+
let x = 1;
103+
let y = 1;
104+
match match y {
105+
0 => 1,
106+
_ => 2,
107+
} {
108+
#[cfg(disabled_feature)]
109+
0 => println!("Array index start"),
110+
_ => println!("Not an array index start"),
111+
}
112+
// False negative
113+
let x = 1;
114+
match x {
115+
// =>
116+
_ => println!("Not an array index start"),
117+
}
90118
}

tests/ui/match_single_binding.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,37 @@ fn main() {
9999
unwrapped => unwrapped,
100100
})
101101
.collect::<Vec<u8>>();
102+
// Ok
103+
let x = 1;
104+
match x {
105+
#[cfg(disabled_feature)]
106+
0 => println!("Disabled branch"),
107+
_ => println!("Enabled branch"),
108+
}
109+
// Lint
110+
let x = 1;
111+
let y = 1;
112+
match match y {
113+
0 => 1,
114+
_ => 2,
115+
} {
116+
_ => println!("Single branch"),
117+
}
118+
// Ok
119+
let x = 1;
120+
let y = 1;
121+
match match y {
122+
0 => 1,
123+
_ => 2,
124+
} {
125+
#[cfg(disabled_feature)]
126+
0 => println!("Array index start"),
127+
_ => println!("Not an array index start"),
128+
}
129+
// False negative
130+
let x = 1;
131+
match x {
132+
// =>
133+
_ => println!("Not an array index start"),
134+
}
102135
}

tests/ui/match_single_binding.stderr

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,5 +167,16 @@ LL | unwrapped
167167
LL | })
168168
|
169169

170-
error: aborting due to 11 previous errors
170+
error: this match could be replaced by its body itself
171+
--> $DIR/match_single_binding.rs:112:5
172+
|
173+
LL | / match match y {
174+
LL | | 0 => 1,
175+
LL | | _ => 2,
176+
LL | | } {
177+
LL | | _ => println!("Single branch"),
178+
LL | | }
179+
| |_____^ help: consider using the match body instead: `println!("Single branch");`
180+
181+
error: aborting due to 12 previous errors
171182

0 commit comments

Comments
 (0)