Skip to content

Commit

Permalink
Implement some trivial size_hints for various iterators
Browse files Browse the repository at this point in the history
This also implements ExactSizeIterator where applicable.

Addresses most of the Iterator traits mentioned in #23708.
  • Loading branch information
Phlosioneer committed Mar 20, 2018
1 parent 6bfa7d0 commit 619003d
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/libcore/char.rs
Expand Up @@ -902,6 +902,11 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
}
})
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}

#[unstable(feature = "decode_utf8", issue = "33906")]
Expand Down
4 changes: 4 additions & 0 deletions src/libcore/iter/traits.rs
Expand Up @@ -901,6 +901,10 @@ impl<I, T, E> Iterator for ResultShunt<I, E>
None => None,
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}

#[stable(feature = "iter_arith_traits_result", since="1.16.0")]
Expand Down
5 changes: 5 additions & 0 deletions src/libcore/option.rs
Expand Up @@ -1188,6 +1188,11 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
None => None,
}
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}

let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/hir/pat_util.rs
Expand Up @@ -31,6 +31,10 @@ impl<I> Iterator for EnumerateAndAdjust<I> where I: Iterator {
(if i < self.gap_pos { i } else { i + self.gap_len }, elem)
})
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.enumerate.size_hint()
}
}

pub trait EnumerateAndAdjustIterator {
Expand Down
26 changes: 26 additions & 0 deletions src/librustc/mir/traversal.rs
Expand Up @@ -77,8 +77,18 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {

None
}

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();

// We will visit all remaining blocks exactly once.
(remaining, Some(remaining))
}
}

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 Down Expand Up @@ -210,8 +220,18 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {

next.map(|(bb, _)| (bb, &self.mir[bb]))
}

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();

// We will visit all remaining blocks exactly once.
(remaining, Some(remaining))
}
}

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 Expand Up @@ -276,4 +296,10 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {

self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb]))
}

fn size_hint(&self) -> (usize, Option<usize>) {
(self.idx, Some(self.idx))
}
}

impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {}
7 changes: 7 additions & 0 deletions src/librustc/session/search_paths.rs
Expand Up @@ -78,4 +78,11 @@ impl<'a> Iterator for Iter<'a> {
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
// This iterator will never return more elements than the base iterator;
// but it can ignore all the remaining elements.
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
5 changes: 5 additions & 0 deletions src/librustc/traits/util.rs
Expand Up @@ -347,6 +347,11 @@ impl<'tcx,I:Iterator<Item=ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.base_iterator.size_hint();
(0, upper)
}
}

///////////////////////////////////////////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_data_structures/bitvec.rs
Expand Up @@ -132,6 +132,11 @@ impl<'a> Iterator for BitVectorIter<'a> {
self.idx += offset + 1;
return Some(self.idx - 1);
}

fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}

impl FromIterator<bool> for BitVector {
Expand Down
13 changes: 13 additions & 0 deletions src/librustc_data_structures/graph/mod.rs
Expand Up @@ -334,6 +334,11 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
self.next = edge.next_edge[self.direction.repr];
Some((edge_index, edge))
}

fn size_hint(&self) -> (usize, Option<usize>) {
// At most, all the edges in the graph.
(0, Some(self.graph.len_edges()))
}
}

pub struct DepthFirstTraversal<'g, N, E>
Expand Down Expand Up @@ -383,8 +388,16 @@ impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
}
next
}

fn size_hint(&self) -> (usize, Option<usize>) {
// We will visit every node in the graph exactly once.
let remaining = self.graph.len_nodes() - self.visited.count();
(remaining, Some(remaining))
}
}

impl<'g, N: Debug, E: Debug> ExactSizeIterator for DepthFirstTraversal<'g, N, E> {}

impl<E> Edge<E> {
pub fn source(&self) -> NodeIndex {
self.source
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_driver/pretty.rs
Expand Up @@ -584,6 +584,13 @@ impl<'a, 'hir> Iterator for NodesMatchingUII<'a, 'hir> {
&mut NodesMatchingSuffix(ref mut iter) => iter.next(),
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
match self {
&NodesMatchingDirect(ref iter) => iter.size_hint(),
&NodesMatchingSuffix(ref iter) => iter.size_hint(),
}
}
}

impl UserIdentifiedItem {
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_typeck/check/method/suggest.rs
Expand Up @@ -718,8 +718,15 @@ impl<'a> Iterator for AllTraits<'a> {
TraitInfo::new(*info)
})
}

fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.borrow.as_ref().unwrap().len() - self.idx;
(len, Some(len))
}
}

impl<'a> ExactSizeIterator for AllTraits<'a> {}


struct UsePlacementFinder<'a, 'tcx: 'a, 'gcx: 'tcx> {
target_module: ast::NodeId,
Expand Down
5 changes: 5 additions & 0 deletions src/librustdoc/clean/mod.rs
Expand Up @@ -602,6 +602,11 @@ impl<'a> Iterator for ListAttributesIter<'a> {

None
}

fn size_hint(&self) -> (usize, Option<usize>) {
let lower = self.current_list.len();
(lower, None)
}
}

pub trait AttributesExt {
Expand Down
9 changes: 9 additions & 0 deletions src/libsyntax_ext/format_foreign.rs
Expand Up @@ -272,6 +272,11 @@ pub mod printf {
self.s = tail;
Some(sub)
}

fn size_hint(&self) -> (usize, Option<usize>) {
// Substitutions are at least 2 characters long.
(0, Some(self.s.len() / 2))
}
}

enum State {
Expand Down Expand Up @@ -782,6 +787,10 @@ pub mod shell {
None => None,
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.s.len()))
}
}

/// Parse the next substitution from the input string.
Expand Down

0 comments on commit 619003d

Please sign in to comment.