diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 3e27a3e990a..9a3605b7a6a 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -2,7 +2,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::graph::dominators::{self, Dominators}; use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode}; use rustc_index::bit_set::BitSet; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::IndexVec; use rustc_middle::mir::{self, BasicBlock, Terminator, TerminatorKind}; use std::cmp::Ordering; @@ -81,9 +81,23 @@ impl CoverageGraph { IndexVec>, ) { let num_basic_blocks = mir_body.basic_blocks.len(); - let mut bcbs = IndexVec::with_capacity(num_basic_blocks); + let mut bcbs = IndexVec::::with_capacity(num_basic_blocks); let mut bb_to_bcb = IndexVec::from_elem_n(None, num_basic_blocks); + let mut add_basic_coverage_block = |basic_blocks: &mut Vec| { + // Take the accumulated list of blocks, leaving the vector empty + // to be used by subsequent BCBs. + let basic_blocks = std::mem::take(basic_blocks); + + let bcb = bcbs.next_index(); + for &bb in basic_blocks.iter() { + bb_to_bcb[bb] = Some(bcb); + } + let bcb_data = BasicCoverageBlockData::from(basic_blocks); + debug!("adding bcb{}: {:?}", bcb.index(), bcb_data); + bcbs.push(bcb_data); + }; + // Walk the MIR CFG using a Preorder traversal, which starts from `START_BLOCK` and follows // each block terminator's `successors()`. Coverage spans must map to actual source code, // so compiler generated blocks and paths can be ignored. To that end, the CFG traversal @@ -113,11 +127,7 @@ impl CoverageGraph { predecessors = ?&mir_body.basic_blocks.predecessors()[bb], "can't chain from {prev:?} to {bb:?}" ); - Self::add_basic_coverage_block( - &mut bcbs, - &mut bb_to_bcb, - basic_blocks.split_off(0), - ); + add_basic_coverage_block(&mut basic_blocks); } basic_blocks.push(bb); @@ -125,26 +135,12 @@ impl CoverageGraph { if !basic_blocks.is_empty() { debug!("flushing accumulated blocks into one last BCB"); - Self::add_basic_coverage_block(&mut bcbs, &mut bb_to_bcb, basic_blocks.split_off(0)); + add_basic_coverage_block(&mut basic_blocks); } (bcbs, bb_to_bcb) } - fn add_basic_coverage_block( - bcbs: &mut IndexVec, - bb_to_bcb: &mut IndexSlice>, - basic_blocks: Vec, - ) { - let bcb = bcbs.next_index(); - for &bb in basic_blocks.iter() { - bb_to_bcb[bb] = Some(bcb); - } - let bcb_data = BasicCoverageBlockData::from(basic_blocks); - debug!("adding bcb{}: {:?}", bcb.index(), bcb_data); - bcbs.push(bcb_data); - } - #[inline(always)] pub fn iter_enumerated( &self,