about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/transform/const_prop.rs25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f0c0e573443..780b49cd9db 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -518,27 +518,30 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
             }
 
-            // Work around: avoid ICE in miri.
-            // FIXME(wesleywiser) we don't currently handle the case where we try to make a ref
-            // from a function argument that hasn't been assigned to in this function. The main
-            // issue is if an arg is a fat-pointer, miri `expects()` to be able to read the value
-            // of that pointer to get size info. However, since this is `ConstProp`, that argument
-            // doesn't actually have a backing value and so this causes an ICE.
+            // Work around: avoid ICE in miri. FIXME(wesleywiser)
+            // The Miri engine ICEs when taking a reference to an uninitialized unsized
+            // local. There's nothing it can do here: taking a reference needs an allocation
+            // which needs to know the size. Normally that's okay as during execution
+            // (e.g. for CTFE) it can never happen. But here in const_prop
+            // unknown data is uninitialized, so if e.g. a function argument is unsized
+            // and has a reference taken, we get an ICE.
             Rvalue::Ref(_, _, Place { base: PlaceBase::Local(local), projection: box [] }) => {
                 trace!("checking Ref({:?})", place);
                 let alive =
                     if let LocalValue::Live(_) = self.ecx.frame().locals[*local].value {
                         true
-                    } else { false };
+                    } else {
+                        false
+                    };
 
-                if local.as_usize() <= self.ecx.frame().body.arg_count && !alive {
-                    trace!("skipping Ref({:?})", place);
+                if !alive {
+                    trace!("skipping Ref({:?}) to uninitialized local", place);
                     return None;
                 }
             }
 
-            // Work around: avoid extra unnecessary locals.
-            // FIXME(wesleywiser): const eval will turn this into a `const Scalar(<ZST>)` that
+            // Work around: avoid extra unnecessary locals. FIXME(wesleywiser)
+            // Const eval will turn this into a `const Scalar(<ZST>)` that
             // `SimplifyLocals` doesn't know it can remove.
             Rvalue::Aggregate(_, operands) if operands.len() == 0 => {
                 return None;