Skip to content

Commit a7c0ff3

Browse files
committed
This commit represents an attempt to address changes requested in the process of reviewing PR #2790.
The changes reflected in this commit are as follows: - Revised `IndexingSlicingPass` struct name to IndexingSlicing for consistency with the rest of the code base. - Revised match arm condition to use `(..)` shorthand in favor of `(_, _, _)`. - Restored a couple telling variable names. - Calls to `cx.span_lint` were revised to use `utils::span_help_and_lint`. - Took a stab at refactoring some generalizable calls to `utils::span_help_and_lint` to minimize duplicate code. - Revised INDEXING_SLICING declaration to pedantic rather than restriction. - Added `&x[0..].get(..3)` to the test cases.
1 parent 5b759ef commit a7c0ff3

File tree

4 files changed

+164
-114
lines changed

4 files changed

+164
-114
lines changed

clippy_lints/src/indexing_slicing.rs

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -59,30 +59,30 @@ declare_clippy_lint! {
5959
/// ```
6060
declare_clippy_lint! {
6161
pub INDEXING_SLICING,
62-
restriction,
62+
pedantic,
6363
"indexing/slicing usage"
6464
}
6565

6666
#[derive(Copy, Clone)]
67-
pub struct IndexingSlicingPass;
67+
pub struct IndexingSlicing;
6868

69-
impl LintPass for IndexingSlicingPass {
69+
impl LintPass for IndexingSlicing {
7070
fn get_lints(&self) -> LintArray {
7171
lint_array!(INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING)
7272
}
7373
}
7474

75-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicingPass {
75+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
7676
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
77-
if let ExprIndex(ref a, ref b) = &expr.node {
78-
match &b.node {
77+
if let ExprIndex(ref array, ref index) = &expr.node {
78+
match &index.node {
7979
// Both ExprStruct and ExprPath require this approach's checks
80-
// on the `range` returned by `higher::range(cx, b)`.
80+
// on the `range` returned by `higher::range(cx, index)`.
8181
// ExprStruct handles &x[n..m], &x[n..] and &x[..n].
8282
// ExprPath handles &x[..] and x[var]
83-
ExprStruct(_, _, _) | ExprPath(_) => {
84-
if let Some(range) = higher::range(cx, b) {
85-
let ty = cx.tables.expr_ty(a);
83+
ExprStruct(..) | ExprPath(..) => {
84+
if let Some(range) = higher::range(cx, index) {
85+
let ty = cx.tables.expr_ty(array);
8686
if let ty::TyArray(_, s) = ty.sty {
8787
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
8888
// Index is a constant range.
@@ -100,49 +100,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicingPass {
100100
}
101101
}
102102
}
103+
104+
let help_msg;
103105
match (range.start, range.end) {
104106
(None, Some(_)) => {
105-
cx.span_lint(
106-
INDEXING_SLICING,
107-
expr.span,
108-
"slicing may panic. Consider using \
109-
`.get(..n)`or `.get_mut(..n)` instead",
110-
);
107+
help_msg = "Consider using `.get(..n)`or `.get_mut(..n)` instead";
111108
}
112109
(Some(_), None) => {
113-
cx.span_lint(
114-
INDEXING_SLICING,
115-
expr.span,
116-
"slicing may panic. Consider using \
117-
`.get(n..)` or .get_mut(n..)` instead",
118-
);
110+
help_msg = "Consider using `.get(n..)` or .get_mut(n..)` instead";
119111
}
120112
(Some(_), Some(_)) => {
121-
cx.span_lint(
122-
INDEXING_SLICING,
123-
expr.span,
124-
"slicing may panic. Consider using \
125-
`.get(n..m)` or `.get_mut(n..m)` instead",
126-
);
113+
help_msg =
114+
"Consider using `.get(n..m)` or `.get_mut(n..m)` instead";
127115
}
128-
(None, None) => (),
116+
(None, None) => return, // [..] is ok
129117
}
118+
119+
utils::span_help_and_lint(
120+
cx,
121+
INDEXING_SLICING,
122+
expr.span,
123+
"slicing may panic.",
124+
help_msg,
125+
);
130126
} else {
131-
cx.span_lint(
127+
utils::span_help_and_lint(
128+
cx,
132129
INDEXING_SLICING,
133130
expr.span,
134-
"indexing may panic. Consider using `.get(n)` or \
135-
`.get_mut(n)` instead",
131+
"indexing may panic.",
132+
"Consider using `.get(n)` or `.get_mut(n)` instead",
136133
);
137134
}
138135
}
139-
ExprLit(_) => {
136+
ExprLit(..) => {
140137
// [n]
141-
let ty = cx.tables.expr_ty(a);
138+
let ty = cx.tables.expr_ty(array);
142139
if let ty::TyArray(_, s) = ty.sty {
143140
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
144141
// Index is a constant uint.
145-
if let Some((Constant::Int(const_index), _)) = constant(cx, cx.tables, b) {
142+
if let Some((Constant::Int(const_index), _)) =
143+
constant(cx, cx.tables, index)
144+
{
146145
if size <= const_index {
147146
utils::span_lint(
148147
cx,
@@ -154,11 +153,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicingPass {
154153
// Else index is in bounds, ok.
155154
}
156155
} else {
157-
cx.span_lint(
156+
utils::span_help_and_lint(
157+
cx,
158158
INDEXING_SLICING,
159159
expr.span,
160-
"indexing may panic. Consider using `.get(n)` or \
161-
`.get_mut(n)` instead",
160+
"indexing may panic.",
161+
"Consider using `.get(n)` or `.get_mut(n)` instead",
162162
);
163163
}
164164
}

clippy_lints/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
431431
reg.register_late_lint_pass(box unwrap::Pass);
432432
reg.register_late_lint_pass(box duration_subsec::DurationSubsec);
433433
reg.register_late_lint_pass(box default_trait_access::DefaultTraitAccess);
434-
reg.register_late_lint_pass(box indexing_slicing::IndexingSlicingPass);
434+
reg.register_late_lint_pass(box indexing_slicing::IndexingSlicing);
435435

436436
reg.register_lint_group("clippy_restriction", vec![
437437
arithmetic::FLOAT_ARITHMETIC,

tests/ui/indexing_slicing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fn main() {
2121
&x[1..][..5];
2222
&x[0..3];
2323
&x[0..][..3];
24+
&x[0..].get(..3); // Ok
2425
&x[0..=4];
2526
&x[..=4];
2627
&x[..];

0 commit comments

Comments
 (0)