1
1
use clippy_utils:: diagnostics:: span_lint_and_then;
2
2
use clippy_utils:: path_to_local;
3
- use clippy_utils:: source:: snippet_with_applicability ;
3
+ use clippy_utils:: source:: snippet ;
4
4
use clippy_utils:: visitors:: { for_each_expr, is_local_used} ;
5
5
use rustc_ast:: { BorrowKind , LitKind } ;
6
6
use rustc_errors:: Applicability ;
@@ -9,6 +9,7 @@ use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, P
9
9
use rustc_lint:: LateContext ;
10
10
use rustc_span:: symbol:: Ident ;
11
11
use rustc_span:: Span ;
12
+ use std:: borrow:: Cow ;
12
13
use std:: ops:: ControlFlow ;
13
14
14
15
use super :: REDUNDANT_GUARDS ;
@@ -41,7 +42,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
41
42
( PatKind :: Ref ( ..) , None ) | ( _, Some ( _) ) => continue ,
42
43
_ => arm. pat . span ,
43
44
} ;
44
- emit_redundant_guards ( cx, outer_arm, if_expr. span , pat_span, & binding, arm. guard ) ;
45
+ emit_redundant_guards (
46
+ cx,
47
+ outer_arm,
48
+ if_expr. span ,
49
+ snippet ( cx, pat_span, "<binding>" ) ,
50
+ & binding,
51
+ arm. guard ,
52
+ ) ;
45
53
}
46
54
// `Some(x) if let Some(2) = x`
47
55
else if let Guard :: IfLet ( let_expr) = guard
@@ -52,7 +60,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
52
60
( PatKind :: Ref ( ..) , None ) | ( _, Some ( _) ) => continue ,
53
61
_ => let_expr. pat . span ,
54
62
} ;
55
- emit_redundant_guards ( cx, outer_arm, let_expr. span , pat_span, & binding, None ) ;
63
+ emit_redundant_guards (
64
+ cx,
65
+ outer_arm,
66
+ let_expr. span ,
67
+ snippet ( cx, pat_span, "<binding>" ) ,
68
+ & binding,
69
+ None ,
70
+ ) ;
56
71
}
57
72
// `Some(x) if x == Some(2)`
58
73
// `Some(x) if Some(2) == x`
@@ -78,7 +93,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
78
93
( ExprKind :: AddrOf ( ..) , None ) | ( _, Some ( _) ) => continue ,
79
94
_ => pat. span ,
80
95
} ;
81
- emit_redundant_guards ( cx, outer_arm, if_expr. span , pat_span, & binding, None ) ;
96
+ emit_redundant_guards (
97
+ cx,
98
+ outer_arm,
99
+ if_expr. span ,
100
+ snippet ( cx, pat_span, "<binding>" ) ,
101
+ & binding,
102
+ None ,
103
+ ) ;
104
+ } else if let Guard :: If ( if_expr) = guard
105
+ && let ExprKind :: MethodCall ( path, recv, ..) = if_expr. kind
106
+ && let Some ( binding) = get_pat_binding ( cx, recv, outer_arm)
107
+ {
108
+ let ty = cx. typeck_results ( ) . expr_ty ( recv) . peel_refs ( ) ;
109
+
110
+ if path. ident . name == sym ! ( is_empty) && ty. is_str ( ) {
111
+ // `s if s.is_empty()` becomes ""
112
+
113
+ emit_redundant_guards ( cx, outer_arm, if_expr. span , r#""""# . into ( ) , & binding, None )
114
+ }
82
115
}
83
116
}
84
117
}
@@ -134,19 +167,16 @@ fn emit_redundant_guards<'tcx>(
134
167
cx : & LateContext < ' tcx > ,
135
168
outer_arm : & Arm < ' tcx > ,
136
169
guard_span : Span ,
137
- pat_span : Span ,
170
+ binding_replacement : Cow < ' static , str > ,
138
171
pat_binding : & PatBindingInfo ,
139
172
inner_guard : Option < Guard < ' _ > > ,
140
173
) {
141
- let mut app = Applicability :: MaybeIncorrect ;
142
-
143
174
span_lint_and_then (
144
175
cx,
145
176
REDUNDANT_GUARDS ,
146
177
guard_span. source_callsite ( ) ,
147
178
"redundant guard" ,
148
179
|diag| {
149
- let binding_replacement = snippet_with_applicability ( cx, pat_span, "<binding_repl>" , & mut app) ;
150
180
let suggestion_span = match * pat_binding {
151
181
PatBindingInfo {
152
182
span,
@@ -170,14 +200,11 @@ fn emit_redundant_guards<'tcx>(
170
200
Guard :: IfLet ( l) => ( "if let" , l. span) ,
171
201
} ;
172
202
173
- format!(
174
- " {prefix} {}" ,
175
- snippet_with_applicability( cx, span, "<guard>" , & mut app) ,
176
- )
203
+ format!( " {prefix} {}" , snippet( cx, span, "<guard>" ) )
177
204
} ) ,
178
205
) ,
179
206
] ,
180
- app ,
207
+ Applicability :: MaybeIncorrect ,
181
208
) ;
182
209
} ,
183
210
) ;
0 commit comments