Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ef587d2

Browse files
committed
[redundant_guards]: lint empty string checks
1 parent abf01e4 commit ef587d2

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

clippy_lints/src/matches/redundant_guards.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::path_to_local;
3-
use clippy_utils::source::snippet_with_applicability;
3+
use clippy_utils::source::snippet;
44
use clippy_utils::visitors::{for_each_expr, is_local_used};
55
use rustc_ast::{BorrowKind, LitKind};
66
use rustc_errors::Applicability;
@@ -9,6 +9,7 @@ use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, P
99
use rustc_lint::LateContext;
1010
use rustc_span::symbol::Ident;
1111
use rustc_span::Span;
12+
use std::borrow::Cow;
1213
use std::ops::ControlFlow;
1314

1415
use super::REDUNDANT_GUARDS;
@@ -41,7 +42,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
4142
(PatKind::Ref(..), None) | (_, Some(_)) => continue,
4243
_ => arm.pat.span,
4344
};
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+
);
4553
}
4654
// `Some(x) if let Some(2) = x`
4755
else if let Guard::IfLet(let_expr) = guard
@@ -52,7 +60,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
5260
(PatKind::Ref(..), None) | (_, Some(_)) => continue,
5361
_ => let_expr.pat.span,
5462
};
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+
);
5671
}
5772
// `Some(x) if x == Some(2)`
5873
// `Some(x) if Some(2) == x`
@@ -78,7 +93,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
7893
(ExprKind::AddrOf(..), None) | (_, Some(_)) => continue,
7994
_ => pat.span,
8095
};
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+
}
82115
}
83116
}
84117
}
@@ -134,19 +167,16 @@ fn emit_redundant_guards<'tcx>(
134167
cx: &LateContext<'tcx>,
135168
outer_arm: &Arm<'tcx>,
136169
guard_span: Span,
137-
pat_span: Span,
170+
binding_replacement: Cow<'static, str>,
138171
pat_binding: &PatBindingInfo,
139172
inner_guard: Option<Guard<'_>>,
140173
) {
141-
let mut app = Applicability::MaybeIncorrect;
142-
143174
span_lint_and_then(
144175
cx,
145176
REDUNDANT_GUARDS,
146177
guard_span.source_callsite(),
147178
"redundant guard",
148179
|diag| {
149-
let binding_replacement = snippet_with_applicability(cx, pat_span, "<binding_repl>", &mut app);
150180
let suggestion_span = match *pat_binding {
151181
PatBindingInfo {
152182
span,
@@ -170,14 +200,11 @@ fn emit_redundant_guards<'tcx>(
170200
Guard::IfLet(l) => ("if let", l.span),
171201
};
172202

173-
format!(
174-
" {prefix} {}",
175-
snippet_with_applicability(cx, span, "<guard>", &mut app),
176-
)
203+
format!(" {prefix} {}", snippet(cx, span, "<guard>"))
177204
}),
178205
),
179206
],
180-
app,
207+
Applicability::MaybeIncorrect,
181208
);
182209
},
183210
);

0 commit comments

Comments
 (0)