about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-02-16 22:18:26 +0100
committerJonas Schievink <jonasschievink@gmail.com>2020-02-19 23:19:15 +0100
commitd4c6dfe6d6028dacc0dc59f509a823aad2d2cdf6 (patch)
tree496cf1af152cb8e12eb7b577c5114345904c6193 /src
parent3723fc1e45381ed8957b60967c8f7af5ab93e796 (diff)
downloadrust-d4c6dfe6d6028dacc0dc59f509a823aad2d2cdf6.tar.gz
rust-d4c6dfe6d6028dacc0dc59f509a823aad2d2cdf6.zip
Handle resume args in `RequiresStorage` analysis
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/dataflow/impls/storage_liveness.rs57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs
index 5781b3982b1..659b66823c2 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs
@@ -152,23 +152,58 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
         // If a place is borrowed in a terminator, it needs storage for that terminator.
         self.borrowed_locals.borrow().analysis().terminator_effect(sets, terminator, loc);
 
-        if let TerminatorKind::Call { destination: Some((place, _)), .. } = terminator.kind {
-            sets.gen(place.local);
+        match &terminator.kind {
+            TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. }
+            | TerminatorKind::Yield { resume_arg: Place { local, .. }, .. } => {
+                sets.gen(*local);
+            }
+
+            // Nothing to do for these. Match exhaustively so this fails to compile when new
+            // variants are added.
+            TerminatorKind::Call { destination: None, .. }
+            | TerminatorKind::Abort
+            | TerminatorKind::Assert { .. }
+            | TerminatorKind::Drop { .. }
+            | TerminatorKind::DropAndReplace { .. }
+            | TerminatorKind::FalseEdges { .. }
+            | TerminatorKind::FalseUnwind { .. }
+            | TerminatorKind::GeneratorDrop
+            | TerminatorKind::Goto { .. }
+            | TerminatorKind::Resume
+            | TerminatorKind::Return
+            | TerminatorKind::SwitchInt { .. }
+            | TerminatorKind::Unreachable => {}
         }
     }
 
     fn terminator_effect(&self, sets: &mut GenKillSet<Local>, loc: Location) {
-        // For call terminators the destination requires storage for the call
-        // and after the call returns successfully, but not after a panic.
-        // Since `propagate_call_unwind` doesn't exist, we have to kill the
-        // destination here, and then gen it again in `propagate_call_return`.
-        if let TerminatorKind::Call { destination: Some((ref place, _)), .. } =
-            self.body[loc.block].terminator().kind
-        {
-            if let Some(local) = place.as_local() {
-                sets.kill(local);
+        match &self.body[loc.block].terminator().kind {
+            // For call terminators the destination requires storage for the call
+            // and after the call returns successfully, but not after a panic.
+            // Since `propagate_call_unwind` doesn't exist, we have to kill the
+            // destination here, and then gen it again in `propagate_call_return`.
+            TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } => {
+                sets.kill(*local);
             }
+
+            // Nothing to do for these. Match exhaustively so this fails to compile when new
+            // variants are added.
+            TerminatorKind::Call { destination: None, .. }
+            | TerminatorKind::Yield { .. }
+            | TerminatorKind::Abort
+            | TerminatorKind::Assert { .. }
+            | TerminatorKind::Drop { .. }
+            | TerminatorKind::DropAndReplace { .. }
+            | TerminatorKind::FalseEdges { .. }
+            | TerminatorKind::FalseUnwind { .. }
+            | TerminatorKind::GeneratorDrop
+            | TerminatorKind::Goto { .. }
+            | TerminatorKind::Resume
+            | TerminatorKind::Return
+            | TerminatorKind::SwitchInt { .. }
+            | TerminatorKind::Unreachable => {}
         }
+
         self.check_for_move(sets, loc);
     }