Return blocks from DropTree::build_mir
Rather than requiring the user to pass in a correctly sized blocks map.
This commit is contained in:
@@ -305,27 +305,25 @@ impl DropTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the MIR for a given drop tree.
|
/// Builds the MIR for a given drop tree.
|
||||||
///
|
|
||||||
/// `blocks` should have the same length as `self.drops`, and may have its
|
|
||||||
/// first value set to some already existing block.
|
|
||||||
fn build_mir<'tcx, T: DropTreeBuilder<'tcx>>(
|
fn build_mir<'tcx, T: DropTreeBuilder<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cfg: &mut CFG<'tcx>,
|
cfg: &mut CFG<'tcx>,
|
||||||
blocks: &mut IndexVec<DropIdx, Option<BasicBlock>>,
|
root_node: Option<BasicBlock>,
|
||||||
) {
|
) -> IndexVec<DropIdx, Option<BasicBlock>> {
|
||||||
debug!("DropTree::build_mir(drops = {:#?})", self);
|
debug!("DropTree::build_mir(drops = {:#?})", self);
|
||||||
assert_eq!(blocks.len(), self.drops.len());
|
|
||||||
|
|
||||||
self.assign_blocks::<T>(cfg, blocks);
|
let mut blocks = self.assign_blocks::<T>(cfg, root_node);
|
||||||
self.link_blocks(cfg, blocks)
|
self.link_blocks(cfg, &mut blocks);
|
||||||
|
|
||||||
|
blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign blocks for all of the drops in the drop tree that need them.
|
/// Assign blocks for all of the drops in the drop tree that need them.
|
||||||
fn assign_blocks<'tcx, T: DropTreeBuilder<'tcx>>(
|
fn assign_blocks<'tcx, T: DropTreeBuilder<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
cfg: &mut CFG<'tcx>,
|
cfg: &mut CFG<'tcx>,
|
||||||
blocks: &mut IndexVec<DropIdx, Option<BasicBlock>>,
|
root_node: Option<BasicBlock>,
|
||||||
) {
|
) -> IndexVec<DropIdx, Option<BasicBlock>> {
|
||||||
// StorageDead statements can share blocks with each other and also with
|
// StorageDead statements can share blocks with each other and also with
|
||||||
// a Drop terminator. We iterate through the drops to find which drops
|
// a Drop terminator. We iterate through the drops to find which drops
|
||||||
// need their own block.
|
// need their own block.
|
||||||
@@ -342,8 +340,11 @@ impl DropTree {
|
|||||||
Own,
|
Own,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut blocks = IndexVec::from_elem(None, &self.drops);
|
||||||
|
blocks[ROOT_NODE] = root_node;
|
||||||
|
|
||||||
let mut needs_block = IndexVec::from_elem(Block::None, &self.drops);
|
let mut needs_block = IndexVec::from_elem(Block::None, &self.drops);
|
||||||
if blocks[ROOT_NODE].is_some() {
|
if root_node.is_some() {
|
||||||
// In some cases (such as drops for `continue`) the root node
|
// In some cases (such as drops for `continue`) the root node
|
||||||
// already has a block. In this case, make sure that we don't
|
// already has a block. In this case, make sure that we don't
|
||||||
// override it.
|
// override it.
|
||||||
@@ -385,6 +386,8 @@ impl DropTree {
|
|||||||
|
|
||||||
debug!("assign_blocks: blocks = {:#?}", blocks);
|
debug!("assign_blocks: blocks = {:#?}", blocks);
|
||||||
assert!(entry_points.is_empty());
|
assert!(entry_points.is_empty());
|
||||||
|
|
||||||
|
blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_blocks<'tcx>(
|
fn link_blocks<'tcx>(
|
||||||
@@ -1574,10 +1577,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
continue_block: Option<BasicBlock>,
|
continue_block: Option<BasicBlock>,
|
||||||
) -> Option<BlockAnd<()>> {
|
) -> Option<BlockAnd<()>> {
|
||||||
let mut blocks = IndexVec::from_elem(None, &drops.drops);
|
let blocks = drops.build_mir::<ExitScopes>(&mut self.cfg, continue_block);
|
||||||
blocks[ROOT_NODE] = continue_block;
|
|
||||||
|
|
||||||
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
|
|
||||||
let is_coroutine = self.coroutine.is_some();
|
let is_coroutine = self.coroutine.is_some();
|
||||||
|
|
||||||
// Link the exit drop tree to unwind drop tree.
|
// Link the exit drop tree to unwind drop tree.
|
||||||
@@ -1633,8 +1633,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||||||
let drops = &mut self.scopes.coroutine_drops;
|
let drops = &mut self.scopes.coroutine_drops;
|
||||||
let cfg = &mut self.cfg;
|
let cfg = &mut self.cfg;
|
||||||
let fn_span = self.fn_span;
|
let fn_span = self.fn_span;
|
||||||
let mut blocks = IndexVec::from_elem(None, &drops.drops);
|
let blocks = drops.build_mir::<CoroutineDrop>(cfg, None);
|
||||||
drops.build_mir::<CoroutineDrop>(cfg, &mut blocks);
|
|
||||||
if let Some(root_block) = blocks[ROOT_NODE] {
|
if let Some(root_block) = blocks[ROOT_NODE] {
|
||||||
cfg.terminate(
|
cfg.terminate(
|
||||||
root_block,
|
root_block,
|
||||||
@@ -1670,9 +1669,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||||||
fn_span: Span,
|
fn_span: Span,
|
||||||
resume_block: &mut Option<BasicBlock>,
|
resume_block: &mut Option<BasicBlock>,
|
||||||
) {
|
) {
|
||||||
let mut blocks = IndexVec::from_elem(None, &drops.drops);
|
let blocks = drops.build_mir::<Unwind>(cfg, *resume_block);
|
||||||
blocks[ROOT_NODE] = *resume_block;
|
|
||||||
drops.build_mir::<Unwind>(cfg, &mut blocks);
|
|
||||||
if let (None, Some(resume)) = (*resume_block, blocks[ROOT_NODE]) {
|
if let (None, Some(resume)) = (*resume_block, blocks[ROOT_NODE]) {
|
||||||
cfg.terminate(resume, SourceInfo::outermost(fn_span), TerminatorKind::UnwindResume);
|
cfg.terminate(resume, SourceInfo::outermost(fn_span), TerminatorKind::UnwindResume);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user