simplify MIR building with cfg.goto(...)
This commit is contained in:
parent
4f0dc7b06c
commit
f5a8d1ab03
7 changed files with 29 additions and 79 deletions
|
|
@ -33,8 +33,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
this.ast_block_stmts(destination, block, span, stmts, expr,
|
||||
safety_mode)
|
||||
});
|
||||
this.cfg.terminate(unpack!(block_exit), source_info,
|
||||
TerminatorKind::Goto { target: exit_block });
|
||||
this.cfg.goto(unpack!(block_exit), source_info, exit_block);
|
||||
exit_block.unit()
|
||||
} else {
|
||||
this.ast_block_stmts(destination, block, span, stmts, expr,
|
||||
|
|
|
|||
|
|
@ -85,4 +85,9 @@ impl<'tcx> CFG<'tcx> {
|
|||
kind,
|
||||
});
|
||||
}
|
||||
|
||||
/// In the `origin` block, push a `goto -> target` terminator.
|
||||
pub fn goto(&mut self, origin: BasicBlock, source_info: SourceInfo, target: BasicBlock) {
|
||||
self.terminate(origin, source_info, TerminatorKind::Goto { target })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,17 +140,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
},
|
||||
);
|
||||
|
||||
this.cfg.terminate(
|
||||
true_block,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: join_block },
|
||||
);
|
||||
this.cfg.terminate(
|
||||
false_block,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: join_block },
|
||||
);
|
||||
|
||||
// Link up both branches:
|
||||
this.cfg.goto(true_block, source_info, join_block);
|
||||
this.cfg.goto(false_block, source_info, join_block);
|
||||
join_block.unit()
|
||||
}
|
||||
ExprKind::Loop { body } => {
|
||||
|
|
@ -167,12 +159,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let loop_block = this.cfg.start_new_block();
|
||||
let exit_block = this.cfg.start_new_block();
|
||||
|
||||
// start the loop
|
||||
this.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: loop_block },
|
||||
);
|
||||
// Start the loop.
|
||||
this.cfg.goto(block, source_info, loop_block);
|
||||
|
||||
this.in_breakable_scope(
|
||||
Some(loop_block),
|
||||
|
|
@ -196,11 +184,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let tmp = this.get_unit_temp();
|
||||
// Execute the body, branching back to the test.
|
||||
let body_block_end = unpack!(this.into(&tmp, body_block, body));
|
||||
this.cfg.terminate(
|
||||
body_block_end,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: loop_block },
|
||||
);
|
||||
this.cfg.goto(body_block_end, source_info, loop_block);
|
||||
},
|
||||
);
|
||||
exit_block.unit()
|
||||
|
|
|
|||
|
|
@ -259,11 +259,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
scrutinee_span,
|
||||
match_scope,
|
||||
);
|
||||
this.cfg.terminate(
|
||||
binding_end,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: arm_block },
|
||||
);
|
||||
this.cfg.goto(binding_end, source_info, arm_block);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,11 +275,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let end_block = self.cfg.start_new_block();
|
||||
|
||||
for arm_block in arm_end_blocks {
|
||||
self.cfg.terminate(
|
||||
unpack!(arm_block),
|
||||
outer_source_info,
|
||||
TerminatorKind::Goto { target: end_block },
|
||||
);
|
||||
self.cfg.goto(unpack!(arm_block), outer_source_info, end_block);
|
||||
}
|
||||
|
||||
self.source_scope = outer_source_info.scope;
|
||||
|
|
@ -848,18 +840,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// never reach this point.
|
||||
if unmatched_candidates.is_empty() {
|
||||
let source_info = self.source_info(span);
|
||||
if let Some(otherwise) = otherwise_block {
|
||||
self.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: otherwise },
|
||||
);
|
||||
} else {
|
||||
self.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::Unreachable,
|
||||
)
|
||||
match otherwise_block {
|
||||
Some(otherwise) => self.cfg.goto(block, source_info, otherwise),
|
||||
None => self.cfg.terminate(block, source_info, TerminatorKind::Unreachable),
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -950,11 +933,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// `goto -> first_prebinding_block` from the `start_block` if there is one.
|
||||
if let Some(start_block) = *start_block {
|
||||
let source_info = self.source_info(first_candidate.span);
|
||||
self.cfg.terminate(
|
||||
start_block,
|
||||
source_info,
|
||||
TerminatorKind::Goto { target: first_prebinding_block },
|
||||
);
|
||||
self.cfg.goto(start_block, source_info, first_prebinding_block);
|
||||
} else {
|
||||
*start_block = Some(first_prebinding_block);
|
||||
}
|
||||
|
|
@ -988,8 +967,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let last_candidate = reachable_candidates.last().unwrap();
|
||||
|
||||
let last_candidate = reachable_candidates.last().unwrap();
|
||||
if let Some(otherwise) = last_candidate.otherwise_block {
|
||||
let source_info = self.source_info(last_candidate.span);
|
||||
let block = self.cfg.start_new_block();
|
||||
|
|
|
|||
|
|
@ -109,15 +109,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
self.cfg.terminate(
|
||||
from_block,
|
||||
source_info,
|
||||
TerminatorKind::Goto {
|
||||
target: real_target
|
||||
}
|
||||
);
|
||||
}
|
||||
_ => self.cfg.goto(from_block, source_info, real_target),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,14 +606,11 @@ where
|
|||
let fn_end = span.shrink_to_hi();
|
||||
let source_info = builder.source_info(fn_end);
|
||||
let return_block = builder.return_block();
|
||||
builder.cfg.terminate(block, source_info,
|
||||
TerminatorKind::Goto { target: return_block });
|
||||
builder.cfg.terminate(return_block, source_info,
|
||||
TerminatorKind::Return);
|
||||
builder.cfg.goto(block, source_info, return_block);
|
||||
builder.cfg.terminate(return_block, source_info, TerminatorKind::Return);
|
||||
// Attribute any unreachable codepaths to the function's closing brace
|
||||
if let Some(unreachable_block) = builder.cached_unreachable_block {
|
||||
builder.cfg.terminate(unreachable_block, source_info,
|
||||
TerminatorKind::Unreachable);
|
||||
builder.cfg.terminate(unreachable_block, source_info, TerminatorKind::Unreachable);
|
||||
}
|
||||
return_block.unit()
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -564,14 +564,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let source_info = scope.source_info(span);
|
||||
block = match scope.cached_exits.entry((target, region_scope)) {
|
||||
Entry::Occupied(e) => {
|
||||
self.cfg.terminate(block, source_info,
|
||||
TerminatorKind::Goto { target: *e.get() });
|
||||
self.cfg.goto(block, source_info, *e.get());
|
||||
return;
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
let b = self.cfg.start_new_block();
|
||||
self.cfg.terminate(block, source_info,
|
||||
TerminatorKind::Goto { target: b });
|
||||
self.cfg.goto(block, source_info, b);
|
||||
v.insert(b);
|
||||
b
|
||||
}
|
||||
|
|
@ -596,8 +594,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
scope = next_scope;
|
||||
}
|
||||
|
||||
let source_info = self.scopes.source_info(scope_count, span);
|
||||
self.cfg.terminate(block, source_info, TerminatorKind::Goto { target });
|
||||
self.cfg.goto(block, self.scopes.source_info(scope_count, span), target);
|
||||
}
|
||||
|
||||
/// Creates a path that performs all required cleanup for dropping a generator.
|
||||
|
|
@ -616,14 +613,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
while let Some(scope) = scopes.next() {
|
||||
block = if let Some(b) = scope.cached_generator_drop {
|
||||
self.cfg.terminate(block, src_info,
|
||||
TerminatorKind::Goto { target: b });
|
||||
self.cfg.goto(block, src_info, b);
|
||||
return Some(result);
|
||||
} else {
|
||||
let b = self.cfg.start_new_block();
|
||||
scope.cached_generator_drop = Some(b);
|
||||
self.cfg.terminate(block, src_info,
|
||||
TerminatorKind::Goto { target: b });
|
||||
self.cfg.goto(block, src_info, b);
|
||||
b
|
||||
};
|
||||
|
||||
|
|
@ -1243,8 +1238,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>,
|
|||
// block for our StorageDead statements.
|
||||
let block = cfg.start_new_cleanup_block();
|
||||
let source_info = SourceInfo { span: DUMMY_SP, scope: source_scope };
|
||||
cfg.terminate(block, source_info,
|
||||
TerminatorKind::Goto { target: target });
|
||||
cfg.goto(block, source_info, target);
|
||||
target = block;
|
||||
target_built_by_us = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue