Skip to content

Commit

Permalink
make slice_iter_any lint universal
Browse files Browse the repository at this point in the history
  • Loading branch information
lapla-cogito committed Dec 13, 2024
1 parent c1d5108 commit 86fee9a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 71 deletions.
2 changes: 1 addition & 1 deletion clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::methods::SHOULD_IMPLEMENT_TRAIT_INFO,
crate::methods::SINGLE_CHAR_ADD_STR_INFO,
crate::methods::SKIP_WHILE_NEXT_INFO,
crate::methods::SLICE_ITER_ANY_INFO,
crate::methods::STABLE_SORT_PRIMITIVE_INFO,
crate::methods::STRING_EXTEND_CHARS_INFO,
crate::methods::STRING_LIT_CHARS_ANY_INFO,
Expand Down Expand Up @@ -677,6 +676,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::single_range_in_vec_init::SINGLE_RANGE_IN_VEC_INIT_INFO,
crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO,
crate::size_of_ref::SIZE_OF_REF_INFO,
crate::slice_iter_any::SLICE_ITER_ANY_INFO,
crate::slow_vector_initialization::SLOW_VECTOR_INITIALIZATION_INFO,
crate::std_instead_of_core::ALLOC_INSTEAD_OF_CORE_INFO,
crate::std_instead_of_core::STD_INSTEAD_OF_ALLOC_INFO,
Expand Down
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ mod single_component_path_imports;
mod single_range_in_vec_init;
mod size_of_in_element_count;
mod size_of_ref;
mod slice_iter_any;
mod slow_vector_initialization;
mod std_instead_of_core;
mod string_patterns;
Expand Down Expand Up @@ -967,5 +968,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp));
store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound));
store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf)));
store.register_late_pass(|_| Box::new(slice_iter_any::SliceIterAny));
// add lints here, do not remove this comment, it's used in `new_lint`
}
28 changes: 0 additions & 28 deletions clippy_lints/src/methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ mod single_char_add_str;
mod single_char_insert_string;
mod single_char_push_string;
mod skip_while_next;
mod slice_iter_any;
mod stable_sort_primitive;
mod str_split;
mod str_splitn;
Expand Down Expand Up @@ -4285,31 +4284,6 @@ declare_clippy_lint! {
"map of a trivial closure (not dependent on parameter) over a range"
}

declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `iter().any()` on slices of `u8` or `i8` and suggests using `contains()` instead.
///
/// ### Why is this bad?
/// `iter().any()` on slices of `u8` or `i8` is optimized to use `memchr`.
///
/// ### Example
/// ```no_run
/// fn foo(values: &[u8]) -> bool {
/// values.iter().any(|&v| v == 10)
/// }
/// ```
/// Use instead:
/// ```no_run
/// fn foo(values: &[u8]) -> bool {
/// values.contains(&10)
/// }
/// ```
#[clippy::version = "1.85.0"]
pub SLICE_ITER_ANY,
perf,
"using `contains()` instead of `iter().any()` on u8/i8 slices is more efficient"
}

pub struct Methods {
avoid_breaking_exported_api: bool,
msrv: Msrv,
Expand Down Expand Up @@ -4475,7 +4449,6 @@ impl_lint_pass!(Methods => [
MAP_ALL_ANY_IDENTITY,
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
UNNECESSARY_MAP_OR,
SLICE_ITER_ANY,
]);

/// Extracts a method call name, args, and `Span` of the method name.
Expand Down Expand Up @@ -4710,7 +4683,6 @@ impl Methods {
("any", [arg]) => {
unused_enumerate_index::check(cx, expr, recv, arg);
needless_character_iteration::check(cx, expr, recv, arg, false);
slice_iter_any::check(cx, expr);
match method_call(recv) {
Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(
cx,
Expand Down
42 changes: 0 additions & 42 deletions clippy_lints/src/methods/slice_iter_any.rs

This file was deleted.

63 changes: 63 additions & 0 deletions clippy_lints/src/slice_iter_any.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::methods::method_call;
use clippy_utils::diagnostics::span_lint;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, IntTy, UintTy};
use rustc_session::declare_lint_pass;

declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `iter().any()` on slices of `u8` or `i8` and suggests using `contains()` instead.
///
/// ### Why is this bad?
/// `iter().any()` on slices of `u8` or `i8` is optimized to use `memchr`.
///
/// ### Example
/// ```no_run
/// fn foo(values: &[u8]) -> bool {
/// values.iter().any(|&v| v == 10)
/// }
/// ```
/// Use instead:
/// ```no_run
/// fn foo(values: &[u8]) -> bool {
/// values.contains(&10)
/// }
/// ```
#[clippy::version = "1.85.0"]
pub SLICE_ITER_ANY,
perf,
"using `contains()` instead of `iter().any()` on u8/i8 slices is more efficient"
}

declare_lint_pass!(SliceIterAny => [SLICE_ITER_ANY]);

impl LateLintPass<'_> for SliceIterAny {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if !expr.span.from_expansion()
// any()
&& let Some((name, recv, args, _, _)) = method_call(expr)
&& name == "any"
// check if the inner closure is a equality check
&& args.len() == 1
&& let ExprKind::Closure(closure) = args[0].kind
&& let body = cx.tcx.hir().body(closure.body)
&& let ExprKind::Binary(op, _, _) = body.value.kind
&& op.node == rustc_ast::ast::BinOpKind::Eq
// iter()
&& let Some((name, recv, _, _, _)) = method_call(recv)
&& name == "iter"
// check if the receiver is a u8/i8 slice
&& let ty::Ref(_, inner_type, _) = cx.typeck_results().expr_ty(recv).kind()
&& let ty::Slice(slice_type) = inner_type.kind()
&& matches!(slice_type.kind(), ty::Uint(UintTy::U8) | ty::Int(IntTy::I8))
{
span_lint(
cx,
SLICE_ITER_ANY,
expr.span,
"using `contains()` instead of `iter().any()` on u8/i8 slices is more efficient",
);
}
}
}

0 comments on commit 86fee9a

Please sign in to comment.