about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCrazyRoka <RokaRostuk@gmail.com>2020-05-02 14:25:45 +0300
committerCrazyRoka <RokaRostuk@gmail.com>2020-05-02 14:25:45 +0300
commite7138e06291d13163e8ab2a57fe2465451fac193 (patch)
treec85b99e0dacb8d702ffb6c01811070253e0673d3
parent991efa6375e548ff86334916a585a7e36a9d6839 (diff)
downloadrust-e7138e06291d13163e8ab2a57fe2465451fac193.tar.gz
rust-e7138e06291d13163e8ab2a57fe2465451fac193.zip
Fix match on vec items: match on vec[..]
- Added new tests
- Fixed false positive when matching on full range, which will never panic
-rw-r--r--clippy_lints/src/match_on_vec_items.rs21
-rw-r--r--tests/ui/match_on_vec_items.rs22
2 files changed, 38 insertions, 5 deletions
diff --git a/clippy_lints/src/match_on_vec_items.rs b/clippy_lints/src/match_on_vec_items.rs
index 421571d2f2f..236362130e5 100644
--- a/clippy_lints/src/match_on_vec_items.rs
+++ b/clippy_lints/src/match_on_vec_items.rs
@@ -1,4 +1,4 @@
-use crate::utils::{is_type_diagnostic_item, snippet, span_lint_and_sugg, walk_ptrs_ty};
+use crate::utils::{is_type_diagnostic_item, match_type, snippet, span_lint_and_sugg, walk_ptrs_ty};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, MatchSource};
@@ -75,10 +75,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchOnVecItems {
 
 fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
     if_chain! {
-        if let ExprKind::Index(ref array, _) = expr.kind;
-        let ty = cx.tables.expr_ty(array);
-        let ty = walk_ptrs_ty(ty);
-        if is_type_diagnostic_item(cx, ty, sym!(vec_type));
+        if let ExprKind::Index(ref array, ref index) = expr.kind;
+        if is_vector(cx, array);
+        if !is_full_range(cx, index);
 
         then {
             return Some(expr);
@@ -87,3 +86,15 @@ fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>)
 
     None
 }
+
+fn is_vector(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
+    let ty = cx.tables.expr_ty(expr);
+    let ty = walk_ptrs_ty(ty);
+    is_type_diagnostic_item(cx, ty, sym!(vec_type))
+}
+
+fn is_full_range(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
+    let ty = cx.tables.expr_ty(expr);
+    let ty = walk_ptrs_ty(ty);
+    match_type(cx, ty, &["core", "ops", "range", "RangeFull"])
+}
diff --git a/tests/ui/match_on_vec_items.rs b/tests/ui/match_on_vec_items.rs
index 0bb39d77e46..30415e3b94d 100644
--- a/tests/ui/match_on_vec_items.rs
+++ b/tests/ui/match_on_vec_items.rs
@@ -120,6 +120,27 @@ fn match_with_array() {
     }
 }
 
+fn match_with_endless_range() {
+    let arr = vec![0, 1, 2, 3];
+    let range = ..;
+
+    // Ok
+    match arr[range] {
+        [0, 1] => println!("0 1"),
+        [1, 2] => println!("1 2"),
+        [0, 1, 2, 3] => println!("0, 1, 2, 3"),
+        _ => {},
+    }
+
+    // Ok
+    match arr[..] {
+        [0, 1] => println!("0 1"),
+        [1, 2] => println!("1 2"),
+        [0, 1, 2, 3] => println!("0, 1, 2, 3"),
+        _ => {},
+    }
+}
+
 fn main() {
     match_with_wildcard();
     match_without_wildcard();
@@ -127,4 +148,5 @@ fn main() {
     match_vec_ref();
     match_with_get();
     match_with_array();
+    match_with_endless_range();
 }