about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduardo Broto <ebroto@tutanota.com>2020-08-08 18:13:43 +0200
committerEduardo Broto <ebroto@tutanota.com>2020-08-08 18:13:43 +0200
commit888657e09a2133fc105382136f61915086144e3f (patch)
tree28a637f5fb6cbbb7a5add66f9a19796347423fe3
parent2d4c3379d355c436342113a302421faf3990fb29 (diff)
downloadrust-888657e09a2133fc105382136f61915086144e3f.tar.gz
rust-888657e09a2133fc105382136f61915086144e3f.zip
Fix ICE in `loops` module
-rw-r--r--clippy_lints/src/loops.rs20
-rw-r--r--tests/ui/crashes/ice-5872.rs5
-rw-r--r--tests/ui/crashes/ice-5872.stderr10
-rw-r--r--tests/ui/needless_collect.fixed4
-rw-r--r--tests/ui/needless_collect.rs2
-rw-r--r--tests/ui/needless_collect.stderr4
6 files changed, 30 insertions, 15 deletions
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 6359c20040c..1729fea7bc8 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -2374,7 +2374,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
                 match_type(cx, ty, &paths::BTREEMAP) ||
                 is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) {
                 if method.ident.name == sym!(len) {
-                    let span = shorten_span(expr, sym!(collect));
+                    let span = shorten_needless_collect_span(expr);
                     span_lint_and_sugg(
                         cx,
                         NEEDLESS_COLLECT,
@@ -2386,20 +2386,20 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
                     );
                 }
                 if method.ident.name == sym!(is_empty) {
-                    let span = shorten_span(expr, sym!(iter));
+                    let span = shorten_needless_collect_span(expr);
                     span_lint_and_sugg(
                         cx,
                         NEEDLESS_COLLECT,
                         span,
                         NEEDLESS_COLLECT_MSG,
                         "replace with",
-                        "get(0).is_none()".to_string(),
+                        "next().is_none()".to_string(),
                         Applicability::MachineApplicable,
                     );
                 }
                 if method.ident.name == sym!(contains) {
                     let contains_arg = snippet(cx, args[1].span, "??");
-                    let span = shorten_span(expr, sym!(collect));
+                    let span = shorten_needless_collect_span(expr);
                     span_lint_and_then(
                         cx,
                         NEEDLESS_COLLECT,
@@ -2579,13 +2579,13 @@ fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident)
     }
 }
 
-fn shorten_span(expr: &Expr<'_>, target_fn_name: Symbol) -> Span {
-    let mut current_expr = expr;
-    while let ExprKind::MethodCall(ref path, ref span, ref args, _) = current_expr.kind {
-        if path.ident.name == target_fn_name {
+fn shorten_needless_collect_span(expr: &Expr<'_>) -> Span {
+    if_chain! {
+        if let ExprKind::MethodCall(.., args, _) = &expr.kind;
+        if let ExprKind::MethodCall(_, span, ..) = &args[0].kind;
+        then {
             return expr.span.with_lo(span.lo());
         }
-        current_expr = &args[0];
     }
-    unreachable!()
+    unreachable!();
 }
diff --git a/tests/ui/crashes/ice-5872.rs b/tests/ui/crashes/ice-5872.rs
new file mode 100644
index 00000000000..68afa8f8c3a
--- /dev/null
+++ b/tests/ui/crashes/ice-5872.rs
@@ -0,0 +1,5 @@
+#![warn(clippy::needless_collect)]
+
+fn main() {
+    let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();
+}
diff --git a/tests/ui/crashes/ice-5872.stderr b/tests/ui/crashes/ice-5872.stderr
new file mode 100644
index 00000000000..a60ca345cf7
--- /dev/null
+++ b/tests/ui/crashes/ice-5872.stderr
@@ -0,0 +1,10 @@
+error: avoid using `collect()` when not needed
+  --> $DIR/ice-5872.rs:4:39
+   |
+LL |     let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
+   |
+   = note: `-D clippy::needless-collect` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed
index be37dc16b9a..7f2fcf02f6b 100644
--- a/tests/ui/needless_collect.fixed
+++ b/tests/ui/needless_collect.fixed
@@ -5,11 +5,11 @@
 use std::collections::{BTreeSet, HashMap, HashSet};
 
 #[warn(clippy::needless_collect)]
-#[allow(unused_variables, clippy::iter_cloned_collect)]
+#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]
 fn main() {
     let sample = [1; 5];
     let len = sample.iter().count();
-    if sample.get(0).is_none() {
+    if sample.iter().next().is_none() {
         // Empty
     }
     sample.iter().cloned().any(|x| x == 1);
diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs
index 7ee603afeb0..788a9eb3264 100644
--- a/tests/ui/needless_collect.rs
+++ b/tests/ui/needless_collect.rs
@@ -5,7 +5,7 @@
 use std::collections::{BTreeSet, HashMap, HashSet};
 
 #[warn(clippy::needless_collect)]
-#[allow(unused_variables, clippy::iter_cloned_collect)]
+#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]
 fn main() {
     let sample = [1; 5];
     let len = sample.iter().collect::<Vec<_>>().len();
diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr
index 9113aad90dd..2a9539d5975 100644
--- a/tests/ui/needless_collect.stderr
+++ b/tests/ui/needless_collect.stderr
@@ -7,10 +7,10 @@ LL |     let len = sample.iter().collect::<Vec<_>>().len();
    = note: `-D clippy::needless-collect` implied by `-D warnings`
 
 error: avoid using `collect()` when not needed
-  --> $DIR/needless_collect.rs:12:15
+  --> $DIR/needless_collect.rs:12:22
    |
 LL |     if sample.iter().collect::<Vec<_>>().is_empty() {
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get(0).is_none()`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
 
 error: avoid using `collect()` when not needed
   --> $DIR/needless_collect.rs:15:28