Skip to content

Commit 8a78019

Browse files
committed
Don't incorrectly mark blocks in generator drop shims as cleanup
This also ensure that dropping a generator won't leak upvars if dropping one of them panics
1 parent 2131b15 commit 8a78019

File tree

2 files changed

+65
-24
lines changed

2 files changed

+65
-24
lines changed

src/librustc_mir/transform/generator.rs

+22-24
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,15 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
592592
let param_env = tcx.param_env(def_id);
593593
let gen = self_arg();
594594

595-
for block in mir.basic_blocks().indices() {
596-
let (target, unwind, source_info) = match mir.basic_blocks()[block].terminator() {
595+
let mut elaborator = DropShimElaborator {
596+
mir: mir,
597+
patch: MirPatch::new(mir),
598+
tcx,
599+
param_env
600+
};
601+
602+
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
603+
let (target, unwind, source_info) = match block_data.terminator() {
597604
&Terminator {
598605
source_info,
599606
kind: TerminatorKind::Drop {
@@ -604,31 +611,22 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
604611
} if local == gen => (target, unwind, source_info),
605612
_ => continue,
606613
};
607-
let unwind = if let Some(unwind) = unwind {
608-
Unwind::To(unwind)
609-
} else {
614+
let unwind = if block_data.is_cleanup {
610615
Unwind::InCleanup
616+
} else {
617+
Unwind::To(unwind.unwrap_or_else(|| elaborator.patch.resume_block()))
611618
};
612-
let patch = {
613-
let mut elaborator = DropShimElaborator {
614-
mir: &mir,
615-
patch: MirPatch::new(mir),
616-
tcx,
617-
param_env
618-
};
619-
elaborate_drop(
620-
&mut elaborator,
621-
source_info,
622-
&Place::Base(PlaceBase::Local(gen)),
623-
(),
624-
target,
625-
unwind,
626-
block
627-
);
628-
elaborator.patch
629-
};
630-
patch.apply(mir);
619+
elaborate_drop(
620+
&mut elaborator,
621+
source_info,
622+
&Place::Base(PlaceBase::Local(gen)),
623+
(),
624+
target,
625+
unwind,
626+
block,
627+
);
631628
}
629+
elaborator.patch.apply(mir);
632630
}
633631

634632
fn create_generator_drop_shim<'a, 'tcx>(
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#![feature(generators, generator_trait)]
2+
3+
// Regression test for #58892, generator drop shims should not have blocks
4+
// spuriously marked as cleanup
5+
6+
fn main() {
7+
let gen = || {
8+
yield;
9+
};
10+
}
11+
12+
// END RUST SOURCE
13+
14+
// START rustc.main-{{closure}}.generator_drop.0.mir
15+
// bb0: {
16+
// switchInt(((*_1).0: u32)) -> [0u32: bb4, 3u32: bb7, otherwise: bb8];
17+
// }
18+
// bb1: {
19+
// goto -> bb5;
20+
// }
21+
// bb2: {
22+
// return;
23+
// }
24+
// bb3: {
25+
// return;
26+
// }
27+
// bb4: {
28+
// goto -> bb6;
29+
// }
30+
// bb5: {
31+
// goto -> bb2;
32+
// }
33+
// bb6: {
34+
// goto -> bb3;
35+
// }
36+
// bb7: {
37+
// StorageLive(_3);
38+
// goto -> bb1;
39+
// }
40+
// bb8: {
41+
// return;
42+
// }
43+
// END rustc.main-{{closure}}.generator_drop.0.mir

0 commit comments

Comments
 (0)