Skip to content

Commit 2cd3ea1

Browse files
fix[missing_asserts_for_indexing]: ignore lint if first index is highest
1 parent 31236a4 commit 2cd3ea1

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

clippy_lints/src/missing_asserts_for_indexing.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ enum IndexEntry<'hir> {
168168
/// if the `assert!` asserts the right length.
169169
AssertWithIndex {
170170
highest_index: usize,
171+
is_first_highest: bool,
171172
asserted_len: usize,
172173
assert_span: Span,
173174
slice: &'hir Expr<'hir>,
@@ -177,6 +178,7 @@ enum IndexEntry<'hir> {
177178
/// Indexing without an `assert!`
178179
IndexWithoutAssert {
179180
highest_index: usize,
181+
is_first_highest: bool,
180182
indexes: Vec<Span>,
181183
slice: &'hir Expr<'hir>,
182184
},
@@ -247,6 +249,7 @@ fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Uni
247249
if slice.span.lo() > assert_span.lo() {
248250
*entry = IndexEntry::AssertWithIndex {
249251
highest_index: index,
252+
is_first_highest: true,
250253
asserted_len: *asserted_len,
251254
assert_span: *assert_span,
252255
slice,
@@ -256,18 +259,28 @@ fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Uni
256259
}
257260
},
258261
IndexEntry::IndexWithoutAssert {
259-
highest_index, indexes, ..
262+
highest_index,
263+
indexes,
264+
is_first_highest,
265+
..
260266
}
261267
| IndexEntry::AssertWithIndex {
262-
highest_index, indexes, ..
268+
highest_index,
269+
indexes,
270+
is_first_highest,
271+
..
263272
} => {
264273
indexes.push(expr.span);
274+
if *is_first_highest {
275+
(*is_first_highest) = *highest_index >= index;
276+
}
265277
*highest_index = (*highest_index).max(index);
266278
},
267279
}
268280
} else {
269281
indexes.push(IndexEntry::IndexWithoutAssert {
270282
highest_index: index,
283+
is_first_highest: true,
271284
indexes: vec![expr.span],
272285
slice,
273286
});
@@ -286,6 +299,7 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un
286299
if let Some(entry) = entry {
287300
if let IndexEntry::IndexWithoutAssert {
288301
highest_index,
302+
is_first_highest,
289303
indexes,
290304
slice,
291305
} = entry
@@ -294,6 +308,7 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un
294308
*entry = IndexEntry::AssertWithIndex {
295309
highest_index: *highest_index,
296310
indexes: mem::take(indexes),
311+
is_first_highest: *is_first_highest,
297312
slice,
298313
assert_span: expr.span,
299314
comparison,
@@ -328,12 +343,13 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap<u64, Vec<IndexEntry<'_>
328343
match *entry {
329344
IndexEntry::AssertWithIndex {
330345
highest_index,
346+
is_first_highest,
331347
asserted_len,
332348
ref indexes,
333349
comparison,
334350
assert_span,
335351
slice,
336-
} if indexes.len() > 1 => {
352+
} if indexes.len() > 1 && !is_first_highest => {
337353
// if we have found an `assert!`, let's also check that it's actually right
338354
// and if it covers the highest index and if not, suggest the correct length
339355
let sugg = match comparison {
@@ -381,8 +397,9 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap<u64, Vec<IndexEntry<'_>
381397
IndexEntry::IndexWithoutAssert {
382398
ref indexes,
383399
highest_index,
400+
is_first_highest,
384401
slice,
385-
} if indexes.len() > 1 => {
402+
} if indexes.len() > 1 && !is_first_highest => {
386403
// if there was no `assert!` but more than one index, suggest
387404
// adding an `assert!` that covers the highest index
388405
report_lint(

tests/ui/missing_asserts_for_indexing.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,14 @@ fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {
139139
let _ = v4[0] + v4[1] + v4[2];
140140
}
141141

142+
// ok
143+
fn same_index_multiple_times(v1: &[u8]) {
144+
let _ = v1[0] + v1[0];
145+
}
146+
147+
// ok
148+
fn highest_index_first(v1: &[u8]) {
149+
let _ = v1[2] + v1[1] + v1[0];
150+
}
151+
142152
fn main() {}

tests/ui/missing_asserts_for_indexing.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,14 @@ fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {
139139
let _ = v4[0] + v4[1] + v4[2];
140140
}
141141

142+
// ok
143+
fn same_index_multiple_times(v1: &[u8]) {
144+
let _ = v1[0] + v1[0];
145+
}
146+
147+
// ok
148+
fn highest_index_first(v1: &[u8]) {
149+
let _ = v1[2] + v1[1] + v1[0];
150+
}
151+
142152
fn main() {}

0 commit comments

Comments
 (0)