@@ -14,6 +14,7 @@ mod clone_on_copy;
14
14
mod clone_on_ref_ptr;
15
15
mod cloned_instead_of_copied;
16
16
mod collapsible_str_replace;
17
+ mod contains_for_slice;
17
18
mod drain_collect;
18
19
mod err_expect;
19
20
mod expect_fun_call;
@@ -4284,6 +4285,31 @@ declare_clippy_lint! {
4284
4285
"map of a trivial closure (not dependent on parameter) over a range"
4285
4286
}
4286
4287
4288
+ declare_clippy_lint ! {
4289
+ /// ### What it does
4290
+ /// Checks for usage of `iter().any()` on slices of `u8` or `i8` and suggests using `contains()` instead.
4291
+ ///
4292
+ /// ### Why is this bad?
4293
+ /// `iter().any()` on slices of `u8` or `i8` is optimized to use `memchr`.
4294
+ ///
4295
+ /// ### Example
4296
+ /// ```no_run
4297
+ /// fn foo(values: &[u8]) -> bool {
4298
+ /// values.iter().any(|&v| v == 10)
4299
+ /// }
4300
+ /// ```
4301
+ /// Use instead:
4302
+ /// ```no_run
4303
+ /// fn foo(values: &[u8]) -> bool {
4304
+ /// values.contains(&10)
4305
+ /// }
4306
+ /// ```
4307
+ #[ clippy:: version = "1.85.0" ]
4308
+ pub CONTAINS_FOR_SLICE ,
4309
+ perf,
4310
+ "using `contains()` instead of `iter().any()` on u8/i8 slices is more efficient"
4311
+ }
4312
+
4287
4313
pub struct Methods {
4288
4314
avoid_breaking_exported_api : bool ,
4289
4315
msrv : Msrv ,
@@ -4449,6 +4475,7 @@ impl_lint_pass!(Methods => [
4449
4475
MAP_ALL_ANY_IDENTITY ,
4450
4476
MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES ,
4451
4477
UNNECESSARY_MAP_OR ,
4478
+ CONTAINS_FOR_SLICE ,
4452
4479
] ) ;
4453
4480
4454
4481
/// Extracts a method call name, args, and `Span` of the method name.
@@ -4683,6 +4710,7 @@ impl Methods {
4683
4710
( "any" , [ arg] ) => {
4684
4711
unused_enumerate_index:: check ( cx, expr, recv, arg) ;
4685
4712
needless_character_iteration:: check ( cx, expr, recv, arg, false ) ;
4713
+ contains_for_slice:: check ( cx, expr) ;
4686
4714
match method_call ( recv) {
4687
4715
Some ( ( "cloned" , recv2, [ ] , _, _) ) => iter_overeager_cloned:: check (
4688
4716
cx,
0 commit comments