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
This commit is contained in:
parent
2131b153b3
commit
8a7801908c
2 changed files with 65 additions and 24 deletions
|
|
@ -592,8 +592,15 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let param_env = tcx.param_env(def_id);
|
||||
let gen = self_arg();
|
||||
|
||||
for block in mir.basic_blocks().indices() {
|
||||
let (target, unwind, source_info) = match mir.basic_blocks()[block].terminator() {
|
||||
let mut elaborator = DropShimElaborator {
|
||||
mir: mir,
|
||||
patch: MirPatch::new(mir),
|
||||
tcx,
|
||||
param_env
|
||||
};
|
||||
|
||||
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
|
||||
let (target, unwind, source_info) = match block_data.terminator() {
|
||||
&Terminator {
|
||||
source_info,
|
||||
kind: TerminatorKind::Drop {
|
||||
|
|
@ -604,31 +611,22 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
} if local == gen => (target, unwind, source_info),
|
||||
_ => continue,
|
||||
};
|
||||
let unwind = if let Some(unwind) = unwind {
|
||||
Unwind::To(unwind)
|
||||
} else {
|
||||
let unwind = if block_data.is_cleanup {
|
||||
Unwind::InCleanup
|
||||
} else {
|
||||
Unwind::To(unwind.unwrap_or_else(|| elaborator.patch.resume_block()))
|
||||
};
|
||||
let patch = {
|
||||
let mut elaborator = DropShimElaborator {
|
||||
mir: &mir,
|
||||
patch: MirPatch::new(mir),
|
||||
tcx,
|
||||
param_env
|
||||
};
|
||||
elaborate_drop(
|
||||
&mut elaborator,
|
||||
source_info,
|
||||
&Place::Base(PlaceBase::Local(gen)),
|
||||
(),
|
||||
target,
|
||||
unwind,
|
||||
block
|
||||
);
|
||||
elaborator.patch
|
||||
};
|
||||
patch.apply(mir);
|
||||
elaborate_drop(
|
||||
&mut elaborator,
|
||||
source_info,
|
||||
&Place::Base(PlaceBase::Local(gen)),
|
||||
(),
|
||||
target,
|
||||
unwind,
|
||||
block,
|
||||
);
|
||||
}
|
||||
elaborator.patch.apply(mir);
|
||||
}
|
||||
|
||||
fn create_generator_drop_shim<'a, 'tcx>(
|
||||
|
|
|
|||
43
src/test/mir-opt/generator-drop-cleanup.rs
Normal file
43
src/test/mir-opt/generator-drop-cleanup.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#![feature(generators, generator_trait)]
|
||||
|
||||
// Regression test for #58892, generator drop shims should not have blocks
|
||||
// spuriously marked as cleanup
|
||||
|
||||
fn main() {
|
||||
let gen = || {
|
||||
yield;
|
||||
};
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
|
||||
// START rustc.main-{{closure}}.generator_drop.0.mir
|
||||
// bb0: {
|
||||
// switchInt(((*_1).0: u32)) -> [0u32: bb4, 3u32: bb7, otherwise: bb8];
|
||||
// }
|
||||
// bb1: {
|
||||
// goto -> bb5;
|
||||
// }
|
||||
// bb2: {
|
||||
// return;
|
||||
// }
|
||||
// bb3: {
|
||||
// return;
|
||||
// }
|
||||
// bb4: {
|
||||
// goto -> bb6;
|
||||
// }
|
||||
// bb5: {
|
||||
// goto -> bb2;
|
||||
// }
|
||||
// bb6: {
|
||||
// goto -> bb3;
|
||||
// }
|
||||
// bb7: {
|
||||
// StorageLive(_3);
|
||||
// goto -> bb1;
|
||||
// }
|
||||
// bb8: {
|
||||
// return;
|
||||
// }
|
||||
// END rustc.main-{{closure}}.generator_drop.0.mir
|
||||
Loading…
Add table
Add a link
Reference in a new issue