Skip to content

Commit d5264c7

Browse files
committed
Check for needless uses of str::bytes()
This builds upon the lint for `str::as_bytes()`, and also covers needless uses of the iterator version `str::bytes()`.
1 parent e42e354 commit d5264c7

File tree

5 files changed

+111
-15
lines changed

5 files changed

+111
-15
lines changed

clippy_lints/src/methods/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4924,8 +4924,8 @@ impl Methods {
49244924
},
49254925
("is_empty", []) => {
49264926
match method_call(recv) {
4927-
Some(("as_bytes", prev_recv, [], _, _)) => {
4928-
needless_as_bytes::check(cx, "is_empty", prev_recv, expr.span);
4927+
Some((prev_method @ ("as_bytes" | "bytes"), prev_recv, [], _, _)) => {
4928+
needless_as_bytes::check(cx, prev_method, "is_empty", prev_recv, expr.span);
49294929
},
49304930
Some(("as_str", recv, [], as_str_span, _)) => {
49314931
redundant_as_str::check(cx, expr, recv, as_str_span, span);
@@ -4962,8 +4962,8 @@ impl Methods {
49624962
double_ended_iterator_last::check(cx, expr, recv, call_span);
49634963
},
49644964
("len", []) => {
4965-
if let Some(("as_bytes", prev_recv, [], _, _)) = method_call(recv) {
4966-
needless_as_bytes::check(cx, "len", prev_recv, expr.span);
4965+
if let Some((prev_method @ ("as_bytes" | "bytes"), prev_recv, [], _, _)) = method_call(recv) {
4966+
needless_as_bytes::check(cx, prev_method, "len", prev_recv, expr.span);
49674967
}
49684968
},
49694969
("lock", []) => {

clippy_lints/src/methods/needless_as_bytes.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_span::Span;
88

99
use super::NEEDLESS_AS_BYTES;
1010

11-
pub fn check(cx: &LateContext<'_>, method: &str, prev_recv: &Expr<'_>, span: Span) {
11+
pub fn check(cx: &LateContext<'_>, prev_method: &str, method: &str, prev_recv: &Expr<'_>, span: Span) {
1212
let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs();
1313
if is_type_lang_item(cx, ty1, LangItem::String) || ty1.is_str() {
1414
let mut app = Applicability::MachineApplicable;
@@ -17,7 +17,7 @@ pub fn check(cx: &LateContext<'_>, method: &str, prev_recv: &Expr<'_>, span: Spa
1717
cx,
1818
NEEDLESS_AS_BYTES,
1919
span,
20-
"needless call to `as_bytes()`",
20+
format!("needless call to `{prev_method}`"),
2121
format!("`{method}()` can be called directly on strings"),
2222
format!("{sugg}.{method}()"),
2323
app,

tests/ui/needless_as_bytes.fixed

+36
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#![warn(clippy::needless_as_bytes)]
22
#![allow(clippy::const_is_empty)]
3+
#![feature(exact_size_is_empty)]
34

45
struct S;
56

67
impl S {
78
fn as_bytes(&self) -> &[u8] {
89
&[]
910
}
11+
fn bytes(&self) -> &[u8] {
12+
&[]
13+
}
1014
}
1115

1216
fn main() {
@@ -15,13 +19,23 @@ fn main() {
1519
println!("len = {}", "some string".len());
1620
//~^ needless_as_bytes
1721
}
22+
if "some string".is_empty() {
23+
//~^ needless_as_bytes
24+
println!("len = {}", "some string".len());
25+
//~^ needless_as_bytes
26+
}
1827

1928
let s = String::from("yet another string");
2029
if s.is_empty() {
2130
//~^ needless_as_bytes
2231
println!("len = {}", s.len());
2332
//~^ needless_as_bytes
2433
}
34+
if s.is_empty() {
35+
//~^ needless_as_bytes
36+
println!("len = {}", s.len());
37+
//~^ needless_as_bytes
38+
}
2539

2640
// Do not lint
2741
let _ = S.as_bytes().is_empty();
@@ -36,6 +50,18 @@ fn main() {
3650
};
3751
}
3852
m!(1).as_bytes().len();
53+
let _ = S.bytes().is_empty();
54+
let _ = S.bytes().len();
55+
let _ = (&String::new() as &dyn Bytes).bytes().len();
56+
macro_rules! m {
57+
(1) => {
58+
""
59+
};
60+
(2) => {
61+
"".bytes()
62+
};
63+
}
64+
m!(1).bytes().len();
3965
m!(2).len();
4066
}
4167

@@ -48,3 +74,13 @@ impl AsBytes for String {
4874
&[]
4975
}
5076
}
77+
78+
pub trait Bytes {
79+
fn bytes(&self) -> &[u8];
80+
}
81+
82+
impl Bytes for String {
83+
fn bytes(&self) -> &[u8] {
84+
&[]
85+
}
86+
}

tests/ui/needless_as_bytes.rs

+36
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#![warn(clippy::needless_as_bytes)]
22
#![allow(clippy::const_is_empty)]
3+
#![feature(exact_size_is_empty)]
34

45
struct S;
56

67
impl S {
78
fn as_bytes(&self) -> &[u8] {
89
&[]
910
}
11+
fn bytes(&self) -> &[u8] {
12+
&[]
13+
}
1014
}
1115

1216
fn main() {
@@ -15,13 +19,23 @@ fn main() {
1519
println!("len = {}", "some string".as_bytes().len());
1620
//~^ needless_as_bytes
1721
}
22+
if "some string".bytes().is_empty() {
23+
//~^ needless_as_bytes
24+
println!("len = {}", "some string".bytes().len());
25+
//~^ needless_as_bytes
26+
}
1827

1928
let s = String::from("yet another string");
2029
if s.as_bytes().is_empty() {
2130
//~^ needless_as_bytes
2231
println!("len = {}", s.as_bytes().len());
2332
//~^ needless_as_bytes
2433
}
34+
if s.bytes().is_empty() {
35+
//~^ needless_as_bytes
36+
println!("len = {}", s.bytes().len());
37+
//~^ needless_as_bytes
38+
}
2539

2640
// Do not lint
2741
let _ = S.as_bytes().is_empty();
@@ -36,6 +50,18 @@ fn main() {
3650
};
3751
}
3852
m!(1).as_bytes().len();
53+
let _ = S.bytes().is_empty();
54+
let _ = S.bytes().len();
55+
let _ = (&String::new() as &dyn Bytes).bytes().len();
56+
macro_rules! m {
57+
(1) => {
58+
""
59+
};
60+
(2) => {
61+
"".bytes()
62+
};
63+
}
64+
m!(1).bytes().len();
3965
m!(2).len();
4066
}
4167

@@ -48,3 +74,13 @@ impl AsBytes for String {
4874
&[]
4975
}
5076
}
77+
78+
pub trait Bytes {
79+
fn bytes(&self) -> &[u8];
80+
}
81+
82+
impl Bytes for String {
83+
fn bytes(&self) -> &[u8] {
84+
&[]
85+
}
86+
}

tests/ui/needless_as_bytes.stderr

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,53 @@
1-
error: needless call to `as_bytes()`
2-
--> tests/ui/needless_as_bytes.rs:13:8
1+
error: needless call to `as_bytes`
2+
--> tests/ui/needless_as_bytes.rs:17:8
33
|
44
LL | if "some string".as_bytes().is_empty() {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()`
66
|
77
= note: `-D clippy::needless-as-bytes` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::needless_as_bytes)]`
99

10-
error: needless call to `as_bytes()`
11-
--> tests/ui/needless_as_bytes.rs:15:30
10+
error: needless call to `as_bytes`
11+
--> tests/ui/needless_as_bytes.rs:19:30
1212
|
1313
LL | println!("len = {}", "some string".as_bytes().len());
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()`
1515

16-
error: needless call to `as_bytes()`
17-
--> tests/ui/needless_as_bytes.rs:20:8
16+
error: needless call to `bytes`
17+
--> tests/ui/needless_as_bytes.rs:22:8
18+
|
19+
LL | if "some string".bytes().is_empty() {
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()`
21+
22+
error: needless call to `bytes`
23+
--> tests/ui/needless_as_bytes.rs:24:30
24+
|
25+
LL | println!("len = {}", "some string".bytes().len());
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()`
27+
28+
error: needless call to `as_bytes`
29+
--> tests/ui/needless_as_bytes.rs:29:8
1830
|
1931
LL | if s.as_bytes().is_empty() {
2032
| ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`
2133

22-
error: needless call to `as_bytes()`
23-
--> tests/ui/needless_as_bytes.rs:22:30
34+
error: needless call to `as_bytes`
35+
--> tests/ui/needless_as_bytes.rs:31:30
2436
|
2537
LL | println!("len = {}", s.as_bytes().len());
2638
| ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`
2739

28-
error: aborting due to 4 previous errors
40+
error: needless call to `bytes`
41+
--> tests/ui/needless_as_bytes.rs:34:8
42+
|
43+
LL | if s.bytes().is_empty() {
44+
| ^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`
45+
46+
error: needless call to `bytes`
47+
--> tests/ui/needless_as_bytes.rs:36:30
48+
|
49+
LL | println!("len = {}", s.bytes().len());
50+
| ^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`
51+
52+
error: aborting due to 8 previous errors
2953

0 commit comments

Comments
 (0)