about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSosthène Guédon <sosthene@guedon.gdn>2022-07-19 22:08:03 +0200
committerSosthène Guédon <sosthene@guedon.gdn>2022-08-08 21:04:44 +0200
commitf30d7c2495b3188bfa0cf8bd6dbbf76494c9845e (patch)
tree2c0e78bd7376dee06ce8d38b70f6ecc4a0c515d3
parentf3f86d8fd96dfa5986ffe10d0837169e473b9b83 (diff)
downloadrust-f30d7c2495b3188bfa0cf8bd6dbbf76494c9845e.tar.gz
rust-f30d7c2495b3188bfa0cf8bd6dbbf76494c9845e.zip
Improve suggestions
-rw-r--r--clippy_lints/src/methods/iter_once_empty.rs70
-rw-r--r--clippy_lints/src/methods/mod.rs18
-rw-r--r--tests/ui/iter_empty.stderr12
-rw-r--r--tests/ui/iter_once.stderr12
4 files changed, 59 insertions, 53 deletions
diff --git a/clippy_lints/src/methods/iter_once_empty.rs b/clippy_lints/src/methods/iter_once_empty.rs
index d45dfc67880..82fafb8a45e 100644
--- a/clippy_lints/src/methods/iter_once_empty.rs
+++ b/clippy_lints/src/methods/iter_once_empty.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_lang_ctor;
+use clippy_utils::is_no_std_crate;
 use clippy_utils::source::snippet;
 
 use rustc_errors::Applicability;
@@ -9,6 +10,22 @@ use rustc_lint::LateContext;
 
 use super::{ITER_EMPTY, ITER_ONCE};
 
+enum IterType {
+    Iter,
+    IterMut,
+    IntoIter,
+}
+
+impl IterType {
+    fn ref_prefix(&self) -> &'static str {
+        match self {
+            Self::Iter => "&",
+            Self::IterMut => "&mut ",
+            Self::IntoIter => "",
+        }
+    }
+}
+
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
     let item = match &recv.kind {
         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:
         },
         _ => return,
     };
+    let iter_type = match method_name {
+        "iter" => IterType::Iter,
+        "iter_mut" => IterType::IterMut,
+        "into_iter" => IterType::IntoIter,
+        _ => return,
+    };
 
     if let Some(i) = item {
-        let (sugg, msg) = match method_name {
-            "iter" => (
-                format!("std::iter::once(&{})", snippet(cx, i.span, "...")),
-                "this `iter` call can be replaced with std::iter::once",
-            ),
-            "iter_mut" => (
-                format!("std::iter::once(&mut {})", snippet(cx, i.span, "...")),
-                "this `iter_mut` call can be replaced with std::iter::once",
-            ),
-            "into_iter" => (
-                format!("std::iter::once({})", snippet(cx, i.span, "...")),
-                "this `into_iter` call can be replaced with std::iter::once",
-            ),
-            _ => return,
-        };
-        span_lint_and_sugg(cx, ITER_ONCE, expr.span, msg, "try", sugg, Applicability::Unspecified);
+        let sugg = format!(
+            "{}::iter::once({}{})",
+            if is_no_std_crate(cx) { "core" } else { "std" },
+            iter_type.ref_prefix(),
+            snippet(cx, i.span, "...")
+        );
+        span_lint_and_sugg(
+            cx,
+            ITER_ONCE,
+            expr.span,
+            &format!("`{method_name}` call on a collection with only one item"),
+            "try",
+            sugg,
+            Applicability::MaybeIncorrect,
+        );
     } else {
-        let msg = match method_name {
-            "iter" => "this `iter call` can be replaced with std::iter::empty",
-            "iter_mut" => "this `iter_mut` call can be replaced with std::iter::empty",
-            "into_iter" => "this `into_iter` call can be replaced with std::iter::empty",
-            _ => return,
-        };
         span_lint_and_sugg(
             cx,
             ITER_EMPTY,
             expr.span,
-            msg,
+            &format!("`{method_name}` call on an empty collection"),
             "try",
-            "std::iter::empty()".to_string(),
-            Applicability::Unspecified,
+            if is_no_std_crate(cx) {
+                "core::iter::empty()".to_string()
+            } else {
+                "std::iter::empty()".to_string()
+            },
+            Applicability::MaybeIncorrect,
         );
     }
 }
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index e449ae0e424..015cd094a9e 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -2308,14 +2308,7 @@ declare_clippy_lint! {
 declare_clippy_lint! {
     /// ### What it does
     ///
-    /// Checks for usage of:
-    ///
-    /// - `[foo].iter()`
-    /// - `[foo].iter_mut()`
-    /// - `[foo].into_iter()`
-    /// - `Some(foo).iter()`
-    /// - `Some(foo).iter_mut()`
-    /// - `Some(foo).into_iter()`
+    /// Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item
     ///
     /// ### Why is this bad?
     ///
@@ -2346,14 +2339,7 @@ declare_clippy_lint! {
 declare_clippy_lint! {
     /// ### What it does
     ///
-    /// Checks for usage of:
-    ///
-    /// - `[].iter()`
-    /// - `[].iter_mut()`
-    /// - `[].into_iter()`
-    /// - `None.iter()`
-    /// - `None.iter_mut()`
-    /// - `None.into_iter()`
+    /// Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections
     ///
     /// ### Why is this bad?
     ///
diff --git a/tests/ui/iter_empty.stderr b/tests/ui/iter_empty.stderr
index f4f06e93b23..40c08e6f82b 100644
--- a/tests/ui/iter_empty.stderr
+++ b/tests/ui/iter_empty.stderr
@@ -1,4 +1,4 @@
-error: this `into_iter` call can be replaced with std::iter::empty
+error: `into_iter` call on an empty collection
   --> $DIR/iter_empty.rs:6:16
    |
 LL |     assert_eq!([].into_iter().next(), Option::<i32>::None);
@@ -6,31 +6,31 @@ LL |     assert_eq!([].into_iter().next(), Option::<i32>::None);
    |
    = note: `-D clippy::iter-empty` implied by `-D warnings`
 
-error: this `iter_mut` call can be replaced with std::iter::empty
+error: `iter_mut` call on an empty collection
   --> $DIR/iter_empty.rs:7:16
    |
 LL |     assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);
    |                ^^^^^^^^^^^^^ help: try: `std::iter::empty()`
 
-error: this `iter call` can be replaced with std::iter::empty
+error: `iter` call on an empty collection
   --> $DIR/iter_empty.rs:8:16
    |
 LL |     assert_eq!([].iter().next(), Option::<&i32>::None);
    |                ^^^^^^^^^ help: try: `std::iter::empty()`
 
-error: this `into_iter` call can be replaced with std::iter::empty
+error: `into_iter` call on an empty collection
   --> $DIR/iter_empty.rs:9:16
    |
 LL |     assert_eq!(None.into_iter().next(), Option::<i32>::None);
    |                ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
 
-error: this `iter_mut` call can be replaced with std::iter::empty
+error: `iter_mut` call on an empty collection
   --> $DIR/iter_empty.rs:10:16
    |
 LL |     assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);
    |                ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`
 
-error: this `iter call` can be replaced with std::iter::empty
+error: `iter` call on an empty collection
   --> $DIR/iter_empty.rs:11:16
    |
 LL |     assert_eq!(None.iter().next(), Option::<&i32>::None);
diff --git a/tests/ui/iter_once.stderr b/tests/ui/iter_once.stderr
index d9e8f96f763..b22c8a99f10 100644
--- a/tests/ui/iter_once.stderr
+++ b/tests/ui/iter_once.stderr
@@ -1,4 +1,4 @@
-error: this `into_iter` call can be replaced with std::iter::once
+error: `into_iter` call on a collection with only one item
   --> $DIR/iter_once.rs:6:16
    |
 LL |     assert_eq!([123].into_iter().next(), Some(123));
@@ -6,31 +6,31 @@ LL |     assert_eq!([123].into_iter().next(), Some(123));
    |
    = note: `-D clippy::iter-once` implied by `-D warnings`
 
-error: this `iter_mut` call can be replaced with std::iter::once
+error: `iter_mut` call on a collection with only one item
   --> $DIR/iter_once.rs:7:16
    |
 LL |     assert_eq!([123].iter_mut().next(), Some(&mut 123));
    |                ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
 
-error: this `iter` call can be replaced with std::iter::once
+error: `iter` call on a collection with only one item
   --> $DIR/iter_once.rs:8:16
    |
 LL |     assert_eq!([123].iter().next(), Some(&123));
    |                ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`
 
-error: this `into_iter` call can be replaced with std::iter::once
+error: `into_iter` call on a collection with only one item
   --> $DIR/iter_once.rs:9:16
    |
 LL |     assert_eq!(Some(123).into_iter().next(), Some(123));
    |                ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`
 
-error: this `iter_mut` call can be replaced with std::iter::once
+error: `iter_mut` call on a collection with only one item
   --> $DIR/iter_once.rs:10:16
    |
 LL |     assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));
    |                ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`
 
-error: this `iter` call can be replaced with std::iter::once
+error: `iter` call on a collection with only one item
   --> $DIR/iter_once.rs:11:16
    |
 LL |     assert_eq!(Some(123).iter().next(), Some(&123));