Skip to content

Commit d5c9e76

Browse files
committed
const_prop_lint: Consider array length constant even if array is not
1 parent 983f4da commit d5c9e76

File tree

6 files changed

+79
-3
lines changed

6 files changed

+79
-3
lines changed

compiler/rustc_mir_transform/src/const_prop_lint.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
501501
return None;
502502
}
503503

504+
Rvalue::Len(len_place) => {
505+
// To get the length of an array, we don't need to know the value.
506+
let ty = len_place.ty(self.local_decls, self.tcx).ty;
507+
if let &ty::Array(_, len) = ty.kind() {
508+
return self.use_ecx(source_info, |this| {
509+
let const_len = this.ecx.const_to_op(len, None)?;
510+
let ecx_place = this.ecx.eval_place(place)?;
511+
this.ecx.copy_op(&const_len, &ecx_place, /*allow_transmute*/ false)
512+
});
513+
}
514+
}
515+
504516
// There's no other checking to do at this time.
505517
Rvalue::Aggregate(..)
506518
| Rvalue::Use(..)
507519
| Rvalue::CopyForDeref(..)
508520
| Rvalue::Repeat(..)
509-
| Rvalue::Len(..)
510521
| Rvalue::Cast(..)
511522
| Rvalue::ShallowInitBox(..)
512523
| Rvalue::Discriminant(..)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// build-fail
2+
// Need to use build-fail because check doesn't run constant propagation.
3+
4+
fn main() {
5+
let xs: [i32; 5] = [1, 2, 3, 4, 5];
6+
let _ = &xs;
7+
let _ = xs[7]; //~ ERROR this operation will panic at runtime
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: this operation will panic at runtime
2+
--> $DIR/issue-98444-const-index-out-of-bounds.rs:7:13
3+
|
4+
LL | let _ = xs[7];
5+
| ^^^^^ index out of bounds: the length is 5 but the index is 7
6+
|
7+
= note: `#[deny(unconditional_panic)]` on by default
8+
9+
error: aborting due to previous error
10+

src/test/ui/consts/issue-65348.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// check-pass
2+
#![allow(unconditional_panic)]
23

34
struct Generic<T>(T);
45

src/tools/clippy/tests/ui/indexing_slicing_index.stderr

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
error: this operation will panic at runtime
2+
--> $DIR/indexing_slicing_index.rs:23:5
3+
|
4+
LL | x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
5+
| ^^^^ index out of bounds: the length is 4 but the index is 4
6+
|
7+
= note: `#[deny(unconditional_panic)]` on by default
8+
9+
error: this operation will panic at runtime
10+
--> $DIR/indexing_slicing_index.rs:24:5
11+
|
12+
LL | x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
13+
| ^^^^^^^^^ index out of bounds: the length is 4 but the index is 8
14+
15+
error: this operation will panic at runtime
16+
--> $DIR/indexing_slicing_index.rs:29:5
17+
|
18+
LL | x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
19+
| ^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 4 but the index is 4
20+
121
error[E0080]: evaluation of `main::{constant#3}` failed
222
--> $DIR/indexing_slicing_index.rs:31:14
323
|
@@ -10,6 +30,18 @@ error[E0080]: erroneous constant used
1030
LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
1131
| ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
1232

33+
error: this operation will panic at runtime
34+
--> $DIR/indexing_slicing_index.rs:35:5
35+
|
36+
LL | y[4]; // Ok, rustc will handle references too.
37+
| ^^^^ index out of bounds: the length is 4 but the index is 4
38+
39+
error: this operation will panic at runtime
40+
--> $DIR/indexing_slicing_index.rs:44:5
41+
|
42+
LL | x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
43+
| ^^^^ index out of bounds: the length is 4 but the index is 15
44+
1345
error: indexing may panic
1446
--> $DIR/indexing_slicing_index.rs:22:5
1547
|
@@ -59,6 +91,6 @@ LL | v[M];
5991
|
6092
= help: consider using `.get(n)` or `.get_mut(n)` instead
6193

62-
error: aborting due to 8 previous errors
94+
error: aborting due to 13 previous errors
6395

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

src/tools/clippy/tests/ui/self_assignment.stderr

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
error: this operation will panic at runtime
2+
--> $DIR/self_assignment.rs:16:15
3+
|
4+
LL | s.b[10] = s.b[5 + 5];
5+
| ^^^^^^^^^^ index out of bounds: the length is 10 but the index is 10
6+
|
7+
= note: `#[deny(unconditional_panic)]` on by default
8+
9+
error: this operation will panic at runtime
10+
--> $DIR/self_assignment.rs:16:5
11+
|
12+
LL | s.b[10] = s.b[5 + 5];
13+
| ^^^^^^^ index out of bounds: the length is 10 but the index is 10
14+
115
error: self-assignment of `a` to `a`
216
--> $DIR/self_assignment.rs:12:5
317
|
@@ -66,5 +80,5 @@ error: self-assignment of `(t.0)` to `t.0`
6680
LL | t.0 = (t.0);
6781
| ^^^^^^^^^^^
6882

69-
error: aborting due to 11 previous errors
83+
error: aborting due to 13 previous errors
7084

0 commit comments

Comments
 (0)