Added a lint as suggested in 6010 which recommends using contains()

instead of `find()` follows by `is_some()` on strings

Update clippy_lints/src/find_is_some_on_strs.rs
Co-authored-by: Takayuki Nakata <f.seasons017@gmail.com>

Update clippy_lints/src/methods/mod.rs
Co-authored-by: Philipp Krones <hello@philkrones.com>
This commit is contained in:
Ryan Sullivant 2020-10-05 21:23:36 -07:00
parent c4fc076e11
commit a1cf2d334d
4 changed files with 56 additions and 7 deletions

View file

@ -515,11 +515,11 @@ declare_clippy_lint! {
}
declare_clippy_lint! {
/// **What it does:** Checks for an iterator search (such as `find()`,
/// **What it does:** Checks for an iterator or string search (such as `find()`,
/// `position()`, or `rposition()`) followed by a call to `is_some()`.
///
/// **Why is this bad?** Readability, this can be written more concisely as
/// `_.any(_)`.
/// `_.any(_)` or `_.contains(_)`.
///
/// **Known problems:** None.
///
@ -535,7 +535,7 @@ declare_clippy_lint! {
/// ```
pub SEARCH_IS_SOME,
complexity,
"using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`"
"using an iterator or string search followed by `is_some()`, which is more succinctly expressed as a call to `any()` or `contains()`"
}
declare_clippy_lint! {
@ -3041,6 +3041,7 @@ fn lint_flat_map_identity<'tcx>(
}
/// lint searching an Iterator followed by `is_some()`
/// or calling `find()` on a string followed by `is_some()`
fn lint_search_is_some<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx hir::Expr<'_>,
@ -3094,6 +3095,37 @@ fn lint_search_is_some<'tcx>(
span_lint(cx, SEARCH_IS_SOME, expr.span, &msg);
}
}
// lint if `find()` is called by `String` or `&str`
else if search_method == "find" {
let is_string_or_str_slice = |e| {
let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
if is_type_diagnostic_item(cx, self_ty, sym!(string_type)) {
true
} else {
*self_ty.kind() == ty::Str
}
};
if_chain! {
if is_string_or_str_slice(&search_args[0]);
if is_string_or_str_slice(&search_args[1]);
then {
let msg = "called `is_some()` after calling `find()` \
on a string. This is more succinctly expressed by calling \
`contains()`.".to_string();
let mut applicability = Applicability::MachineApplicable;
let find_arg = snippet_with_applicability(cx, search_args[1].span, "..", &mut applicability);
span_lint_and_sugg(
cx,
SEARCH_IS_SOME,
method_span.with_hi(expr.span.hi()),
&msg,
"try this",
format!("contains({})", find_arg),
applicability,
);
}
}
}
}
/// Used for `lint_binary_expr_with_method_call`.