Skip to content

Commit

Permalink
Rollup merge of rust-lang#55271 - sinkuu:traversal_iter, r=matthewjasper
Browse files Browse the repository at this point in the history
Unimplement ExactSizeIterator for MIR traversing iterators

If `root` is not `START_BLOCK`, `basic_blocks().len() - visited` does not represent their exact size.
  • Loading branch information
kennytm committed Oct 26, 2018
2 parents 46f5045 + 80a6b73 commit 9111fab
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions src/librustc/mir/traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct Preorder<'a, 'tcx: 'a> {
mir: &'a Mir<'tcx>,
visited: BitSet<BasicBlock>,
worklist: Vec<BasicBlock>,
root_is_start_block: bool,
}

impl<'a, 'tcx> Preorder<'a, 'tcx> {
Expand All @@ -44,6 +45,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
mir,
visited: BitSet::new_empty(mir.basic_blocks().len()),
worklist,
root_is_start_block: root == START_BLOCK,
}
}
}
Expand Down Expand Up @@ -75,15 +77,19 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {

fn size_hint(&self) -> (usize, Option<usize>) {
// All the blocks, minus the number of blocks we've visited.
let remaining = self.mir.basic_blocks().len() - self.visited.count();
let upper = self.mir.basic_blocks().len() - self.visited.count();

// We will visit all remaining blocks exactly once.
(remaining, Some(remaining))
let lower = if self.root_is_start_block {
// We will visit all remaining blocks exactly once.
upper
} else {
self.worklist.len()
};

(lower, Some(upper))
}
}

impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}

/// Postorder traversal of a graph.
///
/// Postorder traversal is when each node is visited after all of it's
Expand All @@ -105,15 +111,17 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}
pub struct Postorder<'a, 'tcx: 'a> {
mir: &'a Mir<'tcx>,
visited: BitSet<BasicBlock>,
visit_stack: Vec<(BasicBlock, Successors<'a>)>
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
root_is_start_block: bool,
}

impl<'a, 'tcx> Postorder<'a, 'tcx> {
pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
let mut po = Postorder {
mir,
visited: BitSet::new_empty(mir.basic_blocks().len()),
visit_stack: Vec::new()
visit_stack: Vec::new(),
root_is_start_block: root == START_BLOCK,
};


Expand Down Expand Up @@ -214,15 +222,19 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {

fn size_hint(&self) -> (usize, Option<usize>) {
// All the blocks, minus the number of blocks we've visited.
let remaining = self.mir.basic_blocks().len() - self.visited.count();
let upper = self.mir.basic_blocks().len() - self.visited.count();

// We will visit all remaining blocks exactly once.
(remaining, Some(remaining))
let lower = if self.root_is_start_block {
// We will visit all remaining blocks exactly once.
upper
} else {
self.visit_stack.len()
};

(lower, Some(upper))
}
}

impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {}

/// Reverse postorder traversal of a graph
///
/// Reverse postorder is the reverse order of a postorder traversal.
Expand Down

0 comments on commit 9111fab

Please sign in to comment.