Auto merge of #12488 - Jacherr:issue-11525, r=llogiq

Disable `indexing_slicing` for custom Index impls

Fixes https://github.com/rust-lang/rust-clippy/issues/11525

Disables `indexing_slicing` for custom Index impls, specifically any implementations that also do not have a `get` method anywhere along the deref chain (so, for example, it still lints on Vec, which has its `get` method as part of the deref chain).

Thanks `@y21` for pointing me in the right direction with a couple of handy util functions for deref chain and inherent methods, saved a headache there!

changelog: FP: Disable `indexing_slicing` for custom Index impls
This commit is contained in:
bors 2024-05-31 16:42:50 +00:00
commit 28e887fe71
5 changed files with 232 additions and 54 deletions

View file

@ -2,7 +2,89 @@
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
#![warn(clippy::out_of_bounds_indexing)]
#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec)]
#![allow(
clippy::no_effect,
clippy::unnecessary_operation,
clippy::useless_vec,
unused_must_use,
unused
)]
#![warn(clippy::indexing_slicing)]
use std::ops::Index;
struct BoolMap<T> {
false_value: T,
true_value: T,
}
impl<T> Index<bool> for BoolMap<T> {
type Output = T;
fn index(&self, index: bool) -> &T {
if index { &self.true_value } else { &self.false_value }
}
}
struct BoolMapWithGet<T> {
false_value: T,
true_value: T,
}
impl<T> Index<bool> for BoolMapWithGet<T> {
type Output = T;
fn index(&self, index: bool) -> &Self::Output {
if index { &self.true_value } else { &self.false_value }
}
}
impl<T> BoolMapWithGet<T> {
fn get(&self, index: bool) -> Option<&T> {
if index {
Some(&self.true_value)
} else {
Some(&self.false_value)
}
}
}
struct S<T>(T);
impl S<i32> {
fn get() -> Option<i32> {
unimplemented!()
}
}
impl<T> Index<i32> for S<T> {
type Output = T;
fn index(&self, _index: i32) -> &Self::Output {
&self.0
}
}
struct Y<T>(T);
impl Y<i32> {
fn get<U>() -> Option<U> {
unimplemented!()
}
}
impl<T> Index<i32> for Y<T> {
type Output = T;
fn index(&self, _index: i32) -> &Self::Output {
&self.0
}
}
struct Z<T>(T);
impl<T> Z<T> {
fn get<T2>() -> T2 {
unimplemented!()
}
}
impl<T> Index<i32> for Z<T> {
type Output = T;
fn index(&self, _index: i32) -> &Self::Output {
&self.0
}
}
fn main() {
let x = [1, 2, 3, 4];
@ -51,4 +133,28 @@ fn main() {
//~^ ERROR: slicing may panic
&v[..]; // Ok, should not produce stderr.
let map = BoolMap {
false_value: 2,
true_value: 4,
};
map[true]; // Ok, because `get` does not exist (custom indexing)
let map_with_get = BoolMapWithGet {
false_value: 2,
true_value: 4,
};
// Lint on this, because `get` does exist with same signature
map_with_get[true];
let s = S::<i32>(1);
s[0];
let y = Y::<i32>(1);
y[0];
let z = Z::<i32>(1);
z[0];
}

View file

@ -1,5 +1,5 @@
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:12:6
--> tests/ui/indexing_slicing_slice.rs:94:6
|
LL | &x[index..];
| ^^^^^^^^^^
@ -9,7 +9,7 @@ LL | &x[index..];
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:14:6
--> tests/ui/indexing_slicing_slice.rs:96:6
|
LL | &x[..index];
| ^^^^^^^^^^
@ -17,7 +17,7 @@ LL | &x[..index];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:16:6
--> tests/ui/indexing_slicing_slice.rs:98:6
|
LL | &x[index_from..index_to];
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -25,7 +25,7 @@ LL | &x[index_from..index_to];
= help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:18:6
--> tests/ui/indexing_slicing_slice.rs:100:6
|
LL | &x[index_from..][..index_to];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -33,7 +33,7 @@ LL | &x[index_from..][..index_to];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:18:6
--> tests/ui/indexing_slicing_slice.rs:100:6
|
LL | &x[index_from..][..index_to];
| ^^^^^^^^^^^^^^^
@ -41,7 +41,7 @@ LL | &x[index_from..][..index_to];
= help: consider using `.get(n..)` or .get_mut(n..)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:21:6
--> tests/ui/indexing_slicing_slice.rs:103:6
|
LL | &x[5..][..10];
| ^^^^^^^^^^^^
@ -49,7 +49,7 @@ LL | &x[5..][..10];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:21:8
--> tests/ui/indexing_slicing_slice.rs:103:8
|
LL | &x[5..][..10];
| ^
@ -58,7 +58,7 @@ LL | &x[5..][..10];
= help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:25:6
--> tests/ui/indexing_slicing_slice.rs:107:6
|
LL | &x[0..][..3];
| ^^^^^^^^^^^
@ -66,7 +66,7 @@ LL | &x[0..][..3];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:27:6
--> tests/ui/indexing_slicing_slice.rs:109:6
|
LL | &x[1..][..5];
| ^^^^^^^^^^^
@ -74,19 +74,19 @@ LL | &x[1..][..5];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:35:12
--> tests/ui/indexing_slicing_slice.rs:117:12
|
LL | &y[0..=4];
| ^
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:37:11
--> tests/ui/indexing_slicing_slice.rs:119:11
|
LL | &y[..=4];
| ^
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:43:6
--> tests/ui/indexing_slicing_slice.rs:125:6
|
LL | &v[10..100];
| ^^^^^^^^^^
@ -94,7 +94,7 @@ LL | &v[10..100];
= help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:45:6
--> tests/ui/indexing_slicing_slice.rs:127:6
|
LL | &x[10..][..100];
| ^^^^^^^^^^^^^^
@ -102,13 +102,13 @@ LL | &x[10..][..100];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:45:8
--> tests/ui/indexing_slicing_slice.rs:127:8
|
LL | &x[10..][..100];
| ^^
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:48:6
--> tests/ui/indexing_slicing_slice.rs:130:6
|
LL | &v[10..];
| ^^^^^^^
@ -116,12 +116,36 @@ LL | &v[10..];
= help: consider using `.get(n..)` or .get_mut(n..)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:50:6
--> tests/ui/indexing_slicing_slice.rs:132:6
|
LL | &v[..100];
| ^^^^^^^^
|
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: aborting due to 16 previous errors
error: indexing may panic
--> tests/ui/indexing_slicing_slice.rs:150:5
|
LL | map_with_get[true];
| ^^^^^^^^^^^^^^^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_slice.rs:153:5
|
LL | s[0];
| ^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_slice.rs:156:5
|
LL | y[0];
| ^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: aborting due to 19 previous errors