Skip to content

Commit f30d7c2

Browse files
committed
Improve suggestions
1 parent f3f86d8 commit f30d7c2

File tree

4 files changed

+59
-53
lines changed

4 files changed

+59
-53
lines changed
Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::is_lang_ctor;
3+
use clippy_utils::is_no_std_crate;
34
use clippy_utils::source::snippet;
45

56
use rustc_errors::Applicability;
@@ -9,6 +10,22 @@ use rustc_lint::LateContext;
910

1011
use super::{ITER_EMPTY, ITER_ONCE};
1112

13+
enum IterType {
14+
Iter,
15+
IterMut,
16+
IntoIter,
17+
}
18+
19+
impl IterType {
20+
fn ref_prefix(&self) -> &'static str {
21+
match self {
22+
Self::Iter => "&",
23+
Self::IterMut => "&mut ",
24+
Self::IntoIter => "",
25+
}
26+
}
27+
}
28+
1229
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
1330
let item = match &recv.kind {
1431
ExprKind::Array(v) if v.len() <= 1 => v.first(),
@@ -32,39 +49,42 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name:
3249
},
3350
_ => return,
3451
};
52+
let iter_type = match method_name {
53+
"iter" => IterType::Iter,
54+
"iter_mut" => IterType::IterMut,
55+
"into_iter" => IterType::IntoIter,
56+
_ => return,
57+
};
3558

3659
if let Some(i) = item {
37-
let (sugg, msg) = match method_name {
38-
"iter" => (
39-
format!("std::iter::once(&{})", snippet(cx, i.span, "...")),
40-
"this `iter` call can be replaced with std::iter::once",
41-
),
42-
"iter_mut" => (
43-
format!("std::iter::once(&mut {})", snippet(cx, i.span, "...")),
44-
"this `iter_mut` call can be replaced with std::iter::once",
45-
),
46-
"into_iter" => (
47-
format!("std::iter::once({})", snippet(cx, i.span, "...")),
48-
"this `into_iter` call can be replaced with std::iter::once",
49-
),
50-
_ => return,
51-
};
52-
span_lint_and_sugg(cx, ITER_ONCE, expr.span, msg, "try", sugg, Applicability::Unspecified);
60+
let sugg = format!(
61+
"{}::iter::once({}{})",
62+
if is_no_std_crate(cx) { "core" } else { "std" },
63+
iter_type.ref_prefix(),
64+
snippet(cx, i.span, "...")
65+
);
66+
span_lint_and_sugg(
67+
cx,
68+
ITER_ONCE,
69+
expr.span,
70+
&format!("`{method_name}` call on a collection with only one item"),
71+
"try",
72+
sugg,
73+
Applicability::MaybeIncorrect,
74+
);
5375
} else {
54-
let msg = match method_name {
55-
"iter" => "this `iter call` can be replaced with std::iter::empty",
56-
"iter_mut" => "this `iter_mut` call can be replaced with std::iter::empty",
57-
"into_iter" => "this `into_iter` call can be replaced with std::iter::empty",
58-
_ => return,
59-
};
6076
span_lint_and_sugg(
6177
cx,
6278
ITER_EMPTY,
6379
expr.span,
64-
msg,
80+
&format!("`{method_name}` call on an empty collection"),
6581
"try",
66-
"std::iter::empty()".to_string(),
67-
Applicability::Unspecified,
82+
if is_no_std_crate(cx) {
83+
"core::iter::empty()".to_string()
84+
} else {
85+
"std::iter::empty()".to_string()
86+
},
87+
Applicability::MaybeIncorrect,
6888
);
6989
}
7090
}

clippy_lints/src/methods/mod.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,14 +2308,7 @@ declare_clippy_lint! {
23082308
declare_clippy_lint! {
23092309
/// ### What it does
23102310
///
2311-
/// Checks for usage of:
2312-
///
2313-
/// - `[foo].iter()`
2314-
/// - `[foo].iter_mut()`
2315-
/// - `[foo].into_iter()`
2316-
/// - `Some(foo).iter()`
2317-
/// - `Some(foo).iter_mut()`
2318-
/// - `Some(foo).into_iter()`
2311+
/// Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item
23192312
///
23202313
/// ### Why is this bad?
23212314
///
@@ -2346,14 +2339,7 @@ declare_clippy_lint! {
23462339
declare_clippy_lint! {
23472340
/// ### What it does
23482341
///
2349-
/// Checks for usage of:
2350-
///
2351-
/// - `[].iter()`
2352-
/// - `[].iter_mut()`
2353-
/// - `[].into_iter()`
2354-
/// - `None.iter()`
2355-
/// - `None.iter_mut()`
2356-
/// - `None.into_iter()`
2342+
/// Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections
23572343
///
23582344
/// ### Why is this bad?
23592345
///

tests/ui/iter_empty.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
error: this `into_iter` call can be replaced with std::iter::empty
1+
error: `into_iter` call on an empty collection
22
--> $DIR/iter_empty.rs:6:16
33
|
44
LL | assert_eq!([].into_iter().next(), Option::<i32>::None);
55
| ^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
66
|
77
= note: `-D clippy::iter-empty` implied by `-D warnings`
88

9-
error: this `iter_mut` call can be replaced with std::iter::empty
9+
error: `iter_mut` call on an empty collection
1010
--> $DIR/iter_empty.rs:7:16
1111
|
1212
LL | assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
1313
| ^^^^^^^^^^^^^ help: try: `std::iter::empty()`
1414

15-
error: this `iter call` can be replaced with std::iter::empty
15+
error: `iter` call on an empty collection
1616
--> $DIR/iter_empty.rs:8:16
1717
|
1818
LL | assert_eq!([].iter().next(), Option::<&i32>::None);
1919
| ^^^^^^^^^ help: try: `std::iter::empty()`
2020

21-
error: this `into_iter` call can be replaced with std::iter::empty
21+
error: `into_iter` call on an empty collection
2222
--> $DIR/iter_empty.rs:9:16
2323
|
2424
LL | assert_eq!(None.into_iter().next(), Option::<i32>::None);
2525
| ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
2626

27-
error: this `iter_mut` call can be replaced with std::iter::empty
27+
error: `iter_mut` call on an empty collection
2828
--> $DIR/iter_empty.rs:10:16
2929
|
3030
LL | assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
3131
| ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
3232

33-
error: this `iter call` can be replaced with std::iter::empty
33+
error: `iter` call on an empty collection
3434
--> $DIR/iter_empty.rs:11:16
3535
|
3636
LL | assert_eq!(None.iter().next(), Option::<&i32>::None);

tests/ui/iter_once.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
error: this `into_iter` call can be replaced with std::iter::once
1+
error: `into_iter` call on a collection with only one item
22
--> $DIR/iter_once.rs:6:16
33
|
44
LL | assert_eq!([123].into_iter().next(), Some(123));
55
| ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
66
|
77
= note: `-D clippy::iter-once` implied by `-D warnings`
88

9-
error: this `iter_mut` call can be replaced with std::iter::once
9+
error: `iter_mut` call on a collection with only one item
1010
--> $DIR/iter_once.rs:7:16
1111
|
1212
LL | assert_eq!([123].iter_mut().next(), Some(&mut 123));
1313
| ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
1414

15-
error: this `iter` call can be replaced with std::iter::once
15+
error: `iter` call on a collection with only one item
1616
--> $DIR/iter_once.rs:8:16
1717
|
1818
LL | assert_eq!([123].iter().next(), Some(&123));
1919
| ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
2020

21-
error: this `into_iter` call can be replaced with std::iter::once
21+
error: `into_iter` call on a collection with only one item
2222
--> $DIR/iter_once.rs:9:16
2323
|
2424
LL | assert_eq!(Some(123).into_iter().next(), Some(123));
2525
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
2626

27-
error: this `iter_mut` call can be replaced with std::iter::once
27+
error: `iter_mut` call on a collection with only one item
2828
--> $DIR/iter_once.rs:10:16
2929
|
3030
LL | assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
3131
| ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
3232

33-
error: this `iter` call can be replaced with std::iter::once
33+
error: `iter` call on a collection with only one item
3434
--> $DIR/iter_once.rs:11:16
3535
|
3636
LL | assert_eq!(Some(123).iter().next(), Some(&123));

0 commit comments

Comments
 (0)