about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDmitry Murzin <diralik@yandex.ru>2020-07-25 17:09:44 +0300
committerDmitry Murzin <diralik@yandex.ru>2020-07-25 17:11:55 +0300
commitb375f1dd20bf07175ec06d13e1e9dc8b20287cd3 (patch)
tree6e04da704ea08969e5b4b7587d89c9c00cf8eb81
parent79f948ec0a507f8dc663508ce013104847fcc9f3 (diff)
downloadrust-b375f1dd20bf07175ec06d13e1e9dc8b20287cd3.tar.gz
rust-b375f1dd20bf07175ec06d13e1e9dc8b20287cd3.zip
Add suggestion for `iter_skip_next` lint
-rw-r--r--clippy_lints/src/methods/mod.rs24
-rw-r--r--tests/ui/iter_skip_next.fixed22
-rw-r--r--tests/ui/iter_skip_next.rs8
-rw-r--r--tests/ui/iter_skip_next.stderr23
4 files changed, 48 insertions, 29 deletions
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 97cc58023f5..56686f6d24f 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1408,7 +1408,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             ["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
             ["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
             ["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]),
-            ["next", "skip"] => lint_iter_skip_next(cx, expr),
+            ["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]),
             ["collect", "cloned"] => lint_iter_cloned_collect(cx, expr, arg_lists[1]),
             ["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]),
             ["as_mut"] => lint_asref(cx, expr, "as_mut", arg_lists[0]),
@@ -2436,17 +2436,21 @@ fn lint_get_unwrap<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, get_args:
     );
 }
 
-fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
+fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[hir::Expr<'_>]) {
     // lint if caller of skip is an Iterator
     if match_trait_method(cx, expr, &paths::ITERATOR) {
-        span_lint_and_help(
-            cx,
-            ITER_SKIP_NEXT,
-            expr.span,
-            "called `skip(x).next()` on an iterator",
-            None,
-            "this is more succinctly expressed by calling `nth(x)`",
-        );
+        if let [caller, n] = skip_args {
+            let hint = format!(".nth({})", snippet(cx, n.span, ".."));
+            span_lint_and_sugg(
+                cx,
+                ITER_SKIP_NEXT,
+                expr.span.trim_start(caller.span).unwrap(),
+                "called `skip(x).next()` on an iterator",
+                "use `nth` instead",
+                hint,
+                Applicability::MachineApplicable,
+            );
+        }
     }
 }
 
diff --git a/tests/ui/iter_skip_next.fixed b/tests/ui/iter_skip_next.fixed
new file mode 100644
index 00000000000..928b6acb951
--- /dev/null
+++ b/tests/ui/iter_skip_next.fixed
@@ -0,0 +1,22 @@
+// run-rustfix
+// aux-build:option_helpers.rs
+
+#![warn(clippy::iter_skip_next)]
+#![allow(clippy::blacklisted_name)]
+#![allow(clippy::iter_nth)]
+
+extern crate option_helpers;
+
+use option_helpers::IteratorFalsePositives;
+
+/// Checks implementation of `ITER_SKIP_NEXT` lint
+fn main() {
+    let some_vec = vec![0, 1, 2, 3];
+    let _ = some_vec.iter().nth(42);
+    let _ = some_vec.iter().cycle().nth(42);
+    let _ = (1..10).nth(10);
+    let _ = &some_vec[..].iter().nth(3);
+    let foo = IteratorFalsePositives { foo: 0 };
+    let _ = foo.skip(42).next();
+    let _ = foo.filter().skip(42).next();
+}
diff --git a/tests/ui/iter_skip_next.rs b/tests/ui/iter_skip_next.rs
index a65ca3bbb13..7075e2598eb 100644
--- a/tests/ui/iter_skip_next.rs
+++ b/tests/ui/iter_skip_next.rs
@@ -1,15 +1,17 @@
+// run-rustfix
 // aux-build:option_helpers.rs
 
 #![warn(clippy::iter_skip_next)]
 #![allow(clippy::blacklisted_name)]
+#![allow(clippy::iter_nth)]
 
 extern crate option_helpers;
 
 use option_helpers::IteratorFalsePositives;
 
 /// Checks implementation of `ITER_SKIP_NEXT` lint
-fn iter_skip_next() {
-    let mut some_vec = vec![0, 1, 2, 3];
+fn main() {
+    let some_vec = vec![0, 1, 2, 3];
     let _ = some_vec.iter().skip(42).next();
     let _ = some_vec.iter().cycle().skip(42).next();
     let _ = (1..10).skip(10).next();
@@ -18,5 +20,3 @@ fn iter_skip_next() {
     let _ = foo.skip(42).next();
     let _ = foo.filter().skip(42).next();
 }
-
-fn main() {}
diff --git a/tests/ui/iter_skip_next.stderr b/tests/ui/iter_skip_next.stderr
index 5709f335529..feedc2f288a 100644
--- a/tests/ui/iter_skip_next.stderr
+++ b/tests/ui/iter_skip_next.stderr
@@ -1,35 +1,28 @@
 error: called `skip(x).next()` on an iterator
-  --> $DIR/iter_skip_next.rs:13:13
+  --> $DIR/iter_skip_next.rs:15:28
    |
 LL |     let _ = some_vec.iter().skip(42).next();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                            ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)`
    |
    = note: `-D clippy::iter-skip-next` implied by `-D warnings`
-   = help: this is more succinctly expressed by calling `nth(x)`
 
 error: called `skip(x).next()` on an iterator
-  --> $DIR/iter_skip_next.rs:14:13
+  --> $DIR/iter_skip_next.rs:16:36
    |
 LL |     let _ = some_vec.iter().cycle().skip(42).next();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: this is more succinctly expressed by calling `nth(x)`
+   |                                    ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)`
 
 error: called `skip(x).next()` on an iterator
-  --> $DIR/iter_skip_next.rs:15:13
+  --> $DIR/iter_skip_next.rs:17:20
    |
 LL |     let _ = (1..10).skip(10).next();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: this is more succinctly expressed by calling `nth(x)`
+   |                    ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(10)`
 
 error: called `skip(x).next()` on an iterator
-  --> $DIR/iter_skip_next.rs:16:14
+  --> $DIR/iter_skip_next.rs:18:33
    |
 LL |     let _ = &some_vec[..].iter().skip(3).next();
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: this is more succinctly expressed by calling `nth(x)`
+   |                                 ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(3)`
 
 error: aborting due to 4 previous errors