about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/transform/const_prop.rs20
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff15
2 files changed, 31 insertions, 4 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index e898f22ec23..d66c909fe6c 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -775,6 +775,10 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
             // Projections are fine, because `&mut foo.x` will be caught by
             // `MutatingUseContext::Borrow` elsewhere.
             MutatingUse(MutatingUseContext::Projection)
+            // These are just stores, where the storing is not propagatable, but there may be later
+            // mutations of the same local via `Store`
+            | MutatingUse(MutatingUseContext::Call)
+            // Actual store that can possibly even propagate a value
             | MutatingUse(MutatingUseContext::Store) => {
                 if !self.found_assignment.insert(local) {
                     match &mut self.can_const_prop[local] {
@@ -799,7 +803,21 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
             | NonMutatingUse(NonMutatingUseContext::Inspect)
             | NonMutatingUse(NonMutatingUseContext::Projection)
             | NonUse(_) => {}
-            _ => {
+
+            // These could be propagated with a smarter analysis or just some careful thinking about
+            // whether they'd be fine right now.
+            MutatingUse(MutatingUseContext::AsmOutput)
+            | MutatingUse(MutatingUseContext::Yield)
+            | MutatingUse(MutatingUseContext::Drop)
+            | MutatingUse(MutatingUseContext::Retag)
+            // These can't ever be propagated under any scheme, as we can't reason about indirect
+            // mutation.
+            | NonMutatingUse(NonMutatingUseContext::SharedBorrow)
+            | NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
+            | NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
+            | NonMutatingUse(NonMutatingUseContext::AddressOf)
+            | MutatingUse(MutatingUseContext::Borrow)
+            | MutatingUse(MutatingUseContext::AddressOf) => {
                 trace!("local {:?} can't be propagaged because it's used: {:?}", local, context);
                 self.can_const_prop[local] = ConstPropMode::NoPropagation;
             }
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff
index b88bb9b4915..3cf05f13578 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read/rustc.main.ConstProp.diff
@@ -29,17 +29,26 @@
                                            // + ty: i32
                                            // + val: Value(Scalar(0x00000063))
                                            // mir::Constant
-                                           // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:11: 6:13
+-                                          // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:11: 6:13
++                                          // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:5: 6:13
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
           (_1.0: i32) = const 42i32;       // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:7:5: 7:13
                                            // ty::Const
                                            // + ty: i32
                                            // + val: Value(Scalar(0x0000002a))
                                            // mir::Constant
-                                           // + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:11: 7:13
+-                                          // + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:11: 7:13
++                                          // + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:5: 7:13
                                            // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
           StorageLive(_2);                 // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:9: 8:10
-          _2 = (_1.1: i32);                // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
+-         _2 = (_1.1: i32);                // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
++         _2 = const 99i32;                // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
++                                          // ty::Const
++                                          // + ty: i32
++                                          // + val: Value(Scalar(0x00000063))
++                                          // mir::Constant
++                                          // + span: $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
++                                          // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
           _0 = const ();                   // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:4:11: 9:2
                                            // ty::Const
                                            // + ty: ()