about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-02 16:13:02 +0000
committerbors <bors@rust-lang.org>2020-05-02 16:13:02 +0000
commit76ddac5e8e9f588fda939cf8ec116e5926419758 (patch)
treed0ec8c063f1d4e1d8edce03847324d6510395f4d
parent75a717159d33037915f16932967b997f4fbd1dcc (diff)
parentde58c5644de0d9ffe46e7e2923d2301eaf4dd347 (diff)
downloadrust-76ddac5e8e9f588fda939cf8ec116e5926419758.tar.gz
rust-76ddac5e8e9f588fda939cf8ec116e5926419758.zip
Auto merge of #5560 - CrazyRoka:fix-match-on-vector-full-range, r=phansch,flip1995
Fix match on vec items: match on vec[..]

- Added new tests
- Fixed false positive when matching on full range, which will never panic

Closes #5551
changelog: fix match_on_vec_items when matching full range
-rw-r--r--clippy_lints/src/match_on_vec_items.rs21
-rw-r--r--clippy_lints/src/utils/paths.rs2
-rw-r--r--tests/ui/match_on_vec_items.rs22
3 files changed, 39 insertions, 6 deletions
diff --git a/clippy_lints/src/match_on_vec_items.rs b/clippy_lints/src/match_on_vec_items.rs
index 421571d2f2f..ee69628e9f0 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::{self, 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, &utils::paths::RANGE_FULL)
+}
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index ca2c4ade155..79ca6845c6f 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -85,7 +85,7 @@ pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
 pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
 pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
 pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
-pub const RANGE_FULL: [&str; 3] = ["core", "ops", "RangeFull"];
+pub const RANGE_FULL: [&str; 4] = ["core", "ops", "range", "RangeFull"];
 pub const RANGE_FULL_STD: [&str; 3] = ["std", "ops", "RangeFull"];
 pub const RANGE_INCLUSIVE_NEW: [&str; 4] = ["core", "ops", "RangeInclusive", "new"];
 pub const RANGE_INCLUSIVE_STD_NEW: [&str; 4] = ["std", "ops", "RangeInclusive", "new"];
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();
 }