Skip to content

Commit d44233e

Browse files
committed
Temp: Cleanup 6 (Separate exit trees)
1 parent e41a7c5 commit d44233e

File tree

2 files changed

+35
-31
lines changed

2 files changed

+35
-31
lines changed

src/librustc_mir_build/build/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
711711
fn_span: span,
712712
arg_count,
713713
generator_kind,
714-
scopes: scope::Scopes::new(is_generator),
714+
scopes: scope::Scopes::new(),
715715
block_context: BlockContext::new(),
716716
source_scopes: IndexVec::new(),
717717
source_scope: OUTERMOST_SOURCE_SCOPE,

src/librustc_mir_build/build/scope.rs

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,10 @@ struct BreakableScope<'tcx> {
155155
/// The destination of the loop/block expression itself (i.e., where to put
156156
/// the result of a `break` or `return` expression)
157157
break_destination: Place<'tcx>,
158-
/// Drops that happen on the
159-
drops: DropTree,
158+
/// Drops that happen on the `break`/`return` path.
159+
break_drops: DropTree,
160+
/// Drops that happen on the `continue` path.
161+
continue_drops: Option<DropTree>,
160162
}
161163

162164
/// The target of an expression that breaks out of a scope
@@ -172,10 +174,8 @@ rustc_index::newtype_index! {
172174
}
173175

174176
const ROOT_NODE: DropIdx = DropIdx::from_u32_const(0);
175-
const CONTINUE_NODE: DropIdx = DropIdx::from_u32_const(1);
176177

177-
/// A tree (usually, sometimes this is a forest of two trees) of drops that we
178-
/// have deferred lowering. It's used for:
178+
/// A tree of drops that we have deferred lowering. It's used for:
179179
///
180180
/// * Drops on unwind paths
181181
/// * Drops on generator drop paths (when a suspended generator is dropped)
@@ -189,12 +189,10 @@ struct DropTree {
189189
drops: IndexVec<DropIdx, (DropData, DropIdx)>,
190190
/// Map for finding the inverse of the `next_drop` relation:
191191
///
192-
/// `previous_drops[(next_drop[i], drops[i].local, drops[i].kind] == i`
192+
/// `previous_drops[(drops[i].1, drops[i].0.local, drops[i].0.kind] == i`
193193
previous_drops: FxHashMap<(DropIdx, Local, DropKind), DropIdx>,
194194
/// Edges into the `DropTree` that need to be added once it's lowered.
195195
entry_points: Vec<(DropIdx, BasicBlock)>,
196-
/// The first non-root nodes in the forest.
197-
first_non_root: DropIdx,
198196
}
199197

200198
impl Scope {
@@ -225,15 +223,14 @@ trait DropTreeBuilder<'tcx> {
225223
}
226224

227225
impl DropTree {
228-
fn new(num_roots: usize) -> Self {
226+
fn new() -> Self {
229227
let fake_source_info = SourceInfo { span: DUMMY_SP, scope: OUTERMOST_SOURCE_SCOPE };
230228
let fake_data =
231229
DropData { source_info: fake_source_info, local: Local::MAX, kind: DropKind::Storage };
232230
let drop_idx = DropIdx::MAX;
233-
let drops = IndexVec::from_elem_n((fake_data, drop_idx), num_roots);
231+
let drops = IndexVec::from_elem_n((fake_data, drop_idx), 1);
234232
Self {
235233
drops,
236-
first_non_root: DropIdx::from_usize(num_roots),
237234
entry_points: Vec::new(),
238235
previous_drops: FxHashMap::default(),
239236
}
@@ -248,6 +245,7 @@ impl DropTree {
248245
}
249246

250247
fn add_entry(&mut self, from: BasicBlock, to: DropIdx) {
248+
debug_assert!(to < self.drops.next_index());
251249
self.entry_points.push((to, from));
252250
}
253251

@@ -285,9 +283,11 @@ impl DropTree {
285283
}
286284

287285
let mut needs_block = IndexVec::from_elem(Block::None, &self.drops);
288-
if self.first_non_root > CONTINUE_NODE {
289-
// `continue` already has its own node.
290-
needs_block[CONTINUE_NODE] = Block::Own;
286+
if blocks[ROOT_NODE].is_some() {
287+
// In some cases (such as drops for `continue`) the root node
288+
// already has a block. In this case, make sure that we don't
289+
// override it.
290+
needs_block[ROOT_NODE] = Block::Own;
291291
}
292292

293293
// Sort so that we only need to check the last
@@ -315,7 +315,7 @@ impl DropTree {
315315
if let DropKind::Value = drop_data.0.kind {
316316
needs_block[drop_data.1] = Block::Own;
317317
} else {
318-
if drop_idx >= self.first_non_root {
318+
if drop_idx != ROOT_NODE {
319319
match &mut needs_block[drop_data.1] {
320320
pred @ Block::None => *pred = Block::Shares(drop_idx),
321321
pred @ Block::Shares(_) => *pred = Block::Own,
@@ -347,7 +347,7 @@ impl DropTree {
347347
cfg.terminate(block, drop_data.0.source_info, terminator);
348348
}
349349
// Root nodes don't correspond to a drop.
350-
DropKind::Storage if drop_idx < self.first_non_root => {}
350+
DropKind::Storage if drop_idx == ROOT_NODE => {}
351351
DropKind::Storage => {
352352
let stmt = Statement {
353353
source_info: drop_data.0.source_info,
@@ -366,12 +366,12 @@ impl DropTree {
366366
}
367367

368368
impl<'tcx> Scopes<'tcx> {
369-
pub(crate) fn new(is_generator: bool) -> Self {
369+
pub(crate) fn new() -> Self {
370370
Self {
371371
scopes: Vec::new(),
372372
breakable_scopes: Vec::new(),
373-
unwind_drops: DropTree::new(1),
374-
generator_drops: DropTree::new(is_generator as usize),
373+
unwind_drops: DropTree::new(),
374+
generator_drops: DropTree::new(),
375375
}
376376
}
377377

@@ -429,13 +429,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
429429
let scope = BreakableScope {
430430
region_scope,
431431
break_destination,
432-
drops: DropTree::new(1 + loop_block.is_some() as usize),
432+
break_drops: DropTree::new(),
433+
continue_drops: loop_block.map(|_| DropTree::new()),
433434
};
434435
self.scopes.breakable_scopes.push(scope);
435436
let normal_exit_block = f(self);
436437
let breakable_scope = self.scopes.breakable_scopes.pop().unwrap();
437438
assert!(breakable_scope.region_scope == region_scope);
438-
let break_block = self.build_exit_tree(breakable_scope.drops, loop_block);
439+
let break_block = self.build_exit_tree(breakable_scope.break_drops, None);
440+
breakable_scope.continue_drops.map(|drops| {
441+
self.build_exit_tree(drops, loop_block);
442+
});
439443
match (normal_exit_block, break_block) {
440444
(Some(block), None) | (None, Some(block)) => block,
441445
(None, None) => self.cfg.start_new_block().unit(),
@@ -600,10 +604,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
600604

601605
let region_scope = self.scopes.breakable_scopes[break_index].region_scope;
602606
let scope_index = self.scopes.scope_index(region_scope, span);
603-
let exited_scopes = &self.scopes.scopes[scope_index + 1..];
604-
let scope_drops = exited_scopes.iter().flat_map(|scope| &scope.drops);
607+
let drops = if destination.is_some() {
608+
&mut self.scopes.breakable_scopes[break_index].break_drops
609+
} else {
610+
self.scopes.breakable_scopes[break_index].continue_drops.as_mut().unwrap()
611+
};
605612

606-
let drops = &mut self.scopes.breakable_scopes[break_index].drops;
607613
let mut drop_idx = DropIdx::from_u32(destination.is_none() as u32);
608614
for drop in scope_drops {
609615
drop_idx = drops.add_drop(*drop, drop_idx);
@@ -1095,15 +1101,13 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
10951101
continue_block: Option<BasicBlock>,
10961102
) -> Option<BlockAnd<()>> {
10971103
let mut blocks = IndexVec::from_elem(None, &drops.drops);
1098-
if continue_block.is_some() {
1099-
blocks[CONTINUE_NODE] = continue_block;
1100-
}
1104+
blocks[ROOT_NODE] = continue_block;
1105+
11011106
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
11021107
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
11031108
let unwind_target = self.diverge_cleanup();
1104-
let num_roots = drops.first_non_root.index();
1105-
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, num_roots);
1106-
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(num_roots) {
1109+
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
1110+
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
11071111
match drop_data.0.kind {
11081112
DropKind::Storage => {
11091113
if self.is_generator {

0 commit comments

Comments
 (0)