Skip to content

Commit b725535

Browse files
committed
Address CR feedback
1 parent f09d381 commit b725535

File tree

3 files changed

+26
-61
lines changed

3 files changed

+26
-61
lines changed

src/libcore/iter/iterator.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,11 +1338,11 @@ pub trait Iterator {
13381338
/// An iterator method that applies a function as long as it returns
13391339
/// successfully, producing a single, final value.
13401340
///
1341-
/// `fold()` takes two arguments: an initial value, and a closure with two
1342-
/// arguments: an 'accumulator', and an element. The closure either returns
1343-
/// successfully, with the value that the accumulator should have for the
1344-
/// next iteration, or it returns failure, with an error value that is
1345-
/// propagated back to the caller immediately (short-circuiting).
1341+
/// `try_fold()` takes two arguments: an initial value, and a closure with
1342+
/// two arguments: an 'accumulator', and an element. The closure either
1343+
/// returns successfully, with the value that the accumulator should have
1344+
/// for the next iteration, or it returns failure, with an error value that
1345+
/// is propagated back to the caller immediately (short-circuiting).
13461346
///
13471347
/// The initial value is the value the accumulator will have on the first
13481348
/// call. If applying the closure succeeded against every element of the
@@ -1353,9 +1353,16 @@ pub trait Iterator {
13531353
///
13541354
/// # Note to Implementors
13551355
///
1356-
/// If possible, override this method with an implementation using
1357-
/// internal iteration. Most of the other methods have their default
1358-
/// implementation in terms of this one.
1356+
/// Most of the other (forward) methods have default implementations in
1357+
/// terms of this one, so try to implement this explicitly if it can
1358+
/// do something better than the default `for` loop implementation.
1359+
///
1360+
/// In particular, try to have this call `try_fold()` on the internal parts
1361+
/// from which this iterator is composed. If multiple calls are needed,
1362+
/// the `?` operator be convenient for chaining the accumulator value along,
1363+
/// but beware any invariants that need to be upheld before those early
1364+
/// returns. This is a `&mut self` method, so iteration needs to be
1365+
/// resumable after hitting an error here.
13591366
///
13601367
/// # Examples
13611368
///
@@ -1687,7 +1694,7 @@ pub trait Iterator {
16871694
// The addition might panic on overflow
16881695
self.try_fold(0, move |i, x| {
16891696
if predicate(x) { SearchResult::Found(i) }
1690-
else { SearchResult::NotFound(i+1) }
1697+
else { SearchResult::NotFound(i + 1) }
16911698
}).into_option()
16921699
}
16931700

@@ -1973,7 +1980,7 @@ pub trait Iterator {
19731980
let mut ts: FromA = Default::default();
19741981
let mut us: FromB = Default::default();
19751982

1976-
self.for_each(|(t, u)|{
1983+
self.for_each(|(t, u)| {
19771984
ts.extend(Some(t));
19781985
us.extend(Some(u));
19791986
});
@@ -2380,7 +2387,7 @@ trait SpecIterator : Iterator {
23802387
fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
23812388
}
23822389

2383-
impl<I:Iterator+?Sized> SpecIterator for I {
2390+
impl<I: Iterator + ?Sized> SpecIterator for I {
23842391
default fn spec_nth(&mut self, mut n: usize) -> Option<Self::Item> {
23852392
for x in self {
23862393
if n == 0 { return Some(x) }
@@ -2390,11 +2397,11 @@ impl<I:Iterator+?Sized> SpecIterator for I {
23902397
}
23912398
}
23922399

2393-
impl<I:Iterator+Sized> SpecIterator for I {
2400+
impl<I: Iterator + Sized> SpecIterator for I {
23942401
fn spec_nth(&mut self, n: usize) -> Option<Self::Item> {
23952402
self.try_fold(n, move |i, x| {
23962403
if i == 0 { SearchResult::Found(x) }
2397-
else { SearchResult::NotFound(i-1) }
2404+
else { SearchResult::NotFound(i - 1) }
23982405
}).into_option()
23992406
}
24002407
}

src/libcore/iter/mod.rs

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ mod range;
337337
mod sources;
338338
mod traits;
339339

340-
/// ZST used to implement foo methods in terms of try_foo
340+
/// Transparent newtype used to implement foo methods in terms of try_foo.
341+
/// Important until #43278 is fixed; might be better as `Result<T, !>` later.
341342
struct AlwaysOk<T>(pub T);
342343

343344
impl<T> Try for AlwaysOk<T> {
@@ -2310,23 +2311,6 @@ impl<I> Iterator for Take<I> where I: Iterator{
23102311
}).into_try()
23112312
}
23122313
}
2313-
2314-
#[inline]
2315-
fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
2316-
where Fold: FnMut(Acc, Self::Item) -> Acc,
2317-
{
2318-
let mut n = self.n;
2319-
if n == 0 {
2320-
init
2321-
} else {
2322-
self.iter.try_fold(init, move |acc, x| {
2323-
n -= 1;
2324-
let acc = fold(acc, x);
2325-
if n == 0 { SearchResult::Found(acc) }
2326-
else { SearchResult::NotFound(acc) }
2327-
}).into_inner()
2328-
}
2329-
}
23302314
}
23312315

23322316
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2392,20 +2376,6 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
23922376
}
23932377
}).into_try()
23942378
}
2395-
2396-
#[inline]
2397-
fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
2398-
where Fold: FnMut(Acc, Self::Item) -> Acc,
2399-
{
2400-
let mut state = self.state;
2401-
let mut f = self.f;
2402-
self.iter.try_fold(init, move |acc, x| {
2403-
match f(&mut state, x) {
2404-
None => SearchResult::Found(acc),
2405-
Some(v) => SearchResult::NotFound(fold(acc, v)),
2406-
}
2407-
}).into_inner()
2408-
}
24092379
}
24102380

24112381
/// An iterator that maps each element to an iterator, and yields the elements

src/libcore/slice/mod.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,14 +1197,8 @@ macro_rules! iterator {
11971197
// Let LLVM unroll this, rather than using the default
11981198
// impl that would force the manual unrolling above
11991199
let mut accum = init;
1200-
unsafe {
1201-
if mem::size_of::<T>() != 0 {
1202-
assume(!self.ptr.is_null());
1203-
assume(self.ptr <= self.end);
1204-
}
1205-
while self.ptr != self.end {
1206-
accum = f(accum, $mkref!(self.ptr.post_inc()));
1207-
}
1200+
while let Some(x) = self.next() {
1201+
accum = f(accum, x);
12081202
}
12091203
accum
12101204
}
@@ -1259,14 +1253,8 @@ macro_rules! iterator {
12591253
// Let LLVM unroll this, rather than using the default
12601254
// impl that would force the manual unrolling above
12611255
let mut accum = init;
1262-
unsafe {
1263-
if mem::size_of::<T>() != 0 {
1264-
assume(!self.ptr.is_null());
1265-
assume(self.ptr <= self.end);
1266-
}
1267-
while self.ptr != self.end {
1268-
accum = f(accum, $mkref!(self.end.pre_dec()));
1269-
}
1256+
while let Some(x) = self.next_back() {
1257+
accum = f(accum, x);
12701258
}
12711259
accum
12721260
}

0 commit comments

Comments
 (0)