Skip to content

Commit 41f2ecc

Browse files
committed
Auto merge of #8588 - pitaj:fix-8348, r=flip1995
`indexing_slicing` should not fire if a valid array index comes from a constant function that is evaluated at compile-time fix #8348 changelog: [`indexing_slicing`] fewer false positives in `const` contexts and with `const` indices
2 parents 9a09506 + 21eae8c commit 41f2ecc

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

clippy_lints/src/indexing_slicing.rs

+8
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ declare_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]
9696

9797
impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
9898
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
99+
if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
100+
return;
101+
}
102+
99103
if let ExprKind::Index(array, index) = &expr.kind {
100104
let ty = cx.typeck_results().expr_ty(array).peel_refs();
101105
if let Some(range) = higher::Range::hir(index) {
@@ -151,6 +155,10 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
151155
} else {
152156
// Catchall non-range index, i.e., [n] or [n << m]
153157
if let ty::Array(..) = ty.kind() {
158+
// Index is a const block.
159+
if let ExprKind::ConstBlock(..) = index.kind {
160+
return;
161+
}
154162
// Index is a constant uint.
155163
if let Some(..) = constant(cx, cx.typeck_results(), index) {
156164
// Let rustc's `const_err` lint handle constant `usize` indexing on arrays.

tests/ui/indexing_slicing_index.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
1+
#![feature(inline_const)]
12
#![warn(clippy::indexing_slicing)]
23
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
34
// we want to avoid false positives.
45
#![warn(clippy::out_of_bounds_indexing)]
5-
#![allow(clippy::no_effect, clippy::unnecessary_operation)]
6+
#![allow(const_err, clippy::no_effect, clippy::unnecessary_operation)]
7+
8+
const ARR: [i32; 2] = [1, 2];
9+
const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr.
10+
const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
11+
12+
const fn idx() -> usize {
13+
1
14+
}
15+
const fn idx4() -> usize {
16+
4
17+
}
618

719
fn main() {
820
let x = [1, 2, 3, 4];
921
let index: usize = 1;
1022
x[index];
11-
x[4]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
12-
x[1 << 3]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
23+
x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
24+
x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
1325

1426
x[0]; // Ok, should not produce stderr.
1527
x[3]; // Ok, should not produce stderr.
28+
x[const { idx() }]; // Ok, should not produce stderr.
29+
x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
30+
const { &ARR[idx()] }; // Ok, should not produce stderr.
31+
const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
1632

1733
let y = &x;
1834
y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021
@@ -25,7 +41,7 @@ fn main() {
2541

2642
const N: usize = 15; // Out of bounds
2743
const M: usize = 3; // In bounds
28-
x[N]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
44+
x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
2945
x[M]; // Ok, should not produce stderr.
3046
v[N];
3147
v[M];
+20-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
1+
error[E0080]: evaluation of `main::{constant#3}::<&i32>` failed
2+
--> $DIR/indexing_slicing_index.rs:31:14
3+
|
4+
LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
5+
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
6+
7+
error[E0080]: erroneous constant used
8+
--> $DIR/indexing_slicing_index.rs:31:5
9+
|
10+
LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
11+
| ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
12+
113
error: indexing may panic
2-
--> $DIR/indexing_slicing_index.rs:10:5
14+
--> $DIR/indexing_slicing_index.rs:22:5
315
|
416
LL | x[index];
517
| ^^^^^^^^
@@ -8,44 +20,45 @@ LL | x[index];
820
= help: consider using `.get(n)` or `.get_mut(n)` instead
921

1022
error: indexing may panic
11-
--> $DIR/indexing_slicing_index.rs:22:5
23+
--> $DIR/indexing_slicing_index.rs:38:5
1224
|
1325
LL | v[0];
1426
| ^^^^
1527
|
1628
= help: consider using `.get(n)` or `.get_mut(n)` instead
1729

1830
error: indexing may panic
19-
--> $DIR/indexing_slicing_index.rs:23:5
31+
--> $DIR/indexing_slicing_index.rs:39:5
2032
|
2133
LL | v[10];
2234
| ^^^^^
2335
|
2436
= help: consider using `.get(n)` or `.get_mut(n)` instead
2537

2638
error: indexing may panic
27-
--> $DIR/indexing_slicing_index.rs:24:5
39+
--> $DIR/indexing_slicing_index.rs:40:5
2840
|
2941
LL | v[1 << 3];
3042
| ^^^^^^^^^
3143
|
3244
= help: consider using `.get(n)` or `.get_mut(n)` instead
3345

3446
error: indexing may panic
35-
--> $DIR/indexing_slicing_index.rs:30:5
47+
--> $DIR/indexing_slicing_index.rs:46:5
3648
|
3749
LL | v[N];
3850
| ^^^^
3951
|
4052
= help: consider using `.get(n)` or `.get_mut(n)` instead
4153

4254
error: indexing may panic
43-
--> $DIR/indexing_slicing_index.rs:31:5
55+
--> $DIR/indexing_slicing_index.rs:47:5
4456
|
4557
LL | v[M];
4658
| ^^^^
4759
|
4860
= help: consider using `.get(n)` or `.get_mut(n)` instead
4961

50-
error: aborting due to 6 previous errors
62+
error: aborting due to 8 previous errors
5163

64+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)