about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWesley Wiser <wwiser@gmail.com>2019-09-11 07:46:17 -0400
committerWesley Wiser <wwiser@gmail.com>2019-09-27 20:11:12 -0400
commitc0c8ce80b345dee4f306519c2262c4af687ef818 (patch)
tree2c8d553f54b00dbb8a66e52490516410c857b53d
parent9ec928ca06877611f60fbf652775ae8e4aaf8cfc (diff)
[const-prop] Replace `Ref` handling with use of `InterpCx`
-rw-r--r--src/librustc_mir/interpret/step.rs21
-rw-r--r--src/librustc_mir/transform/const_prop.rs8
2 files changed, 21 insertions, 8 deletions
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index daca7a25787..0aa6f5174c1 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -2,11 +2,11 @@
 //!
 //! The main entry point is the `step` method.
 
-use rustc::mir;
+use rustc::mir::{self, Place, PlaceBase};
 use rustc::ty::layout::LayoutOf;
 use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic};
 
-use super::{InterpCx, Machine};
+use super::{InterpCx, LocalValue, Machine};
 
 /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the
 /// same type as the result.
@@ -240,6 +240,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             Ref(_, _, ref place) => {
+                // 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. So just
+                // report those as uninitialized for now.
+                if let Place {
+                    base: PlaceBase::Local(local),
+                    projection: None
+                } = place {
+                    let alive =
+                        if let LocalValue::Live(_) = self.frame().locals[*local].value {
+                            true
+                        } else { false };
+
+                    if local.as_usize() <= self.frame().body.arg_count && !alive {
+                        trace!("skipping Ref({:?})", place);
+                        throw_unsup!(UninitializedLocal);
+                    }
+                }
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(src)?;
                 if place.layout.size.bytes() > 0 {
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 06117dc6a7e..0653598bc86 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -313,17 +313,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             Rvalue::Len(_) |
             Rvalue::Cast(..) |
             Rvalue::NullaryOp(..) |
-            Rvalue::CheckedBinaryOp(..) => {
+            Rvalue::CheckedBinaryOp(..) |
+            Rvalue::Ref(..) => {
                 self.use_ecx(source_info, |this| {
                     this.ecx.eval_rvalue_into_place(rvalue, place)?;
                     this.ecx.eval_place_to_op(place, Some(place_layout))
                 })
             },
-            Rvalue::Ref(_, _, ref place) => {
-                let src = self.eval_place(place, source_info)?;
-                let mplace = src.try_as_mplace().ok()?;
-                Some(ImmTy::from_scalar(mplace.ptr.into(), place_layout).into())
-            },
 
             Rvalue::UnaryOp(op, ref arg) => {
                 let overflow_check = self.tcx.sess.overflow_checks();