about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2017-12-21 13:18:21 +0100
committerGitHub <noreply@github.com>2017-12-21 13:18:21 +0100
commitbdd3f5b240bac62e6e49c12313ebf9ebbc1dfea4 (patch)
tree48a7a548c355ca922f94e472214ec7a52b535114 /src
parent1219494f6f1172343e8b08c43229c3ba148a9ffc (diff)
parenta0e1d509aba0ec14f6e95e1bf720563784ae6771 (diff)
Rollup merge of #46887 - pnkfelix:ensure-activations-are-from-assignments-to-locals, r=arielb1
Ensure separate activations only occur for assignments to locals

Ensure separate activations only occur for assignments to locals, not projections.

Fix #46746.

(I didn't make a regression test because we do not really have a good way to directly express the case that we are trying to catch, because we cannot write MIR directly.)
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 25e4b30da80..8083c1debb8 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -361,7 +361,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
                 }
             }
 
-            mir::StatementKind::Assign(_, ref rhs) => {
+            mir::StatementKind::Assign(ref lhs, ref rhs) => {
                 // NOTE: if/when the Assign case is revised to inspect
                 // the assigned_place here, make sure to also
                 // re-consider the current implementations of the
@@ -382,6 +382,22 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
                         panic!("could not find BorrowIndexs for region {:?}", region);
                     }).contains(&index));
                     sets.gen(&ReserveOrActivateIndex::reserved(*index));
+
+                    if is_activations {
+                        // Issue #46746: Two-phase borrows handles
+                        // stmts of form `Tmp = &mut Borrow` ...
+                        match lhs {
+                            Place::Local(..) => {} // okay
+                            Place::Static(..) => unreachable!(), // (filtered by is_unsafe_place)
+                            Place::Projection(..) => {
+                                // ... can assign into projections,
+                                // e.g. `box (&mut _)`. Current
+                                // conservative solution: force
+                                // immediate activation here.
+                                sets.gen(&ReserveOrActivateIndex::active(*index));
+                            }
+                        }
+                    }
                 }
             }