@@ -60,6 +60,7 @@ mod manual_ok_or;
6060mod manual_saturating_arithmetic;
6161mod manual_str_repeat;
6262mod manual_try_fold;
63+ mod map_all_any_identity;
6364mod map_clone;
6465mod map_collect_result_unit;
6566mod map_err_ignore;
@@ -4167,29 +4168,54 @@ declare_clippy_lint! {
41674168 "calling `.first().is_some()` or `.first().is_none()` instead of `.is_empty()`"
41684169}
41694170
4171+ declare_clippy_lint ! {
4172+ /// ### What it does
4173+ /// It detects useless calls to `str::as_bytes()` before calling `len()` or `is_empty()`.
4174+ ///
4175+ /// ### Why is this bad?
4176+ /// The `len()` and `is_empty()` methods are also directly available on strings, and they
4177+ /// return identical results. In particular, `len()` on a string returns the number of
4178+ /// bytes.
4179+ ///
4180+ /// ### Example
4181+ /// ```
4182+ /// let len = "some string".as_bytes().len();
4183+ /// let b = "some string".as_bytes().is_empty();
4184+ /// ```
4185+ /// Use instead:
4186+ /// ```
4187+ /// let len = "some string".len();
4188+ /// let b = "some string".is_empty();
4189+ /// ```
4190+ #[ clippy:: version = "1.84.0" ]
4191+ pub NEEDLESS_AS_BYTES ,
4192+ complexity,
4193+ "detect useless calls to `as_bytes()`"
4194+ }
4195+
41704196declare_clippy_lint ! {
41714197 /// ### What it does
4172- /// It detects useless calls to `str::as_bytes()` before calling `len( )` or `is_empty( )`.
4198+ /// Checks for usage of `.map(…)`, followed by `.all(identity )` or `.any(identity )`.
41734199 ///
41744200 /// ### Why is this bad?
4175- /// The `len()` and `is_empty()` methods are also directly available on strings, and they
4176- /// return identical results. In particular, `len()` on a string returns the number of
4177- /// bytes.
4201+ /// The `.all(…)` or `.any(…)` methods can be called directly in place of `.map(…)`.
41784202 ///
41794203 /// ### Example
41804204 /// ```
4181- /// let len = "some string".as_bytes().len();
4182- /// let b = "some string".as_bytes().is_empty();
4205+ /// # let mut v = [""];
4206+ /// let e1 = v.iter().map(|s| s.is_empty()).all(|a| a);
4207+ /// let e2 = v.iter().map(|s| s.is_empty()).any(std::convert::identity);
41834208 /// ```
41844209 /// Use instead:
41854210 /// ```
4186- /// let len = "some string".len();
4187- /// let b = "some string".is_empty();
4211+ /// # let mut v = [""];
4212+ /// let e1 = v.iter().all(|s| s.is_empty());
4213+ /// let e2 = v.iter().any(|s| s.is_empty());
41884214 /// ```
41894215 #[ clippy:: version = "1.84.0" ]
4190- pub NEEDLESS_AS_BYTES ,
4216+ pub MAP_ALL_ANY_IDENTITY ,
41914217 complexity,
4192- "detect useless calls to `as_bytes()` "
4218+ "combine `.map(_)` followed by `.all(identity)`/`.any(identity)` into a single call "
41934219}
41944220
41954221pub struct Methods {
@@ -4354,6 +4380,7 @@ impl_lint_pass!(Methods => [
43544380 MANUAL_INSPECT ,
43554381 UNNECESSARY_MIN_OR_MAX ,
43564382 NEEDLESS_AS_BYTES ,
4383+ MAP_ALL_ANY_IDENTITY ,
43574384] ) ;
43584385
43594386/// Extracts a method call name, args, and `Span` of the method name.
@@ -4561,15 +4588,21 @@ impl Methods {
45614588 ( "all" , [ arg] ) => {
45624589 unused_enumerate_index:: check ( cx, expr, recv, arg) ;
45634590 needless_character_iteration:: check ( cx, expr, recv, arg, true ) ;
4564- if let Some ( ( "cloned" , recv2, [ ] , _, _) ) = method_call ( recv) {
4565- iter_overeager_cloned:: check (
4566- cx,
4567- expr,
4568- recv,
4569- recv2,
4570- iter_overeager_cloned:: Op :: NeedlessMove ( arg) ,
4571- false ,
4572- ) ;
4591+ match method_call ( recv) {
4592+ Some ( ( "cloned" , recv2, [ ] , _, _) ) => {
4593+ iter_overeager_cloned:: check (
4594+ cx,
4595+ expr,
4596+ recv,
4597+ recv2,
4598+ iter_overeager_cloned:: Op :: NeedlessMove ( arg) ,
4599+ false ,
4600+ ) ;
4601+ } ,
4602+ Some ( ( "map" , _, [ map_arg] , _, map_call_span) ) => {
4603+ map_all_any_identity:: check ( cx, expr, recv, map_call_span, map_arg, call_span, arg, "all" ) ;
4604+ } ,
4605+ _ => { } ,
45734606 }
45744607 } ,
45754608 ( "and_then" , [ arg] ) => {
@@ -4598,6 +4631,9 @@ impl Methods {
45984631 {
45994632 string_lit_chars_any:: check ( cx, expr, recv, param, peel_blocks ( body. value ) , & self . msrv ) ;
46004633 } ,
4634+ Some ( ( "map" , _, [ map_arg] , _, map_call_span) ) => {
4635+ map_all_any_identity:: check ( cx, expr, recv, map_call_span, map_arg, call_span, arg, "any" ) ;
4636+ } ,
46014637 _ => { } ,
46024638 }
46034639 } ,
0 commit comments