about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhlosioneer <mattmdrr2@gmail.com>2018-03-20 05:33:59 -0400
committerPhlosioneer <mattmdrr2@gmail.com>2018-03-20 05:33:59 -0400
commit619003d1d414167630331efffe83702f74413be6 (patch)
treec986c64f37ab88feda2f7df926261e133d385aad
parent6bfa7d02d6713acd15ead20c199b808e85031f9e (diff)
downloadrust-619003d1d414167630331efffe83702f74413be6.tar.gz
rust-619003d1d414167630331efffe83702f74413be6.zip
Implement some trivial size_hints for various iterators
This also implements ExactSizeIterator where applicable.

Addresses most of the Iterator traits mentioned in #23708.
-rw-r--r--src/libcore/char.rs5
-rw-r--r--src/libcore/iter/traits.rs4
-rw-r--r--src/libcore/option.rs5
-rw-r--r--src/librustc/hir/pat_util.rs4
-rw-r--r--src/librustc/mir/traversal.rs26
-rw-r--r--src/librustc/session/search_paths.rs7
-rw-r--r--src/librustc/traits/util.rs5
-rw-r--r--src/librustc_data_structures/bitvec.rs5
-rw-r--r--src/librustc_data_structures/graph/mod.rs13
-rw-r--r--src/librustc_driver/pretty.rs7
-rw-r--r--src/librustc_typeck/check/method/suggest.rs7
-rw-r--r--src/librustdoc/clean/mod.rs5
-rw-r--r--src/libsyntax_ext/format_foreign.rs9
13 files changed, 102 insertions, 0 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 1638f9710f5..2f56238a463 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -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")]
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 0267fcd3754..5e4622f804a 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -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")]
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 570f745f833..1ca69f3f503 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -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 };
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 2bec224362e..1f00a3ab1f5 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -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 {
diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs
index 74c3408c4c2..666ca5eabe8 100644
--- a/src/librustc/mir/traversal.rs
+++ b/src/librustc/mir/traversal.rs
@@ -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
@@ -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.
@@ -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> {}
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index 5bbc6841693..d2dca9f6084 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -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)
+    }
 }
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 8f7a2405747..9e38911f53c 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -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)
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/src/librustc_data_structures/bitvec.rs b/src/librustc_data_structures/bitvec.rs
index 54565afa4c6..28e3180063c 100644
--- a/src/librustc_data_structures/bitvec.rs
+++ b/src/librustc_data_structures/bitvec.rs
@@ -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 {
diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs
index 1945b82c031..e2b393071ff 100644
--- a/src/librustc_data_structures/graph/mod.rs
+++ b/src/librustc_data_structures/graph/mod.rs
@@ -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>
@@ -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
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 4ae6a93d698..c5e7fdb30d3 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -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 {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 61afac97d64..a7536980503 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -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,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 904c24815cb..a2a0e878fd8 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -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 {
diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs
index 0476d7d4fcc..e95c6f2e124 100644
--- a/src/libsyntax_ext/format_foreign.rs
+++ b/src/libsyntax_ext/format_foreign.rs
@@ -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 {
@@ -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.