@@ -67,6 +67,7 @@ mod map_flatten;
6767mod map_identity;
6868mod map_unwrap_or;
6969mod mut_mutex_lock;
70+ mod needless_as_bytes;
7071mod needless_character_iteration;
7172mod needless_collect;
7273mod needless_option_as_deref;
@@ -4166,6 +4167,31 @@ declare_clippy_lint! {
41664167 "calling `.first().is_some()` or `.first().is_none()` instead of `.is_empty()`"
41674168}
41684169
4170+ declare_clippy_lint ! {
4171+ /// ### What it does
4172+ /// It detects useless calls to `str::as_bytes()` before calling `len()` or `is_empty()`.
4173+ ///
4174+ /// ### 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.
4178+ ///
4179+ /// ### Example
4180+ /// ```
4181+ /// let len = "some string".as_bytes().len();
4182+ /// let b = "some string".as_bytes().is_empty();
4183+ /// ```
4184+ /// Use instead:
4185+ /// ```
4186+ /// let len = "some string".len();
4187+ /// let b = "some string".is_empty();
4188+ /// ```
4189+ #[ clippy:: version = "1.83.0" ]
4190+ pub NEEDLESS_AS_BYTES ,
4191+ complexity,
4192+ "detect useless calls to `as_bytes()`"
4193+ }
4194+
41694195pub struct Methods {
41704196 avoid_breaking_exported_api : bool ,
41714197 msrv : Msrv ,
@@ -4327,6 +4353,7 @@ impl_lint_pass!(Methods => [
43274353 NEEDLESS_CHARACTER_ITERATION ,
43284354 MANUAL_INSPECT ,
43294355 UNNECESSARY_MIN_OR_MAX ,
4356+ NEEDLESS_AS_BYTES ,
43304357] ) ;
43314358
43324359/// Extracts a method call name, args, and `Span` of the method name.
@@ -4764,8 +4791,14 @@ impl Methods {
47644791 unit_hash:: check ( cx, expr, recv, arg) ;
47654792 } ,
47664793 ( "is_empty" , [ ] ) => {
4767- if let Some ( ( "as_str" , recv, [ ] , as_str_span, _) ) = method_call ( recv) {
4768- redundant_as_str:: check ( cx, expr, recv, as_str_span, span) ;
4794+ match method_call ( recv) {
4795+ Some ( ( "as_bytes" , prev_recv, [ ] , _, _) ) => {
4796+ needless_as_bytes:: check ( cx, "is_empty" , recv, prev_recv, expr. span ) ;
4797+ } ,
4798+ Some ( ( "as_str" , recv, [ ] , as_str_span, _) ) => {
4799+ redundant_as_str:: check ( cx, expr, recv, as_str_span, span) ;
4800+ } ,
4801+ _ => { } ,
47694802 }
47704803 is_empty:: check ( cx, expr, recv) ;
47714804 } ,
@@ -4795,6 +4828,11 @@ impl Methods {
47954828 ) ;
47964829 }
47974830 } ,
4831+ ( "len" , [ ] ) => {
4832+ if let Some ( ( "as_bytes" , prev_recv, [ ] , _, _) ) = method_call ( recv) {
4833+ needless_as_bytes:: check ( cx, "len" , recv, prev_recv, expr. span ) ;
4834+ }
4835+ } ,
47984836 ( "lock" , [ ] ) => {
47994837 mut_mutex_lock:: check ( cx, expr, recv, span) ;
48004838 } ,
0 commit comments