Skip to content

Commit b0115fb

Browse files
committed
Removed unnecessary code, added support for vector references
1 parent 96e2bc8 commit b0115fb

File tree

4 files changed

+94
-71
lines changed

4 files changed

+94
-71
lines changed

clippy_lints/src/consts.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,9 +358,9 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
358358
},
359359
(Some(Constant::Vec(vec)), _) => {
360360
if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) {
361-
match vec[0] {
362-
Constant::F32(x) => Some(Constant::F32(x)),
363-
Constant::F64(x) => Some(Constant::F64(x)),
361+
match vec.get(0) {
362+
Some(Constant::F32(x)) => Some(Constant::F32(*x)),
363+
Some(Constant::F64(x)) => Some(Constant::F64(*x)),
364364
_ => None,
365365
}
366366
} else {

clippy_lints/src/match_vec_item.rs

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::utils::{is_wild, span_lint_and_help};
1+
use crate::utils::{is_type_diagnostic_item, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty};
22
use if_chain::if_chain;
3-
use rustc_hir::{Arm, Expr, ExprKind, MatchSource};
3+
use rustc_errors::Applicability;
4+
use rustc_hir::{Expr, ExprKind, MatchSource};
45
use rustc_lint::{LateContext, LateLintPass, LintContext};
56
use rustc_middle::lint::in_external_macro;
6-
use rustc_middle::ty::{self, AdtDef};
77
use rustc_session::{declare_lint_pass, declare_tool_lint};
88

99
declare_clippy_lint! {
@@ -48,64 +48,41 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchVecItem {
4848
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) {
4949
if_chain! {
5050
if !in_external_macro(cx.sess(), expr.span);
51-
if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.kind;
52-
if contains_wild_arm(arms);
53-
if is_vec_indexing(cx, ex);
51+
if let ExprKind::Match(ref match_expr, _, MatchSource::Normal) = expr.kind;
52+
if let Some(idx_expr) = is_vec_indexing(cx, match_expr);
53+
if let ExprKind::Index(vec, idx) = idx_expr.kind;
5454

5555
then {
56-
span_lint_and_help(
56+
let mut applicability = Applicability::MaybeIncorrect;
57+
span_lint_and_sugg(
5758
cx,
5859
MATCH_VEC_ITEM,
59-
expr.span,
60-
"indexing vector may panic",
61-
None,
62-
"consider using `get(..)` instead.",
60+
match_expr.span,
61+
"indexing vector may panic. Consider using `get`",
62+
"try this",
63+
format!(
64+
"{}.get({})",
65+
snippet_with_applicability(cx, vec.span, "..", &mut applicability),
66+
snippet_with_applicability(cx, idx.span, "..", &mut applicability)
67+
),
68+
applicability
6369
);
6470
}
6571
}
6672
}
6773
}
6874

69-
fn contains_wild_arm(arms: &[Arm<'_>]) -> bool {
70-
arms.iter().any(|arm| is_wild(&arm.pat) && is_unit_expr(arm.body))
71-
}
72-
73-
fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
75+
fn is_vec_indexing<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
7476
if_chain! {
7577
if let ExprKind::Index(ref array, _) = expr.kind;
7678
let ty = cx.tables.expr_ty(array);
77-
if let ty::Adt(def, _) = ty.kind;
78-
if is_vec(cx, def);
79+
let ty = walk_ptrs_ty(ty);
80+
if is_type_diagnostic_item(cx, ty, sym!(vec_type));
7981

8082
then {
81-
return true;
83+
return Some(expr);
8284
}
8385
}
8486

85-
false
86-
}
87-
88-
fn is_vec<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, def: &'a AdtDef) -> bool {
89-
if_chain! {
90-
let def_path = cx.tcx.def_path(def.did);
91-
if def_path.data.len() == 2;
92-
if let Some(module) = def_path.data.get(0);
93-
if module.data.as_symbol() == sym!(vec);
94-
if let Some(name) = def_path.data.get(1);
95-
if name.data.as_symbol() == sym!(Vec);
96-
97-
then {
98-
return true;
99-
}
100-
}
101-
102-
false
103-
}
104-
105-
fn is_unit_expr(expr: &Expr<'_>) -> bool {
106-
match expr.kind {
107-
ExprKind::Tup(ref v) if v.is_empty() => true,
108-
ExprKind::Block(ref b, _) if b.stmts.is_empty() && b.expr.is_none() => true,
109-
_ => false,
110-
}
87+
None
11188
}

tests/ui/match_vec_item.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ fn main() {
44
match_with_wildcard();
55
match_without_wildcard();
66
match_wildcard_and_action();
7+
match_vec_ref();
78
match_with_get();
89
match_with_array();
910
}
@@ -33,14 +34,14 @@ fn match_without_wildcard() {
3334
let range = 1..3;
3435
let idx = 2;
3536

36-
// Ok
37+
// Lint, may panic
3738
match arr[idx] {
3839
0 => println!("0"),
3940
1 => println!("1"),
4041
num => {},
4142
}
4243

43-
// Ok
44+
// Lint, may panic
4445
match arr[range] {
4546
[0, 1] => println!("0 1"),
4647
[1, 2] => println!("1 2"),
@@ -53,21 +54,41 @@ fn match_wildcard_and_action() {
5354
let range = 1..3;
5455
let idx = 3;
5556

56-
// Ok
57+
// Lint, may panic
5758
match arr[idx] {
5859
0 => println!("0"),
5960
1 => println!("1"),
6061
_ => println!("Hello, World!"),
6162
}
6263

63-
// Ok
64+
// Lint, may panic
6465
match arr[range] {
6566
[0, 1] => println!("0 1"),
6667
[1, 2] => println!("1 2"),
6768
_ => println!("Hello, World!"),
6869
}
6970
}
7071

72+
fn match_vec_ref() {
73+
let arr = &vec![0, 1, 2, 3];
74+
let range = 1..3;
75+
let idx = 3;
76+
77+
// Lint, may panic
78+
match arr[idx] {
79+
0 => println!("0"),
80+
1 => println!("1"),
81+
_ => {},
82+
}
83+
84+
// Lint, may panic
85+
match arr[range] {
86+
[0, 1] => println!("0 1"),
87+
[1, 2] => println!("1 2"),
88+
_ => {},
89+
}
90+
}
91+
7192
fn match_with_get() {
7293
let arr = vec![0, 1, 2, 3];
7394
let range = 1..3;

tests/ui/match_vec_item.stderr

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,52 @@
1-
error: indexing vector may panic
2-
--> $DIR/match_vec_item.rs:17:5
1+
error: indexing vector may panic. Consider using `get`
2+
--> $DIR/match_vec_item.rs:18:11
33
|
4-
LL | / match arr[idx] {
5-
LL | | 0 => println!("0"),
6-
LL | | 1 => println!("1"),
7-
LL | | _ => {},
8-
LL | | }
9-
| |_____^
4+
LL | match arr[idx] {
5+
| ^^^^^^^^ help: try this: `arr.get(idx)`
106
|
117
= note: `-D clippy::match-vec-item` implied by `-D warnings`
12-
= help: consider using `get(..)` instead.
138

14-
error: indexing vector may panic
15-
--> $DIR/match_vec_item.rs:24:5
9+
error: indexing vector may panic. Consider using `get`
10+
--> $DIR/match_vec_item.rs:25:11
1611
|
17-
LL | / match arr[range] {
18-
LL | | [0, 1] => println!("0 1"),
19-
LL | | [1, 2] => println!("1 2"),
20-
LL | | _ => {},
21-
LL | | }
22-
| |_____^
12+
LL | match arr[range] {
13+
| ^^^^^^^^^^ help: try this: `arr.get(range)`
14+
15+
error: indexing vector may panic. Consider using `get`
16+
--> $DIR/match_vec_item.rs:38:11
17+
|
18+
LL | match arr[idx] {
19+
| ^^^^^^^^ help: try this: `arr.get(idx)`
20+
21+
error: indexing vector may panic. Consider using `get`
22+
--> $DIR/match_vec_item.rs:45:11
23+
|
24+
LL | match arr[range] {
25+
| ^^^^^^^^^^ help: try this: `arr.get(range)`
26+
27+
error: indexing vector may panic. Consider using `get`
28+
--> $DIR/match_vec_item.rs:58:11
29+
|
30+
LL | match arr[idx] {
31+
| ^^^^^^^^ help: try this: `arr.get(idx)`
32+
33+
error: indexing vector may panic. Consider using `get`
34+
--> $DIR/match_vec_item.rs:65:11
35+
|
36+
LL | match arr[range] {
37+
| ^^^^^^^^^^ help: try this: `arr.get(range)`
38+
39+
error: indexing vector may panic. Consider using `get`
40+
--> $DIR/match_vec_item.rs:78:11
41+
|
42+
LL | match arr[idx] {
43+
| ^^^^^^^^ help: try this: `arr.get(idx)`
44+
45+
error: indexing vector may panic. Consider using `get`
46+
--> $DIR/match_vec_item.rs:85:11
2347
|
24-
= help: consider using `get(..)` instead.
48+
LL | match arr[range] {
49+
| ^^^^^^^^^^ help: try this: `arr.get(range)`
2550

26-
error: aborting due to 2 previous errors
51+
error: aborting due to 8 previous errors
2752

0 commit comments

Comments
 (0)