about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-11-15 16:07:48 +0000
committerbors <bors@rust-lang.org>2017-11-15 16:07:48 +0000
commit88a28ff6028cf197ed6b4185d8cd4887f05e3e07 (patch)
treeba93d344ef887de5fb4c4fd17ebb88d287c3be31 /src
parentce2b8a4944f1983759cb7d0e8d35a8bb889dbee6 (diff)
parent9e35fd262f8ca57d755259448df4e7b601cb236a (diff)
downloadrust-88a28ff6028cf197ed6b4185d8cd4887f05e3e07.tar.gz
rust-88a28ff6028cf197ed6b4185d8cd4887f05e3e07.zip
Auto merge of #45936 - mikhail-m1:mir-borrowck-storage-dead, r=arielb1
add `StorageDead` handling

fix #45642
r? @arielb1
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/dataflow/drop_flag_effects.rs12
-rw-r--r--src/librustc_mir/dataflow/impls/mod.rs24
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs16
-rw-r--r--src/test/compile-fail/borrowck/borrowck-storage-dead.rs30
-rw-r--r--src/test/compile-fail/issue-25579.rs3
5 files changed, 57 insertions, 28 deletions
diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index e35bd34c40b..c1320d9daa8 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax_pos::DUMMY_SP;
-
 use rustc::mir::{self, Mir, Location};
 use rustc::ty::{self, TyCtxt};
 use util::elaborate_drops::DropFlagState;
@@ -187,7 +185,6 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
     where F: FnMut(MovePathIndex, DropFlagState)
 {
     let move_data = &ctxt.move_data;
-    let param_env = ctxt.param_env;
     debug!("drop_flag_effects_for_location({:?})", loc);
 
     // first, move out of the RHS
@@ -195,15 +192,6 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
         let path = mi.move_path_index(move_data);
         debug!("moving out of path {:?}", move_data.move_paths[path]);
 
-        // don't move out of non-Copy things
-        let lvalue = &move_data.move_paths[path].lvalue;
-        let ty = lvalue.ty(mir, tcx).to_ty(tcx);
-        let gcx = tcx.global_tcx();
-        let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
-        if !erased_ty.moves_by_default(gcx, param_env, DUMMY_SP) {
-            continue;
-        }
-
         on_all_children_bits(tcx, mir, move_data,
                              path,
                              |mpi| callback(mpi, DropFlagState::Absent))
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index dad96dc3a6f..147f3d796b9 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -456,14 +456,24 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
         let path_map = &move_data.path_map;
         let rev_lookup = &move_data.rev_lookup;
 
-        debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
-               stmt, location, &loc_map[location]);
-        for move_index in &loc_map[location] {
-            // Every path deinitialized by a *particular move*
-            // has corresponding bit, "gen'ed" (i.e. set)
-            // here, in dataflow vector
-            zero_to_one(sets.gen_set.words_mut(), *move_index);
+        match stmt.kind {
+            // this analysis only tries to find moves explicitly
+            // written by the user, so we ignore the move-outs
+            // created by `StorageDead` and at the beginning
+            // of a function.
+            mir::StatementKind::StorageDead(_) => {}
+            _ => {
+                debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
+                       stmt, location, &loc_map[location]);
+                for move_index in &loc_map[location] {
+                    // Every path deinitialized by a *particular move*
+                    // has corresponding bit, "gen'ed" (i.e. set)
+                    // here, in dataflow vector
+                    zero_to_one(sets.gen_set.words_mut(), *move_index);
+                }
+            }
         }
+
         let bits_per_block = self.bits_per_block();
         match stmt.kind {
             mir::StatementKind::SetDiscriminant { .. } => {
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index f333dd4d2a1..a0212de605e 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -250,8 +250,10 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
                 }
                 self.gather_rvalue(rval);
             }
-            StatementKind::StorageLive(_) |
-            StatementKind::StorageDead(_) => {}
+            StatementKind::StorageLive(_) => {}
+            StatementKind::StorageDead(local) => {
+                self.gather_move(&Lvalue::Local(local), true);
+            }
             StatementKind::SetDiscriminant{ .. } => {
                 span_bug!(stmt.source_info.span,
                           "SetDiscriminant should not exist during borrowck");
@@ -309,7 +311,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
             TerminatorKind::Unreachable => { }
 
             TerminatorKind::Return => {
-                self.gather_move(&Lvalue::Local(RETURN_POINTER));
+                self.gather_move(&Lvalue::Local(RETURN_POINTER), false);
             }
 
             TerminatorKind::Assert { .. } |
@@ -322,7 +324,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
             }
 
             TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
-                self.gather_move(location);
+                self.gather_move(location, false);
             }
             TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
                 self.create_move_path(location);
@@ -344,19 +346,19 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
         match *operand {
             Operand::Constant(..) => {} // not-a-move
             Operand::Consume(ref lval) => { // a move
-                self.gather_move(lval);
+                self.gather_move(lval, false);
             }
         }
     }
 
-    fn gather_move(&mut self, lval: &Lvalue<'tcx>) {
+    fn gather_move(&mut self, lval: &Lvalue<'tcx>, force: bool) {
         debug!("gather_move({:?}, {:?})", self.loc, lval);
 
         let tcx = self.builder.tcx;
         let gcx = tcx.global_tcx();
         let lv_ty = lval.ty(self.builder.mir, tcx).to_ty(tcx);
         let erased_ty = gcx.lift(&tcx.erase_regions(&lv_ty)).unwrap();
-        if !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) {
+        if !force && !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) {
             debug!("gather_move({:?}, {:?}) - {:?} is Copy. skipping", self.loc, lval, lv_ty);
             return
         }
diff --git a/src/test/compile-fail/borrowck/borrowck-storage-dead.rs b/src/test/compile-fail/borrowck/borrowck-storage-dead.rs
new file mode 100644
index 00000000000..5ef502acd81
--- /dev/null
+++ b/src/test/compile-fail/borrowck/borrowck-storage-dead.rs
@@ -0,0 +1,30 @@
+// Copyright 2012 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.
+
+// compile-flags: -Z emit-end-regions -Z borrowck-mir
+
+fn ok() {
+    loop {
+        let _x = 1;
+    }
+}
+
+fn fail() {
+    loop {
+        let x: i32;
+        let _ = x + 1; //~ERROR (Ast) [E0381]
+                       //~^ ERROR (Mir) [E0381]
+    }
+}
+
+fn main() {
+    ok();
+    fail();
+}
diff --git a/src/test/compile-fail/issue-25579.rs b/src/test/compile-fail/issue-25579.rs
index 7da80d2852e..4437e20fc42 100644
--- a/src/test/compile-fail/issue-25579.rs
+++ b/src/test/compile-fail/issue-25579.rs
@@ -18,11 +18,10 @@ enum Sexpression {
 
 fn causes_ice(mut l: &mut Sexpression) {
     loop { match l {
-        &mut Sexpression::Num(ref mut n) => {}, //[mir]~ ERROR (Mir) [E0384]
+        &mut Sexpression::Num(ref mut n) => {},
         &mut Sexpression::Cons(ref mut expr) => { //[ast]~ ERROR [E0499]
                                                   //[mir]~^ ERROR (Ast) [E0499]
                                                   //[mir]~| ERROR (Mir) [E0506]
-                                                  //[mir]~| ERROR (Mir) [E0384]
                                                   //[mir]~| ERROR (Mir) [E0499]
             l = &mut **expr; //[ast]~ ERROR [E0506]
                              //[mir]~^ ERROR (Ast) [E0506]