diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-02-16 22:18:26 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2020-02-19 23:19:15 +0100 |
| commit | d4c6dfe6d6028dacc0dc59f509a823aad2d2cdf6 (patch) | |
| tree | 496cf1af152cb8e12eb7b577c5114345904c6193 /src | |
| parent | 3723fc1e45381ed8957b60967c8f7af5ab93e796 (diff) | |
| download | rust-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.rs | 57 |
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); } |
