diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index c2ea55af48a1e..d4ad67338a2bd 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -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(..) diff --git a/src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.rs b/src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.rs new file mode 100644 index 0000000000000..a6e0ce2103856 --- /dev/null +++ b/src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.rs @@ -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 +} diff --git a/src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.stderr b/src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.stderr new file mode 100644 index 0000000000000..75580bbd6816e --- /dev/null +++ b/src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.stderr @@ -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 + diff --git a/src/test/ui/consts/issue-65348.rs b/src/test/ui/consts/issue-65348.rs index 5eafa831d6317..e3a8c2c922bb1 100644 --- a/src/test/ui/consts/issue-65348.rs +++ b/src/test/ui/consts/issue-65348.rs @@ -1,4 +1,5 @@ // check-pass +#![allow(unconditional_panic)] struct Generic(T); diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr index 6ae700753f06d..58c7a3942d399 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr @@ -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 | @@ -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 | @@ -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`. diff --git a/src/tools/clippy/tests/ui/self_assignment.stderr b/src/tools/clippy/tests/ui/self_assignment.stderr index 826e0d0ba888d..b951586370798 100644 --- a/src/tools/clippy/tests/ui/self_assignment.stderr +++ b/src/tools/clippy/tests/ui/self_assignment.stderr @@ -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 | @@ -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