summary refs log tree commit diff
path: root/src/librustc_mir/transform
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-01-05 02:33:09 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-01-05 02:33:09 +0200
commit8f84e955e006dd9e116f69eaba6efbbcd2e3ca8a (patch)
treefdbde6930700b2db5ebbda95a2617503668a6ba1 /src/librustc_mir/transform
parent05f4a75ebaccdf3646fbea4b560a3a0dfc1be9e2 (diff)
downloadrust-8f84e955e006dd9e116f69eaba6efbbcd2e3ca8a.tar.gz
rust-8f84e955e006dd9e116f69eaba6efbbcd2e3ca8a.zip
Allow projections to be promoted to constants in MIR.
Diffstat (limited to 'src/librustc_mir/transform')
-rw-r--r--src/librustc_mir/transform/promote_consts.rs25
1 files changed, 12 insertions, 13 deletions
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 41698574e0f..232f995dcae 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -96,11 +96,8 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
             // Ignore drops, if the temp gets promoted,
             // then it's constant and thus drop is noop.
             // Storage live ranges are also irrelevant.
-            match context {
-                LvalueContext::Drop |
-                LvalueContext::StorageLive |
-                LvalueContext::StorageDead => return,
-                _ => {}
+            if context.is_drop() || context.is_storage_marker() {
+                return;
             }
 
             let temp = &mut self.temps[index];
@@ -117,15 +114,17 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
                     _ => { /* mark as unpromotable below */ }
                 }
             } else if let TempState::Defined { ref mut uses, .. } = *temp {
-                match context {
-                    LvalueContext::Borrow {..} |
-                    LvalueContext::Consume |
-                    LvalueContext::Inspect => {
-                        *uses += 1;
-                        return;
-                    }
-                    _ => { /* mark as unpromotable below */ }
+                // We always allow borrows, even mutable ones, as we need
+                // to promote mutable borrows of some ZSTs e.g. `&mut []`.
+                let allowed_use = match context {
+                    LvalueContext::Borrow {..} => true,
+                    _ => context.is_nonmutating_use()
+                };
+                if allowed_use {
+                    *uses += 1;
+                    return;
                 }
+                /* mark as unpromotable below */
             }
             *temp = TempState::Unpromotable;
         }