diff --git a/src/libcore/char.rs b/src/libcore/char.rs index bbeebf52a73c19ddeda47bfcc44187b4532ed7a0..718c6b893edf229cfecf8ddb9d337521634136fd 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -902,6 +902,16 @@ fn next(&mut self) -> Option> { } }) } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.0.size_hint(); + + // A code point is at most 4 bytes long. + let min_code_points = lower / 4; + + (min_code_points, upper) + } } #[unstable(feature = "decode_utf8", issue = "33906")] diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 0267fcd375453cbcdd24f9f6e330ebdb3a65787f..c3aebc4fb23ce37eb8c4aaf63c65a4297d798889 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -901,6 +901,15 @@ fn next(&mut self) -> Option { None => None, } } + + fn size_hint(&self) -> (usize, Option) { + if self.error.is_some() { + (0, Some(0)) + } else { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } + } } #[stable(feature = "iter_arith_traits_result", since="1.16.0")] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 570f745f8330c78739bd095d97d20416b9e362cc..61ef6798b2efb2062d5c874f531c86171a573c22 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1188,6 +1188,16 @@ fn next(&mut self) -> Option { None => None, } } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + if self.found_none { + (0, Some(0)) + } else { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } + } } 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 2bec224362ea64710106683d573240ba914afacc..1f00a3ab1f5ded464dc5fb701b7725ad9afa0a9e 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -31,6 +31,10 @@ fn next(&mut self) -> Option<(usize, ::Item)> { (if i < self.gap_pos { i } else { i + self.gap_len }, elem) }) } + + fn size_hint(&self) -> (usize, Option) { + self.enumerate.size_hint() + } } pub trait EnumerateAndAdjustIterator { diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 74c3408c4c2f61837d9e3e7fb4841b7080ee0518..666ca5eabe81b93485f5ba5cf3718ceaef1b43e1 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -77,8 +77,18 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { None } + + fn size_hint(&self) -> (usize, Option) { + // 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 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { next.map(|(bb, _)| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option) { + // 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 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option) { + (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 5bbc6841693ea3628c75c8ebf35988b046485ac1..d2dca9f60845a42ee91d7c2d1e47b344633a786a 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -78,4 +78,11 @@ fn next(&mut self) -> Option<(&'a Path, PathKind)> { } } } + + fn size_hint(&self) -> (usize, Option) { + // 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 8f7a24057472c1c2d65b48b4a52e13b366a393e6..9e38911f53c9a0ec179cb93f5428725b1e771349 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -347,6 +347,11 @@ fn next(&mut self) -> Option> { } } } + + fn size_hint(&self) -> (usize, Option) { + 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 54565afa4c6c7be4154cd9c5f15529c4b61c41d1..28e3180063c170d83a497e4d0307e5d1bbd8c72d 100644 --- a/src/librustc_data_structures/bitvec.rs +++ b/src/librustc_data_structures/bitvec.rs @@ -132,6 +132,11 @@ fn next(&mut self) -> Option { self.idx += offset + 1; return Some(self.idx - 1); } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } impl FromIterator for BitVector { diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 1945b82c03145218b9ac3c3730ff9ac0e4425182..e2b393071ff5c4ec0333aaf2f343ed31db734902 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -334,6 +334,11 @@ fn next(&mut self) -> Option<(EdgeIndex, &'g Edge)> { self.next = edge.next_edge[self.direction.repr]; Some((edge_index, edge)) } + + fn size_hint(&self) -> (usize, Option) { + // At most, all the edges in the graph. + (0, Some(self.graph.len_edges())) + } } pub struct DepthFirstTraversal<'g, N, E> @@ -383,8 +388,16 @@ fn next(&mut self) -> Option { } next } + + fn size_hint(&self) -> (usize, Option) { + // 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 Edge { pub fn source(&self) -> NodeIndex { self.source diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4ae6a93d6983a12bd8535c7b19f1fca136ce4401..c5e7fdb30d36ade6dd716322037674395a9fe0d4 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -584,6 +584,13 @@ fn next(&mut self) -> Option { &mut NodesMatchingSuffix(ref mut iter) => iter.next(), } } + + fn size_hint(&self) -> (usize, Option) { + 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 c4d98c8a2abb536b7bdc36caf9436eb7035b7286..4bc2d8ce123a7527091376b97b95b207aa5f49da 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -730,8 +730,15 @@ fn next(&mut self) -> Option { TraitInfo::new(*info) }) } + + fn size_hint(&self) -> (usize, Option) { + 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 7f3a50cf561c9d4358f2afb3141dcc9fcb054cbf..e3ba482eecfeef90058febf1fe74a6a6ee6aaabc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -604,6 +604,11 @@ fn next(&mut self) -> Option { None } + + fn size_hint(&self) -> (usize, Option) { + 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 0476d7d4fcc1c53b45d14f0e6f1e94187efafbd1..e95c6f2e1243fe7f5a2556d64d243eb3c30e12b4 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -272,6 +272,11 @@ fn next(&mut self) -> Option { self.s = tail; Some(sub) } + + fn size_hint(&self) -> (usize, Option) { + // Substitutions are at least 2 characters long. + (0, Some(self.s.len() / 2)) + } } enum State { @@ -782,6 +787,10 @@ fn next(&mut self) -> Option { None => None, } } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.s.len())) + } } /// Parse the next substitution from the input string.