Skip to content

Commit

Permalink
Auto merge of rust-lang#5560 - CrazyRoka:fix-match-on-vector-full-ran…
Browse files Browse the repository at this point in the history
…ge, 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 rust-lang#5551
changelog: fix match_on_vec_items when matching full range
  • Loading branch information
bors committed May 2, 2020
2 parents 75a7171 + de58c56 commit 76ddac5
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
21 changes: 16 additions & 5 deletions clippy_lints/src/match_on_vec_items.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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);
Expand All @@ -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)
}
2 changes: 1 addition & 1 deletion clippy_lints/src/utils/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
Expand Down
22 changes: 22 additions & 0 deletions tests/ui/match_on_vec_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,33 @@ 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();
match_wildcard_and_action();
match_vec_ref();
match_with_get();
match_with_array();
match_with_endless_range();
}

0 comments on commit 76ddac5

Please sign in to comment.