about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVishruth-Thimmaiah <vishruththimmaiah@gmail.com>2025-01-29 19:27:32 +0530
committerVishruth-Thimmaiah <vishruththimmaiah@gmail.com>2025-03-01 12:17:03 +0530
commit2cd3ea1f9d756f9029e969ed1758492e7620ab99 (patch)
treec6c7c173e1d63b04f795a4e6e3e8205662ae85bd
parent31236a491571f6fcf3d3be458ada764848f85734 (diff)
downloadrust-2cd3ea1f9d756f9029e969ed1758492e7620ab99.tar.gz
rust-2cd3ea1f9d756f9029e969ed1758492e7620ab99.zip
fix[`missing_asserts_for_indexing`]: ignore lint if first index is highest
-rw-r--r--clippy_lints/src/missing_asserts_for_indexing.rs25
-rw-r--r--tests/ui/missing_asserts_for_indexing.fixed10
-rw-r--r--tests/ui/missing_asserts_for_indexing.rs10
3 files changed, 41 insertions, 4 deletions
diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs
index 5ce3e73ae16..d9acf655b8a 100644
--- a/clippy_lints/src/missing_asserts_for_indexing.rs
+++ b/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -168,6 +168,7 @@ enum IndexEntry<'hir> {
     /// if the `assert!` asserts the right length.
     AssertWithIndex {
         highest_index: usize,
+        is_first_highest: bool,
         asserted_len: usize,
         assert_span: Span,
         slice: &'hir Expr<'hir>,
@@ -177,6 +178,7 @@ enum IndexEntry<'hir> {
     /// Indexing without an `assert!`
     IndexWithoutAssert {
         highest_index: usize,
+        is_first_highest: bool,
         indexes: Vec<Span>,
         slice: &'hir Expr<'hir>,
     },
@@ -247,6 +249,7 @@ fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Uni
                     if slice.span.lo() > assert_span.lo() {
                         *entry = IndexEntry::AssertWithIndex {
                             highest_index: index,
+                            is_first_highest: true,
                             asserted_len: *asserted_len,
                             assert_span: *assert_span,
                             slice,
@@ -256,18 +259,28 @@ fn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Uni
                     }
                 },
                 IndexEntry::IndexWithoutAssert {
-                    highest_index, indexes, ..
+                    highest_index,
+                    indexes,
+                    is_first_highest,
+                    ..
                 }
                 | IndexEntry::AssertWithIndex {
-                    highest_index, indexes, ..
+                    highest_index,
+                    indexes,
+                    is_first_highest,
+                    ..
                 } => {
                     indexes.push(expr.span);
+                    if *is_first_highest {
+                        (*is_first_highest) = *highest_index >= index;
+                    }
                     *highest_index = (*highest_index).max(index);
                 },
             }
         } else {
             indexes.push(IndexEntry::IndexWithoutAssert {
                 highest_index: index,
+                is_first_highest: true,
                 indexes: vec![expr.span],
                 slice,
             });
@@ -286,6 +299,7 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un
         if let Some(entry) = entry {
             if let IndexEntry::IndexWithoutAssert {
                 highest_index,
+                is_first_highest,
                 indexes,
                 slice,
             } = entry
@@ -294,6 +308,7 @@ fn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut Un
                 *entry = IndexEntry::AssertWithIndex {
                     highest_index: *highest_index,
                     indexes: mem::take(indexes),
+                    is_first_highest: *is_first_highest,
                     slice,
                     assert_span: expr.span,
                     comparison,
@@ -328,12 +343,13 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap<u64, Vec<IndexEntry<'_>
             match *entry {
                 IndexEntry::AssertWithIndex {
                     highest_index,
+                    is_first_highest,
                     asserted_len,
                     ref indexes,
                     comparison,
                     assert_span,
                     slice,
-                } if indexes.len() > 1 => {
+                } if indexes.len() > 1 && !is_first_highest => {
                     // if we have found an `assert!`, let's also check that it's actually right
                     // and if it covers the highest index and if not, suggest the correct length
                     let sugg = match comparison {
@@ -381,8 +397,9 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnindexMap<u64, Vec<IndexEntry<'_>
                 IndexEntry::IndexWithoutAssert {
                     ref indexes,
                     highest_index,
+                    is_first_highest,
                     slice,
-                } if indexes.len() > 1 => {
+                } if indexes.len() > 1 && !is_first_highest => {
                     // if there was no `assert!` but more than one index, suggest
                     // adding an `assert!` that covers the highest index
                     report_lint(
diff --git a/tests/ui/missing_asserts_for_indexing.fixed b/tests/ui/missing_asserts_for_indexing.fixed
index 3bbafe0bba3..6e803322f65 100644
--- a/tests/ui/missing_asserts_for_indexing.fixed
+++ b/tests/ui/missing_asserts_for_indexing.fixed
@@ -139,4 +139,14 @@ fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {
     let _ = v4[0] + v4[1] + v4[2];
 }
 
+// ok
+fn same_index_multiple_times(v1: &[u8]) {
+    let _ = v1[0] + v1[0];
+}
+
+// ok
+fn highest_index_first(v1: &[u8]) {
+    let _ = v1[2] + v1[1] + v1[0];
+}
+
 fn main() {}
diff --git a/tests/ui/missing_asserts_for_indexing.rs b/tests/ui/missing_asserts_for_indexing.rs
index f8ea0173c13..4614a8ef5d0 100644
--- a/tests/ui/missing_asserts_for_indexing.rs
+++ b/tests/ui/missing_asserts_for_indexing.rs
@@ -139,4 +139,14 @@ fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {
     let _ = v4[0] + v4[1] + v4[2];
 }
 
+// ok
+fn same_index_multiple_times(v1: &[u8]) {
+    let _ = v1[0] + v1[0];
+}
+
+// ok
+fn highest_index_first(v1: &[u8]) {
+    let _ = v1[2] + v1[1] + v1[0];
+}
+
 fn main() {}