Skip to content

Commit d4c6dfe

Browse files
Handle resume args in RequiresStorage analysis
1 parent 3723fc1 commit d4c6dfe

File tree

1 file changed

+46
-11
lines changed

1 file changed

+46
-11
lines changed

src/librustc_mir/dataflow/impls/storage_liveness.rs

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,23 +152,58 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
152152
// If a place is borrowed in a terminator, it needs storage for that terminator.
153153
self.borrowed_locals.borrow().analysis().terminator_effect(sets, terminator, loc);
154154

155-
if let TerminatorKind::Call { destination: Some((place, _)), .. } = terminator.kind {
156-
sets.gen(place.local);
155+
match &terminator.kind {
156+
TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. }
157+
| TerminatorKind::Yield { resume_arg: Place { local, .. }, .. } => {
158+
sets.gen(*local);
159+
}
160+
161+
// Nothing to do for these. Match exhaustively so this fails to compile when new
162+
// variants are added.
163+
TerminatorKind::Call { destination: None, .. }
164+
| TerminatorKind::Abort
165+
| TerminatorKind::Assert { .. }
166+
| TerminatorKind::Drop { .. }
167+
| TerminatorKind::DropAndReplace { .. }
168+
| TerminatorKind::FalseEdges { .. }
169+
| TerminatorKind::FalseUnwind { .. }
170+
| TerminatorKind::GeneratorDrop
171+
| TerminatorKind::Goto { .. }
172+
| TerminatorKind::Resume
173+
| TerminatorKind::Return
174+
| TerminatorKind::SwitchInt { .. }
175+
| TerminatorKind::Unreachable => {}
157176
}
158177
}
159178

160179
fn terminator_effect(&self, sets: &mut GenKillSet<Local>, loc: Location) {
161-
// For call terminators the destination requires storage for the call
162-
// and after the call returns successfully, but not after a panic.
163-
// Since `propagate_call_unwind` doesn't exist, we have to kill the
164-
// destination here, and then gen it again in `propagate_call_return`.
165-
if let TerminatorKind::Call { destination: Some((ref place, _)), .. } =
166-
self.body[loc.block].terminator().kind
167-
{
168-
if let Some(local) = place.as_local() {
169-
sets.kill(local);
180+
match &self.body[loc.block].terminator().kind {
181+
// For call terminators the destination requires storage for the call
182+
// and after the call returns successfully, but not after a panic.
183+
// Since `propagate_call_unwind` doesn't exist, we have to kill the
184+
// destination here, and then gen it again in `propagate_call_return`.
185+
TerminatorKind::Call { destination: Some((Place { local, .. }, _)), .. } => {
186+
sets.kill(*local);
170187
}
188+
189+
// Nothing to do for these. Match exhaustively so this fails to compile when new
190+
// variants are added.
191+
TerminatorKind::Call { destination: None, .. }
192+
| TerminatorKind::Yield { .. }
193+
| TerminatorKind::Abort
194+
| TerminatorKind::Assert { .. }
195+
| TerminatorKind::Drop { .. }
196+
| TerminatorKind::DropAndReplace { .. }
197+
| TerminatorKind::FalseEdges { .. }
198+
| TerminatorKind::FalseUnwind { .. }
199+
| TerminatorKind::GeneratorDrop
200+
| TerminatorKind::Goto { .. }
201+
| TerminatorKind::Resume
202+
| TerminatorKind::Return
203+
| TerminatorKind::SwitchInt { .. }
204+
| TerminatorKind::Unreachable => {}
171205
}
206+
172207
self.check_for_move(sets, loc);
173208
}
174209

0 commit comments

Comments
 (0)