@@ -52,11 +52,24 @@ declare_lint_pass!(DuplicateMatchGuard => [DUPLICATE_MATCH_GUARD]);
52
52
53
53
impl < ' tcx > LateLintPass < ' tcx > for DuplicateMatchGuard {
54
54
fn check_arm ( & mut self , cx : & LateContext < ' tcx > , arm : & ' tcx Arm < ' tcx > ) {
55
- if let Some ( guard) = arm. guard
56
- && let ExprKind :: Block ( block, _) = arm. body . kind
57
- && block. stmts . is_empty ( )
58
- && let Some ( trailing_expr) = block. expr
59
- && let ExprKind :: If ( cond, then, None ) = trailing_expr. kind
55
+ let Some ( guard) = arm. guard else {
56
+ return ;
57
+ } ;
58
+
59
+ let ( arm_body_expr, body_has_block) = if let ExprKind :: Block ( block, _) = arm. body . kind {
60
+ if block. stmts . is_empty ( )
61
+ && let Some ( trailing_expr) = block. expr
62
+ {
63
+ ( trailing_expr, true )
64
+ } else {
65
+ // the body contains something other than the `if` clause -- bail out
66
+ return ;
67
+ }
68
+ } else {
69
+ ( arm. body , false )
70
+ } ;
71
+
72
+ if let ExprKind :: If ( cond, then, None ) = arm_body_expr. kind
60
73
&& eq_expr_value ( cx, guard, cond. peel_drop_temps ( ) )
61
74
{
62
75
let ExprKind :: Block ( then, _) = then. kind else {
@@ -70,15 +83,49 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateMatchGuard {
70
83
71
84
let sugg = snippet_with_applicability ( cx, then. span , ".." , & mut applicability) ;
72
85
73
- span_lint_and_sugg (
74
- cx,
75
- DUPLICATE_MATCH_GUARD ,
76
- trailing_expr. span ,
77
- "condition duplicates match guard" ,
78
- "remove the condition" ,
79
- sugg. to_string ( ) ,
80
- applicability,
81
- ) ;
86
+ if body_has_block {
87
+ // the common case:
88
+ // ```
89
+ // match 0u32 {
90
+ // 0 if true => {
91
+ // if true {
92
+ // return;
93
+ // }
94
+ // }
95
+ // }
96
+ // ```
97
+ //
98
+ // suggest removing the `if` _and_ the curlies of the inner brace,
99
+ // since the arm body already has braces
100
+ span_lint_and_sugg (
101
+ cx,
102
+ DUPLICATE_MATCH_GUARD ,
103
+ arm_body_expr. span ,
104
+ "condition duplicates match guard" ,
105
+ "remove the condition" ,
106
+ sugg. to_string ( ) ,
107
+ applicability,
108
+ ) ;
109
+ } else {
110
+ // the uncommon case (rusfmt would add the braces here automatically)
111
+ // ```
112
+ // match 0u32 {
113
+ // 0 if true => if true { return; }
114
+ // }
115
+ // ```
116
+ //
117
+ // suggest removing the `if` but _not_ the curlies of the inner brace,
118
+ // since there are no outer braces coming from the arm body
119
+ span_lint_and_sugg (
120
+ cx,
121
+ DUPLICATE_MATCH_GUARD ,
122
+ arm_body_expr. span ,
123
+ "condition duplicates match guard" ,
124
+ "remove the condition" ,
125
+ sugg. to_string ( ) ,
126
+ applicability,
127
+ ) ;
128
+ }
82
129
}
83
130
}
84
131
}
0 commit comments