Skip to content

Commit de23b54

Browse files
committed
Auto merge of #5272 - Phlosioneer:5211-missing-size-hints, r=matklad
Implement size_hint for some iterators This PR implements size_hints for `Deps`, `DepsNotReplaced`, and `Members`. These size_hints are used extensively by cargo to allocate Vecs. `Deps`, `DepsNotReplaced`, and `RcVecIter` also now implement `ExactSizeIterator`. Closes #5211
2 parents d0829a2 + 5e55687 commit de23b54

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

src/cargo/core/resolver/resolve.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::iter::FromIterator;
44

55
use url::Url;
66

7-
use core::{PackageId, Summary};
87
use core::PackageIdSpec;
8+
use core::{PackageId, Summary};
99
use util::Graph;
1010
use util::errors::CargoResult;
1111
use util::graph::{Edges, Nodes};
@@ -203,8 +203,17 @@ impl<'a> Iterator for Deps<'a> {
203203
.and_then(|e| e.next())
204204
.map(|id| self.resolve.replacement(id).unwrap_or(id))
205205
}
206+
207+
fn size_hint(&self) -> (usize, Option<usize>) {
208+
// Note: Edges is actually a std::collections::hash_set::Iter, which
209+
// is an ExactSizeIterator.
210+
let len = self.edges.as_ref().map(ExactSizeIterator::len).unwrap_or(0);
211+
(len, Some(len))
212+
}
206213
}
207214

215+
impl<'a> ExactSizeIterator for Deps<'a> {}
216+
208217
pub struct DepsNotReplaced<'a> {
209218
edges: Option<Edges<'a, PackageId>>,
210219
}
@@ -215,4 +224,13 @@ impl<'a> Iterator for DepsNotReplaced<'a> {
215224
fn next(&mut self) -> Option<&'a PackageId> {
216225
self.edges.as_mut().and_then(|e| e.next())
217226
}
227+
228+
fn size_hint(&self) -> (usize, Option<usize>) {
229+
// Note: Edges is actually a std::collections::hash_set::Iter, which
230+
// is an ExactSizeIterator.
231+
let len = self.edges.as_ref().map(ExactSizeIterator::len).unwrap_or(0);
232+
(len, Some(len))
233+
}
218234
}
235+
236+
impl<'a> ExactSizeIterator for DepsNotReplaced<'a> {}

src/cargo/core/resolver/types.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,13 @@ where
343343
}
344344

345345
fn size_hint(&self) -> (usize, Option<usize>) {
346+
// rest is a std::ops::Range, which is an ExactSizeIterator.
346347
self.rest.size_hint()
347348
}
348349
}
349350

351+
impl<T: Clone> ExactSizeIterator for RcVecIter<T> {}
352+
350353
pub struct RcList<T> {
351354
pub head: Option<Rc<(T, RcList<T>)>>,
352355
}

src/cargo/core/workspace.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use glob::glob;
88
use url::Url;
99

1010
use core::registry::PackageRegistry;
11-
use core::{EitherManifest, Package, SourceId, VirtualManifest};
1211
use core::{Dependency, PackageIdSpec, Profile, Profiles};
12+
use core::{EitherManifest, Package, SourceId, VirtualManifest};
1313
use ops;
1414
use sources::PathSource;
1515
use util::errors::{CargoResult, CargoResultExt};
@@ -776,6 +776,11 @@ impl<'a, 'cfg> Iterator for Members<'a, 'cfg> {
776776
}
777777
}
778778
}
779+
780+
fn size_hint(&self) -> (usize, Option<usize>) {
781+
let (_, upper) = self.iter.size_hint();
782+
(0, upper)
783+
}
779784
}
780785

781786
impl MaybePackage {

0 commit comments

Comments
 (0)