about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-12-24 13:37:39 +0200
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-12-24 14:56:52 +0200
commit17d4e9be2afba44c05135752b837bbd1b7b5bee6 (patch)
tree976316e9e61a8a7fdf5aef6050239141cad8052a
parent063b998950f9fcf77630fa820b24375d45426469 (diff)
downloadrust-17d4e9be2afba44c05135752b837bbd1b7b5bee6.tar.gz
rust-17d4e9be2afba44c05135752b837bbd1b7b5bee6.zip
Make killing of out-of-scope borrows a pre-statement effect
Fixes #46875.
Fixes #46917.
Fixes #46935.
-rw-r--r--src/librustc_mir/borrow_check/flows.rs3
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs28
-rw-r--r--src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs1
-rw-r--r--src/test/ui/nll/borrow-use-issue-46875.rs30
5 files changed, 62 insertions, 2 deletions
diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index 69a08c7a30d..61d6c14d627 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -88,7 +88,8 @@ impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
             };
             saw_one = true;
             let borrow_data = &self.borrows.operator().borrows()[borrow.borrow_index()];
-            s.push_str(&format!("{}", borrow_data));
+            s.push_str(&format!("{}{}", borrow_data,
+                                if borrow.is_activation() { "@active" } else { "" }));
         });
         s.push_str("] ");
 
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 1e8a6792963..2fe9bf064e3 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -2011,6 +2011,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             let borrowed = &data[i.borrow_index()];
 
             if self.places_conflict(&borrowed.borrowed_place, place, access) {
+                debug!("each_borrow_involving_path: {:?} @ {:?} vs. {:?}/{:?}",
+                       i, borrowed, place, access);
                 let ctrl = op(self, i, borrowed);
                 if ctrl == Control::Break {
                     return;
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index c39ae10371c..44d4fdf250f 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -635,6 +635,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Reservations<'a, 'gcx, 'tcx> {
         // `_sets`.
     }
 
+    fn before_statement_effect(&self,
+                               sets: &mut BlockSets<ReserveOrActivateIndex>,
+                               location: Location) {
+        debug!("Reservations::before_statement_effect sets: {:?} location: {:?}", sets, location);
+        self.0.kill_loans_out_of_scope_at_location(sets, location, false);
+    }
+
     fn statement_effect(&self,
                         sets: &mut BlockSets<ReserveOrActivateIndex>,
                         location: Location) {
@@ -642,6 +649,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Reservations<'a, 'gcx, 'tcx> {
         self.0.statement_effect_on_borrows(sets, location, false);
     }
 
+    fn before_terminator_effect(&self,
+                                sets: &mut BlockSets<ReserveOrActivateIndex>,
+                                location: Location) {
+        debug!("Reservations::before_terminator_effect sets: {:?} location: {:?}", sets, location);
+        self.0.kill_loans_out_of_scope_at_location(sets, location, false);
+    }
+
     fn terminator_effect(&self,
                          sets: &mut BlockSets<ReserveOrActivateIndex>,
                          location: Location) {
@@ -682,6 +696,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for ActiveBorrows<'a, 'gcx, 'tcx> {
         // `_sets`.
     }
 
+    fn before_statement_effect(&self,
+                               sets: &mut BlockSets<ReserveOrActivateIndex>,
+                               location: Location) {
+        debug!("ActiveBorrows::before_statement_effect sets: {:?} location: {:?}", sets, location);
+        self.0.kill_loans_out_of_scope_at_location(sets, location, true);
+    }
+
     fn statement_effect(&self,
                         sets: &mut BlockSets<ReserveOrActivateIndex>,
                         location: Location) {
@@ -689,6 +710,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for ActiveBorrows<'a, 'gcx, 'tcx> {
         self.0.statement_effect_on_borrows(sets, location, true);
     }
 
+    fn before_terminator_effect(&self,
+                                sets: &mut BlockSets<ReserveOrActivateIndex>,
+                                location: Location) {
+        debug!("ActiveBorrows::before_terminator_effect sets: {:?} location: {:?}", sets, location);
+        self.0.kill_loans_out_of_scope_at_location(sets, location, true);
+    }
+
     fn terminator_effect(&self,
                          sets: &mut BlockSets<ReserveOrActivateIndex>,
                          location: Location) {
diff --git a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs
index b6f5e17f1f6..a9797e4d215 100644
--- a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs
+++ b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs
@@ -56,7 +56,6 @@ fn should_also_eventually_be_ok_with_nll() {
     let _z = &x;
     *y += 1;
     //[lxl]~^  ERROR cannot borrow `x` as mutable because it is also borrowed as immutable
-    //[nll]~^^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable
 }
 
 fn main() { }
diff --git a/src/test/ui/nll/borrow-use-issue-46875.rs b/src/test/ui/nll/borrow-use-issue-46875.rs
new file mode 100644
index 00000000000..47d69fe8e97
--- /dev/null
+++ b/src/test/ui/nll/borrow-use-issue-46875.rs
@@ -0,0 +1,30 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(nll)]
+
+// run-pass
+
+fn vec() {
+    let mut _x = vec!['c'];
+    let _y = &_x;
+    _x = Vec::new();
+}
+
+fn int() {
+    let mut _x = 5;
+    let _y = &_x;
+    _x = 7;
+}
+
+fn main() {
+    vec();
+    int();
+}