diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-03-07 21:51:34 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2020-03-07 21:51:34 +0100 |
| commit | 5ac41a1a8d28493c7aa927ae49c664b9b9dce476 (patch) | |
| tree | 55e1a95b282c03796f07588dee5101b21a5e36a3 | |
| parent | 425e7e5596c0ab6555fa75292d38863280d4a3d7 (diff) | |
| download | rust-5ac41a1a8d28493c7aa927ae49c664b9b9dce476.tar.gz rust-5ac41a1a8d28493c7aa927ae49c664b9b9dce476.zip | |
Don't insert panic when generator can not unwind
| -rw-r--r-- | src/librustc_mir/transform/generator.rs | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index cc8d2807b47..0502e57533d 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -1008,6 +1008,45 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { false } +fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { + // Nothing can unwind when landing pads are off. + if tcx.sess.no_landing_pads() { + return false; + } + + // Unwinds can only start at certain terminators. + for block in body.basic_blocks() { + match block.terminator().kind { + // These never unwind. + TerminatorKind::Goto { .. } + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Abort + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::GeneratorDrop + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } => {} + + // Resume will *continue* unwinding, but if there's no other unwinding terminator it + // will never be reached. + TerminatorKind::Resume => {} + + TerminatorKind::Yield { .. } => { + unreachable!("`can_unwind` called before generator transform") + } + + // These may unwind. + TerminatorKind::Drop { .. } + | TerminatorKind::DropAndReplace { .. } + | TerminatorKind::Call { .. } + | TerminatorKind::Assert { .. } => return true, + } + } + + // If we didn't find an unwinding terminator, the function cannot unwind. + false +} + fn create_generator_resume_function<'tcx>( tcx: TyCtxt<'tcx>, transform: TransformVisitor<'tcx>, @@ -1041,7 +1080,12 @@ fn create_generator_resume_function<'tcx>( ); } - cases.insert(2, (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(generator_kind)))); + if can_unwind(tcx, body) { + cases.insert( + 2, + (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(generator_kind))), + ); + } insert_switch(body, cases, &transform, TerminatorKind::Unreachable); |
