about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFélix Fischer <felix91gr@gmail.com>2020-04-22 21:53:51 -0400
committerFélix Fischer <felix91gr@gmail.com>2020-04-27 20:13:22 -0400
commit3fd2d4aaa6fa07a673b7c46c8253c5f69b23d851 (patch)
treeceeb74f4428f2a4acd2e7c6d6c0c85c0553a3b1d
parent6316601ec4012b6dc25cacbe0f8d602cce37d08b (diff)
downloadrust-3fd2d4aaa6fa07a673b7c46c8253c5f69b23d851.tar.gz
rust-3fd2d4aaa6fa07a673b7c46c8253c5f69b23d851.zip
Blocked `MutatingUseContext::Projection` for all locals of kind `LocalKind::Temp`. Added a cache of `LocalKind`s to `CanConstProp`
-rw-r--r--src/librustc_mir/transform/const_prop.rs17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index abe9249ec37..ed02ef566a6 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -766,6 +766,8 @@ struct CanConstProp {
     can_const_prop: IndexVec<Local, ConstPropMode>,
     // false at the beginning, once set, there are not allowed to be any more assignments
     found_assignment: BitSet<Local>,
+    // Cache of locals' information
+    local_kinds: IndexVec<Local, LocalKind>,
 }
 
 impl CanConstProp {
@@ -774,6 +776,10 @@ impl CanConstProp {
         let mut cpv = CanConstProp {
             can_const_prop: IndexVec::from_elem(ConstPropMode::FullConstProp, &body.local_decls),
             found_assignment: BitSet::new_empty(body.local_decls.len()),
+            local_kinds: IndexVec::from_fn_n(
+                |local| body.local_kind(local),
+                body.local_decls.len(),
+            ),
         };
         for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
             // cannot use args at all
@@ -781,9 +787,8 @@ impl CanConstProp {
             //        lint for x != y
             // FIXME(oli-obk): lint variables until they are used in a condition
             // FIXME(oli-obk): lint if return value is constant
-            let local_kind = body.local_kind(local);
-
-            if local_kind == LocalKind::Arg || local_kind == LocalKind::Var {
+            if cpv.local_kinds[local] == LocalKind::Arg || cpv.local_kinds[local] == LocalKind::Var
+            {
                 *val = ConstPropMode::OnlyPropagateInto;
                 trace!("local {:?} can't be const propagated because it's not a temporary", local);
             }
@@ -811,8 +816,12 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
             | NonMutatingUse(NonMutatingUseContext::Move)
             | NonMutatingUse(NonMutatingUseContext::Inspect)
             | NonMutatingUse(NonMutatingUseContext::Projection)
-            | MutatingUse(MutatingUseContext::Projection)
             | NonUse(_) => {}
+            MutatingUse(MutatingUseContext::Projection) => {
+                if self.local_kinds[local] != LocalKind::Temp {
+                    self.can_const_prop[local] = ConstPropMode::NoPropagation;
+                }
+            }
             _ => {
                 trace!("local {:?} can't be propagaged because it's used: {:?}", local, context);
                 self.can_const_prop[local] = ConstPropMode::NoPropagation;