Skip to content

Commit

Permalink
const_prop_lint: Consider array length constant even if array is not
Browse files Browse the repository at this point in the history
  • Loading branch information
TheWastl committed Sep 5, 2022
1 parent 983f4da commit d5c9e76
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 3 deletions.
13 changes: 12 additions & 1 deletion compiler/rustc_mir_transform/src/const_prop_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None;
}

Rvalue::Len(len_place) => {
// To get the length of an array, we don't need to know the value.
let ty = len_place.ty(self.local_decls, self.tcx).ty;
if let &ty::Array(_, len) = ty.kind() {
return self.use_ecx(source_info, |this| {
let const_len = this.ecx.const_to_op(len, None)?;
let ecx_place = this.ecx.eval_place(place)?;
this.ecx.copy_op(&const_len, &ecx_place, /*allow_transmute*/ false)
});
}
}

// There's no other checking to do at this time.
Rvalue::Aggregate(..)
| Rvalue::Use(..)
| Rvalue::CopyForDeref(..)
| Rvalue::Repeat(..)
| Rvalue::Len(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)
| Rvalue::Discriminant(..)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// build-fail
// Need to use build-fail because check doesn't run constant propagation.

fn main() {
let xs: [i32; 5] = [1, 2, 3, 4, 5];
let _ = &xs;
let _ = xs[7]; //~ ERROR this operation will panic at runtime
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: this operation will panic at runtime
--> $DIR/issue-98444-const-index-out-of-bounds.rs:7:13
|
LL | let _ = xs[7];
| ^^^^^ index out of bounds: the length is 5 but the index is 7
|
= note: `#[deny(unconditional_panic)]` on by default

error: aborting due to previous error

1 change: 1 addition & 0 deletions src/test/ui/consts/issue-65348.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// check-pass
#![allow(unconditional_panic)]

struct Generic<T>(T);

Expand Down
34 changes: 33 additions & 1 deletion src/tools/clippy/tests/ui/indexing_slicing_index.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
error: this operation will panic at runtime
--> $DIR/indexing_slicing_index.rs:23:5
|
LL | x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
| ^^^^ index out of bounds: the length is 4 but the index is 4
|
= note: `#[deny(unconditional_panic)]` on by default

error: this operation will panic at runtime
--> $DIR/indexing_slicing_index.rs:24:5
|
LL | x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
| ^^^^^^^^^ index out of bounds: the length is 4 but the index is 8

error: this operation will panic at runtime
--> $DIR/indexing_slicing_index.rs:29:5
|
LL | x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
| ^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 4 but the index is 4

error[E0080]: evaluation of `main::{constant#3}` failed
--> $DIR/indexing_slicing_index.rs:31:14
|
Expand All @@ -10,6 +30,18 @@ error[E0080]: erroneous constant used
LL | const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
| ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors

error: this operation will panic at runtime
--> $DIR/indexing_slicing_index.rs:35:5
|
LL | y[4]; // Ok, rustc will handle references too.
| ^^^^ index out of bounds: the length is 4 but the index is 4

error: this operation will panic at runtime
--> $DIR/indexing_slicing_index.rs:44:5
|
LL | x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
| ^^^^ index out of bounds: the length is 4 but the index is 15

error: indexing may panic
--> $DIR/indexing_slicing_index.rs:22:5
|
Expand Down Expand Up @@ -59,6 +91,6 @@ LL | v[M];
|
= help: consider using `.get(n)` or `.get_mut(n)` instead

error: aborting due to 8 previous errors
error: aborting due to 13 previous errors

For more information about this error, try `rustc --explain E0080`.
16 changes: 15 additions & 1 deletion src/tools/clippy/tests/ui/self_assignment.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
error: this operation will panic at runtime
--> $DIR/self_assignment.rs:16:15
|
LL | s.b[10] = s.b[5 + 5];
| ^^^^^^^^^^ index out of bounds: the length is 10 but the index is 10
|
= note: `#[deny(unconditional_panic)]` on by default

error: this operation will panic at runtime
--> $DIR/self_assignment.rs:16:5
|
LL | s.b[10] = s.b[5 + 5];
| ^^^^^^^ index out of bounds: the length is 10 but the index is 10

error: self-assignment of `a` to `a`
--> $DIR/self_assignment.rs:12:5
|
Expand Down Expand Up @@ -66,5 +80,5 @@ error: self-assignment of `(t.0)` to `t.0`
LL | t.0 = (t.0);
| ^^^^^^^^^^^

error: aborting due to 11 previous errors
error: aborting due to 13 previous errors

0 comments on commit d5c9e76

Please sign in to comment.