about summary refs log tree commit diff
path: root/src/librustc_mir/transform
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2017-02-17 13:38:42 +0100
committerFelix S. Klock II <pnkfelix@pnkfx.org>2017-06-12 13:06:42 +0200
commit1d315cf7da85911dfa239331fab30607ce2d1dce (patch)
treeedd5fdd2b0ac1704287b87ebfa155c499b3d7e64 /src/librustc_mir/transform
parent7c0c4cde80ef871858d5e9dcef506157fcdcc21c (diff)
downloadrust-1d315cf7da85911dfa239331fab30607ce2d1dce.tar.gz
rust-1d315cf7da85911dfa239331fab30607ce2d1dce.zip
Add `EndRegion` statement kind to MIR.
 * Emit `EndRegion` for every code-extent for which we observe a
   borrow. To do this, we needed to thread source info back through
   to `fn in_scope`, which makes this commit a bit more painful than
   one might have expected.

 * There is `end_region` emission in `Builder::pop_scope` and in
   `Builder::exit_scope`; the first handles falling out of a scope
   normally, the second handles e.g. `break`.

 * Remove `EndRegion` statements during the erase_regions mir
   transformation.

 * Preallocate the terminator block, and throw an `Unreachable` marker
   on it from the outset. Then overwrite that Terminator as necessary
   on demand.

 * Instead of marking the scope as needs_cleanup after seeing a
   borrow, just treat every scope in the chain as being part of the
   diverge_block (after any *one* of them has separately signalled
   that it needs cleanup, e.g. due to having a destructor to run).

 * Allow for resume terminators to be patched when looking up drop flags.

   (In particular, `MirPatch::new` has an explicit code path,
   presumably previously unreachable, that patches up such resume
   terminators.)

 * Make `Scope` implement `Debug` trait.

 * Expanded a stray comment: we do not emit StorageDead on diverging
   paths, but that end behavior might not be desirable.
Diffstat (limited to 'src/librustc_mir/transform')
-rw-r--r--src/librustc_mir/transform/erase_regions.rs9
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs1
-rw-r--r--src/librustc_mir/transform/type_check.rs1
3 files changed, 11 insertions, 0 deletions
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index fa88eca6ec3..e809695c180 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -65,6 +65,15 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
                             substs: &mut ClosureSubsts<'tcx>) {
         *substs = self.tcx.erase_regions(substs);
     }
+
+    fn visit_statement(&mut self,
+                       _block: BasicBlock,
+                       statement: &mut Statement<'tcx>,
+                       _location: Location) {
+        if let StatementKind::EndRegion(_) = statement.kind {
+            statement.kind = StatementKind::Nop;
+        }
+    }
 }
 
 pub struct EraseRegions;
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index d60e761bc0b..041d78d3c24 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -907,6 +907,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 StatementKind::StorageLive(_) |
                 StatementKind::StorageDead(_) |
                 StatementKind::InlineAsm {..} |
+                StatementKind::EndRegion(_) |
                 StatementKind::Nop => {}
             }
         });
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index e23f0705b6a..efde39ad6a4 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -413,6 +413,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
             }
             StatementKind::InlineAsm { .. } |
+            StatementKind::EndRegion(_) |
             StatementKind::Nop => {}
         }
     }