From c5b16784046bf69e11bab5b2777aaed8d1fad296 Mon Sep 17 00:00:00 2001 From: TheWastl <36932506+TheWastl@users.noreply.github.com> Date: Fri, 24 Jun 2022 22:42:47 +0200 Subject: [PATCH] const_eval: Consider array length constant even if array is not --- compiler/rustc_const_eval/src/interpret/step.rs | 12 +++++++++--- .../issue-98444-const-index-out-of-bounds.rs | 8 ++++++++ .../issue-98444-const-index-out-of-bounds.stderr | 10 ++++++++++ src/test/ui/consts/issue-65348.rs | 1 + 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.rs create mode 100644 src/test/ui/const_prop/issue-98444-const-index-out-of-bounds.stderr diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index fea158a9fe450..5f7fd857078c5 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -4,6 +4,7 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; +use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf; use super::{InterpCx, Machine}; @@ -251,9 +252,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Len(place) => { let src = self.eval_place(place)?; - let mplace = self.force_allocation(&src)?; - let len = mplace.len(self)?; - self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?; + if let &ty::Array(_, len) = src.layout.ty.kind() { + let len = self.const_to_op(len, Some(dest.layout))?; + self.copy_op(&len, &dest, /*allow_transmute*/ false)?; + } else { + let mplace = self.force_allocation(&src)?; + let len = mplace.len(self)?; + self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?; + } } AddressOf(_, place) | Ref(_, _, place) => { 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);