Skip to content

Commit 80a6b73

Browse files
committed
Unimplement ExactSizeIterator
If root is not START_BLOCK, `basic_blocks().len() - visited` does not represent their exact size.
1 parent 89be71a commit 80a6b73

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

src/librustc/mir/traversal.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct Preorder<'a, 'tcx: 'a> {
3434
mir: &'a Mir<'tcx>,
3535
visited: BitSet<BasicBlock>,
3636
worklist: Vec<BasicBlock>,
37+
root_is_start_block: bool,
3738
}
3839

3940
impl<'a, 'tcx> Preorder<'a, 'tcx> {
@@ -44,6 +45,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
4445
mir,
4546
visited: BitSet::new_empty(mir.basic_blocks().len()),
4647
worklist,
48+
root_is_start_block: root == START_BLOCK,
4749
}
4850
}
4951
}
@@ -75,15 +77,19 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
7577

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

80-
// We will visit all remaining blocks exactly once.
81-
(remaining, Some(remaining))
82+
let lower = if self.root_is_start_block {
83+
// We will visit all remaining blocks exactly once.
84+
upper
85+
} else {
86+
self.worklist.len()
87+
};
88+
89+
(lower, Some(upper))
8290
}
8391
}
8492

85-
impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}
86-
8793
/// Postorder traversal of a graph.
8894
///
8995
/// Postorder traversal is when each node is visited after all of it's
@@ -105,15 +111,17 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}
105111
pub struct Postorder<'a, 'tcx: 'a> {
106112
mir: &'a Mir<'tcx>,
107113
visited: BitSet<BasicBlock>,
108-
visit_stack: Vec<(BasicBlock, Successors<'a>)>
114+
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
115+
root_is_start_block: bool,
109116
}
110117

111118
impl<'a, 'tcx> Postorder<'a, 'tcx> {
112119
pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
113120
let mut po = Postorder {
114121
mir,
115122
visited: BitSet::new_empty(mir.basic_blocks().len()),
116-
visit_stack: Vec::new()
123+
visit_stack: Vec::new(),
124+
root_is_start_block: root == START_BLOCK,
117125
};
118126

119127

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

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

219-
// We will visit all remaining blocks exactly once.
220-
(remaining, Some(remaining))
227+
let lower = if self.root_is_start_block {
228+
// We will visit all remaining blocks exactly once.
229+
upper
230+
} else {
231+
self.visit_stack.len()
232+
};
233+
234+
(lower, Some(upper))
221235
}
222236
}
223237

224-
impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {}
225-
226238
/// Reverse postorder traversal of a graph
227239
///
228240
/// Reverse postorder is the reverse order of a postorder traversal.

0 commit comments

Comments
 (0)