about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-04 12:37:44 +0000
committerbors <bors@rust-lang.org>2019-06-04 12:37:44 +0000
commitacda261de83475cf6cbc607d570153bb864ee7be (patch)
tree7427c87553a743736a80a9c423090836a8766651
parent021a5033098ff0e3f7126acc7ac35149d325f16d (diff)
parentb2536781afd0eaef11f6b2f68924dde380cf18f2 (diff)
downloadrust-acda261de83475cf6cbc607d570153bb864ee7be.tar.gz
rust-acda261de83475cf6cbc607d570153bb864ee7be.zip
Auto merge of #61437 - christianpoveda:const-eval-indirects, r=wesleywiser,oli-obk
Add const-eval support for indirects

r? @wesleywiser
-rw-r--r--src/librustc_mir/interpret/operand.rs2
-rw-r--r--src/librustc_mir/transform/const_prop.rs41
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs5
-rw-r--r--src/test/mir-opt/const_prop/indirect.rs23
4 files changed, 58 insertions, 13 deletions
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 899cc40dc32..5c75c323ddd 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -268,7 +268,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
     /// Note that for a given layout, this operation will either always fail or always
     /// succeed!  Whether it succeeds depends on whether the layout can be represented
     /// in a `Immediate`, not on which data is stored there currently.
-    pub(super) fn try_read_immediate(
+    pub(crate) fn try_read_immediate(
         &self,
         src: OpTy<'tcx, M::PointerTag>,
     ) -> EvalResult<'tcx, Result<Immediate<M::PointerTag>, MemPlace<M::PointerTag>>> {
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 728ea41a9d8..dbaa4e557c6 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -3,8 +3,8 @@
 
 use rustc::hir::def::DefKind;
 use rustc::mir::{
-    AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue, Local,
-    NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
+    AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
+    Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
     TerminatorKind, Terminator,  ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
     SourceScope, SourceScopeLocalData, LocalDecl, Promoted,
 };
@@ -21,7 +21,9 @@ use rustc::ty::layout::{
     HasTyCtxt, TargetDataLayout, HasDataLayout,
 };
 
-use crate::interpret::{self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
+use crate::interpret::{
+    self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind,
+};
 use crate::const_eval::{
     CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
 };
@@ -516,7 +518,12 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
         ))
     }
 
-    fn replace_with_const(&self, rval: &mut Rvalue<'tcx>, value: Const<'tcx>, span: Span) {
+    fn replace_with_const(
+        &mut self,
+        rval: &mut Rvalue<'tcx>,
+        value: Const<'tcx>,
+        source_info: SourceInfo,
+    ) {
         trace!("attepting to replace {:?} with {:?}", rval, value);
         self.ecx.validate_operand(
             value,
@@ -525,10 +532,16 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
             true,
         ).expect("value should already be a valid const");
 
-        if let interpret::Operand::Immediate(im) = *value {
-            match im {
+        // FIXME> figure out what tho do when try_read_immediate fails
+        let imm = self.use_ecx(source_info, |this| {
+            this.ecx.try_read_immediate(value)
+        });
+
+        if let Some(Ok(imm)) = imm {
+            match imm {
                 interpret::Immediate::Scalar(ScalarMaybeUndef::Scalar(scalar)) => {
-                    *rval = Rvalue::Use(self.operand_from_scalar(scalar, value.layout.ty, span));
+                    *rval = Rvalue::Use(
+                        self.operand_from_scalar(scalar, value.layout.ty, source_info.span));
                 },
                 Immediate::ScalarPair(
                     ScalarMaybeUndef::Scalar(one),
@@ -539,8 +552,12 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
                         *rval = Rvalue::Aggregate(
                             Box::new(AggregateKind::Tuple),
                             vec![
-                                self.operand_from_scalar(one, substs[0].expect_ty(), span),
-                                self.operand_from_scalar(two, substs[1].expect_ty(), span),
+                                self.operand_from_scalar(
+                                    one, substs[0].expect_ty(), source_info.span
+                                ),
+                                self.operand_from_scalar(
+                                    two, substs[1].expect_ty(), source_info.span
+                                ),
                             ],
                         );
                     }
@@ -655,7 +672,11 @@ impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
                             self.places[local] = Some(value);
 
                             if self.should_const_prop() {
-                                self.replace_with_const(rval, value, statement.source_info.span);
+                                self.replace_with_const(
+                                    rval,
+                                    value,
+                                    statement.source_info,
+                                );
                             }
                         }
                     }
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
index 97d3abdcc6c..85ed8d55b24 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.rs
@@ -23,8 +23,9 @@ fn main() {
 // START rustc.main.ConstProp.after.mir
 //  bb0: {
 //      ...
-//      _3 = _4;
-//      _2 = move _3 as *const i32 (Misc);
+//      _4 = const Scalar(AllocId(1).0x0) : &i32;
+//      _3 = const Scalar(AllocId(1).0x0) : &i32;
+//      _2 = const Scalar(AllocId(1).0x0) : *const i32;
 //      ...
 //      _1 = move _2 as usize (Misc);
 //      ...
diff --git a/src/test/mir-opt/const_prop/indirect.rs b/src/test/mir-opt/const_prop/indirect.rs
new file mode 100644
index 00000000000..b4ee18ed1b5
--- /dev/null
+++ b/src/test/mir-opt/const_prop/indirect.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C overflow-checks=on
+
+fn main() {
+    let x = (2u32 as u8) + 1;
+}
+
+// END RUST SOURCE
+// START rustc.main.ConstProp.before.mir
+// bb0: {
+//     ...
+//     _2 = const 2u32 as u8 (Misc);
+//     _3 = CheckedAdd(move _2, const 1u8);
+//     assert(!move (_3.1: bool), "attempt to add with overflow") -> bb1;
+//}
+// END rustc.main.ConstProp.before.mir
+// START rustc.main.ConstProp.after.mir
+// bb0: {
+//     ...
+//     _2 = const 2u8;
+//     _3 = (const 3u8, const false);
+//     assert(!const false, "attempt to add with overflow") -> bb1;
+// }
+// END rustc.main.ConstProp.after.mir