From 6b67c46a253d453674401fad70c515d8fd439e35 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 24 Aug 2024 18:19:38 +0000 Subject: [PATCH] Compute array length from type for unconditional panic. --- .../rustc_mir_transform/src/known_panics_lint.rs | 16 +++++++++------- tests/ui/lint/unconditional_panic_promoted.rs | 8 ++++++++ .../ui/lint/unconditional_panic_promoted.stderr | 10 ++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 tests/ui/lint/unconditional_panic_promoted.rs create mode 100644 tests/ui/lint/unconditional_panic_promoted.stderr diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index ccc029b1e28..8f490094d60 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -600,13 +600,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } Len(place) => { - let len = match self.get_const(place)? { - Value::Immediate(src) => src.len(&self.ecx).discard_err()?, - Value::Aggregate { fields, .. } => fields.len() as u64, - Value::Uninit => match place.ty(self.local_decls(), self.tcx).ty.kind() { - ty::Array(_, n) => n.try_eval_target_usize(self.tcx, self.param_env)?, - _ => return None, - }, + let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind() + { + n.try_eval_target_usize(self.tcx, self.param_env)? + } else { + match self.get_const(place)? { + Value::Immediate(src) => src.len(&self.ecx).discard_err()?, + Value::Aggregate { fields, .. } => fields.len() as u64, + Value::Uninit => return None, + } }; ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into() } diff --git a/tests/ui/lint/unconditional_panic_promoted.rs b/tests/ui/lint/unconditional_panic_promoted.rs new file mode 100644 index 00000000000..37bcf046513 --- /dev/null +++ b/tests/ui/lint/unconditional_panic_promoted.rs @@ -0,0 +1,8 @@ +//@ build-fail + +fn main() { + // MIR encodes this as a reborrow from a promoted constant. + // But the array lenth can still be gotten from the type. + let slice = &[0, 1]; + let _ = slice[2]; //~ ERROR: this operation will panic at runtime [unconditional_panic] +} diff --git a/tests/ui/lint/unconditional_panic_promoted.stderr b/tests/ui/lint/unconditional_panic_promoted.stderr new file mode 100644 index 00000000000..647a84a55fd --- /dev/null +++ b/tests/ui/lint/unconditional_panic_promoted.stderr @@ -0,0 +1,10 @@ +error: this operation will panic at runtime + --> $DIR/unconditional_panic_promoted.rs:7:13 + | +LL | let _ = slice[2]; + | ^^^^^^^^ index out of bounds: the length is 2 but the index is 2 + | + = note: `#[deny(unconditional_panic)]` on by default + +error: aborting due to 1 previous error +