Skip to content

Commit 7e53e27

Browse files
committed
Stop bytes_nth from suggesting code that does not compile
1 parent 52c8b53 commit 7e53e27

File tree

4 files changed

+38
-22
lines changed

4 files changed

+38
-22
lines changed

clippy_lints/src/methods/bytes_nth.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use rustc_errors::Applicability;
55
use rustc_hir::{Expr, LangItem};
66
use rustc_lint::LateContext;
77

8+
use crate::methods::method_call;
9+
810
use super::BYTES_NTH;
911

1012
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, n_arg: &'tcx Expr<'tcx>) {
@@ -16,18 +18,32 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
1618
} else {
1719
return;
1820
};
21+
1922
let mut applicability = Applicability::MachineApplicable;
20-
span_lint_and_sugg(
21-
cx,
22-
BYTES_NTH,
23-
expr.span,
24-
&format!("called `.bytes().nth()` on a `{caller_type}`"),
25-
"try",
26-
format!(
27-
"{}.as_bytes().get({})",
28-
snippet_with_applicability(cx, recv.span, "..", &mut applicability),
29-
snippet_with_applicability(cx, n_arg.span, "..", &mut applicability)
30-
),
31-
applicability,
32-
);
23+
let receiver = snippet_with_applicability(cx, recv.span, "..", &mut applicability);
24+
let n = snippet_with_applicability(cx, n_arg.span, "..", &mut applicability);
25+
26+
if let Some(parent) = clippy_utils::get_parent_expr(cx, expr)
27+
&& let Some((name, _, _, _, _)) = method_call(parent)
28+
&& name == "unwrap" {
29+
span_lint_and_sugg(
30+
cx,
31+
BYTES_NTH,
32+
parent.span,
33+
&format!("called `.bytes().nth().unwrap()` on a `{caller_type}`"),
34+
"try",
35+
format!("{receiver}.as_bytes()[{n}]",),
36+
applicability
37+
);
38+
} else {
39+
span_lint_and_sugg(
40+
cx,
41+
BYTES_NTH,
42+
expr.span,
43+
&format!("called `.bytes().nth()` on a `{caller_type}`"),
44+
"try",
45+
format!("{receiver}.as_bytes().get({n}).copied()"),
46+
applicability
47+
);
48+
};
3349
}

tests/ui/bytes_nth.fixed

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
fn main() {
77
let s = String::from("String");
8-
let _ = s.as_bytes().get(3);
9-
let _ = &s.as_bytes().get(3);
10-
let _ = s[..].as_bytes().get(3);
8+
let _ = s.as_bytes().get(3).copied();
9+
let _ = &s.as_bytes()[3];
10+
let _ = s[..].as_bytes().get(3).copied();
1111
}

tests/ui/bytes_nth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
fn main() {
77
let s = String::from("String");
88
let _ = s.bytes().nth(3);
9-
let _ = &s.bytes().nth(3);
9+
let _ = &s.bytes().nth(3).unwrap();
1010
let _ = s[..].bytes().nth(3);
1111
}

tests/ui/bytes_nth.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@ error: called `.bytes().nth()` on a `String`
22
--> $DIR/bytes_nth.rs:8:13
33
|
44
LL | let _ = s.bytes().nth(3);
5-
| ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)`
5+
| ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3).copied()`
66
|
77
= note: `-D clippy::bytes-nth` implied by `-D warnings`
88

9-
error: called `.bytes().nth()` on a `String`
9+
error: called `.bytes().nth().unwrap()` on a `String`
1010
--> $DIR/bytes_nth.rs:9:14
1111
|
12-
LL | let _ = &s.bytes().nth(3);
13-
| ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)`
12+
LL | let _ = &s.bytes().nth(3).unwrap();
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.as_bytes()[3]`
1414

1515
error: called `.bytes().nth()` on a `str`
1616
--> $DIR/bytes_nth.rs:10:13
1717
|
1818
LL | let _ = s[..].bytes().nth(3);
19-
| ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3)`
19+
| ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3).copied()`
2020

2121
error: aborting due to 3 previous errors
2222

0 commit comments

Comments
 (0)