about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs6
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs4
-rw-r--r--tests/ui/const_prop/unsized-local-ice.rs9
4 files changed, 20 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 4d54c01830b..b10f2e9f862 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -337,7 +337,7 @@ fn valtree_into_mplace<'tcx>(
 
     match ty.kind() {
         ty::FnDef(_, _) => {
-            ecx.write_immediate(Immediate::Uninit, &place.into()).unwrap();
+            // Zero-sized type, nothing to do.
         }
         ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
             let scalar_int = valtree.unwrap_leaf();
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 5310ef0bb3e..a7f66071fe2 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -245,6 +245,12 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
 impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
     pub fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
         if self.layout.is_unsized() {
+            if matches!(self.op, Operand::Immediate(Immediate::Uninit)) {
+                // Uninit unsized places shouldn't occur. In the interpreter we have them
+                // temporarily for unsized arguments before their value is put in; in ConstProp they
+                // remain uninit and this code can actually be reached.
+                throw_inval!(UninitUnsizedLocal);
+            }
             // There are no unsized immediates.
             self.assert_mem_place().len(cx)
         } else {
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index c5137cf0666..e45284ca506 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -134,6 +134,9 @@ pub enum InvalidProgramInfo<'tcx> {
     FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
     /// SizeOf of unsized type was requested.
     SizeOfUnsizedType(Ty<'tcx>),
+    /// An unsized local was accessed without having been initialized.
+    /// This is not meaningful as we can't even have backing memory for such locals.
+    UninitUnsizedLocal,
 }
 
 impl fmt::Display for InvalidProgramInfo<'_> {
@@ -150,6 +153,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
             Layout(ref err) => write!(f, "{err}"),
             FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"),
             SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"),
+            UninitUnsizedLocal => write!(f, "unsized local is used while uninitialized"),
         }
     }
 }
diff --git a/tests/ui/const_prop/unsized-local-ice.rs b/tests/ui/const_prop/unsized-local-ice.rs
new file mode 100644
index 00000000000..c725b3238ea
--- /dev/null
+++ b/tests/ui/const_prop/unsized-local-ice.rs
@@ -0,0 +1,9 @@
+// build-pass
+//! Regression test for <https://github.com/rust-lang/rust/issues/68538>.
+#![feature(unsized_fn_params)]
+
+pub fn take_unsized_slice(s: [u8]) {
+    s[0];
+}
+
+fn main() {}