Skip to content

Commit 69db91b

Browse files
committed
Change advance(_back)_by to return usize instead of Result<(), usize>
A successful advance is now signalled by returning `0` and other values now represent the remaining number of steps that couldn't be advanced as opposed to the amount of steps that have been advanced during a partial advance_by. This simplifies adapters a bit, replacing some `match`/`if` with arithmetic. Whether this is beneficial overall depends on whether `advance_by` is mostly used as a building-block for other iterator methods and adapters or whether we also see uses by users where `Result` might be more useful.
1 parent 7a06007 commit 69db91b

File tree

30 files changed

+315
-352
lines changed

30 files changed

+315
-352
lines changed

library/alloc/src/collections/vec_deque/into_iter.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
5454
}
5555

5656
#[inline]
57-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
57+
fn advance_by(&mut self, n: usize) -> usize {
5858
if self.inner.len < n {
5959
let len = self.inner.len;
6060
self.inner.clear();
61-
Err(len)
61+
len - n
6262
} else {
6363
self.inner.drain(..n);
64-
Ok(())
64+
0
6565
}
6666
}
6767

@@ -182,14 +182,14 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
182182
}
183183

184184
#[inline]
185-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
185+
fn advance_back_by(&mut self, n: usize) -> usize {
186186
let len = self.inner.len;
187187
if len >= n {
188188
self.inner.truncate(len - n);
189-
Ok(())
189+
0
190190
} else {
191191
self.inner.clear();
192-
Err(len)
192+
n - len
193193
}
194194
}
195195

library/alloc/src/collections/vec_deque/iter.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ impl<'a, T> Iterator for Iter<'a, T> {
5555
}
5656
}
5757

58-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
59-
let m = match self.i1.advance_by(n) {
60-
Ok(_) => return Ok(()),
61-
Err(m) => m,
62-
};
58+
fn advance_by(&mut self, n: usize) -> usize {
59+
let remaining = self.i1.advance_by(n);
60+
if remaining == 0 {
61+
return 0;
62+
}
6363
mem::swap(&mut self.i1, &mut self.i2);
64-
self.i1.advance_by(n - m).map_err(|o| o + m)
64+
self.i1.advance_by(remaining)
6565
}
6666

6767
#[inline]
@@ -125,14 +125,13 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
125125
}
126126
}
127127

128-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
129-
let m = match self.i2.advance_back_by(n) {
130-
Ok(_) => return Ok(()),
131-
Err(m) => m,
132-
};
133-
128+
fn advance_back_by(&mut self, n: usize) -> usize {
129+
let remaining = self.i2.advance_back_by(n);
130+
if remaining == 0 {
131+
return 0;
132+
}
134133
mem::swap(&mut self.i1, &mut self.i2);
135-
self.i2.advance_back_by(n - m).map_err(|o| m + o)
134+
self.i2.advance_back_by(remaining)
136135
}
137136

138137
fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc

library/alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ impl<'a, T> Iterator for IterMut<'a, T> {
4747
}
4848
}
4949

50-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
51-
let m = match self.i1.advance_by(n) {
52-
Ok(_) => return Ok(()),
53-
Err(m) => m,
54-
};
50+
fn advance_by(&mut self, n: usize) -> usize {
51+
let remaining = self.i1.advance_by(n);
52+
if remaining == 0 {
53+
return 0;
54+
}
5555
mem::swap(&mut self.i1, &mut self.i2);
56-
self.i1.advance_by(n - m).map_err(|o| o + m)
56+
self.i1.advance_by(remaining)
5757
}
5858

5959
#[inline]
@@ -117,14 +117,13 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
117117
}
118118
}
119119

120-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
121-
let m = match self.i2.advance_back_by(n) {
122-
Ok(_) => return Ok(()),
123-
Err(m) => m,
124-
};
125-
120+
fn advance_back_by(&mut self, n: usize) -> usize {
121+
let remaining = self.i2.advance_back_by(n);
122+
if remaining == 0 {
123+
return 0;
124+
}
126125
mem::swap(&mut self.i1, &mut self.i2);
127-
self.i2.advance_back_by(n - m).map_err(|o| m + o)
126+
self.i2.advance_back_by(remaining)
128127
}
129128

130129
fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc

library/alloc/src/vec/into_iter.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
213213
}
214214

215215
#[inline]
216-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
216+
fn advance_by(&mut self, n: usize) -> usize {
217217
let step_size = self.len().min(n);
218218
let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
219219
if T::IS_ZST {
@@ -227,10 +227,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
227227
unsafe {
228228
ptr::drop_in_place(to_drop);
229229
}
230-
if step_size < n {
231-
return Err(step_size);
232-
}
233-
Ok(())
230+
n - step_size
234231
}
235232

236233
#[inline]
@@ -313,7 +310,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
313310
}
314311

315312
#[inline]
316-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
313+
fn advance_back_by(&mut self, n: usize) -> usize {
317314
let step_size = self.len().min(n);
318315
if T::IS_ZST {
319316
// SAFETY: same as for advance_by()
@@ -327,10 +324,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
327324
unsafe {
328325
ptr::drop_in_place(to_drop);
329326
}
330-
if step_size < n {
331-
return Err(step_size);
332-
}
333-
Ok(())
327+
n - step_size
334328
}
335329
}
336330

library/alloc/tests/vec.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::alloc::{Allocator, Layout};
2+
use core::assert_eq;
23
use core::iter::IntoIterator;
34
use core::ptr::NonNull;
45
use std::alloc::System;
@@ -1062,21 +1063,21 @@ fn test_into_iter_leak() {
10621063

10631064
#[test]
10641065
fn test_into_iter_advance_by() {
1065-
let mut i = [1, 2, 3, 4, 5].into_iter();
1066-
i.advance_by(0).unwrap();
1067-
i.advance_back_by(0).unwrap();
1066+
let mut i = vec![1, 2, 3, 4, 5].into_iter();
1067+
assert_eq!(i.advance_by(0), 0);
1068+
assert_eq!(i.advance_back_by(0), 0);
10681069
assert_eq!(i.as_slice(), [1, 2, 3, 4, 5]);
10691070

1070-
i.advance_by(1).unwrap();
1071-
i.advance_back_by(1).unwrap();
1071+
assert_eq!(i.advance_by(1), 0);
1072+
assert_eq!(i.advance_back_by(1), 0);
10721073
assert_eq!(i.as_slice(), [2, 3, 4]);
10731074

1074-
assert_eq!(i.advance_back_by(usize::MAX), Err(3));
1075+
assert_eq!(i.advance_back_by(usize::MAX), usize::MAX - 3);
10751076

1076-
assert_eq!(i.advance_by(usize::MAX), Err(0));
1077+
assert_eq!(i.advance_by(usize::MAX), usize::MAX);
10771078

1078-
i.advance_by(0).unwrap();
1079-
i.advance_back_by(0).unwrap();
1079+
assert_eq!(i.advance_by(0), 0);
1080+
assert_eq!(i.advance_back_by(0), 0);
10801081

10811082
assert_eq!(i.len(), 0);
10821083
}
@@ -1124,7 +1125,7 @@ fn test_into_iter_zst() {
11241125
for _ in vec![C; 5].into_iter().rev() {}
11251126

11261127
let mut it = vec![C, C].into_iter();
1127-
it.advance_by(1).unwrap();
1128+
assert_eq!(it.advance_by(1), 0);
11281129
drop(it);
11291130

11301131
let mut it = vec![C, C].into_iter();

library/core/src/array/iter.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,20 +284,19 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
284284
self.next_back()
285285
}
286286

287-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
288-
let original_len = self.len();
289-
287+
fn advance_by(&mut self, n: usize) -> usize {
290288
// This also moves the start, which marks them as conceptually "dropped",
291289
// so if anything goes bad then our drop impl won't double-free them.
292290
let range_to_drop = self.alive.take_prefix(n);
291+
let remaining = n - range_to_drop.len();
293292

294293
// SAFETY: These elements are currently initialized, so it's fine to drop them.
295294
unsafe {
296295
let slice = self.data.get_unchecked_mut(range_to_drop);
297296
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
298297
}
299298

300-
if n > original_len { Err(original_len) } else { Ok(()) }
299+
remaining
301300
}
302301
}
303302

@@ -334,20 +333,19 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
334333
})
335334
}
336335

337-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
338-
let original_len = self.len();
339-
336+
fn advance_back_by(&mut self, n: usize) -> usize {
340337
// This also moves the end, which marks them as conceptually "dropped",
341338
// so if anything goes bad then our drop impl won't double-free them.
342339
let range_to_drop = self.alive.take_suffix(n);
340+
let remaining = n - range_to_drop.len();
343341

344342
// SAFETY: These elements are currently initialized, so it's fine to drop them.
345343
unsafe {
346344
let slice = self.data.get_unchecked_mut(range_to_drop);
347345
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
348346
}
349347

350-
if n > original_len { Err(original_len) } else { Ok(()) }
348+
remaining
351349
}
352350
}
353351

library/core/src/iter/adapters/by_ref_sized.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
2626
}
2727

2828
#[inline]
29-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
29+
fn advance_by(&mut self, n: usize) -> usize {
3030
I::advance_by(self.0, n)
3131
}
3232

@@ -62,7 +62,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
6262
}
6363

6464
#[inline]
65-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
65+
fn advance_back_by(&mut self, n: usize) -> usize {
6666
I::advance_back_by(self.0, n)
6767
}
6868

library/core/src/iter/adapters/chain.rs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -95,38 +95,33 @@ where
9595
}
9696

9797
#[inline]
98-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
99-
let mut rem = n;
100-
98+
fn advance_by(&mut self, mut n: usize) -> usize {
10199
if let Some(ref mut a) = self.a {
102-
match a.advance_by(rem) {
103-
Ok(()) => return Ok(()),
104-
Err(k) => rem -= k,
100+
n = a.advance_by(n);
101+
if n == 0 {
102+
return n;
105103
}
106104
self.a = None;
107105
}
108106

109107
if let Some(ref mut b) = self.b {
110-
match b.advance_by(rem) {
111-
Ok(()) => return Ok(()),
112-
Err(k) => rem -= k,
113-
}
108+
n = b.advance_by(n);
114109
// we don't fuse the second iterator
115110
}
116111

117-
if rem == 0 { Ok(()) } else { Err(n - rem) }
112+
n
118113
}
119114

120115
#[inline]
121116
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
122117
if let Some(ref mut a) = self.a {
123-
match a.advance_by(n) {
124-
Ok(()) => match a.next() {
125-
None => n = 0,
118+
n = match a.advance_by(n) {
119+
0 => match a.next() {
120+
None => 0,
126121
x => return x,
127122
},
128-
Err(k) => n -= k,
129-
}
123+
k => k,
124+
};
130125

131126
self.a = None;
132127
}
@@ -186,38 +181,33 @@ where
186181
}
187182

188183
#[inline]
189-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
190-
let mut rem = n;
191-
184+
fn advance_back_by(&mut self, mut n: usize) -> usize {
192185
if let Some(ref mut b) = self.b {
193-
match b.advance_back_by(rem) {
194-
Ok(()) => return Ok(()),
195-
Err(k) => rem -= k,
186+
n = b.advance_back_by(n);
187+
if n == 0 {
188+
return n;
196189
}
197190
self.b = None;
198191
}
199192

200193
if let Some(ref mut a) = self.a {
201-
match a.advance_back_by(rem) {
202-
Ok(()) => return Ok(()),
203-
Err(k) => rem -= k,
204-
}
194+
n = a.advance_back_by(n);
205195
// we don't fuse the second iterator
206196
}
207197

208-
if rem == 0 { Ok(()) } else { Err(n - rem) }
198+
n
209199
}
210200

211201
#[inline]
212202
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
213203
if let Some(ref mut b) = self.b {
214-
match b.advance_back_by(n) {
215-
Ok(()) => match b.next_back() {
216-
None => n = 0,
204+
n = match b.advance_back_by(n) {
205+
0 => match b.next_back() {
206+
None => 0,
217207
x => return x,
218208
},
219-
Err(k) => n -= k,
220-
}
209+
k => k,
210+
};
221211

222212
self.b = None;
223213
}

library/core/src/iter/adapters/copied.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ where
8989
}
9090

9191
#[inline]
92-
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
92+
fn advance_by(&mut self, n: usize) -> usize {
9393
self.it.advance_by(n)
9494
}
9595

@@ -130,7 +130,7 @@ where
130130
}
131131

132132
#[inline]
133-
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
133+
fn advance_back_by(&mut self, n: usize) -> usize {
134134
self.it.advance_back_by(n)
135135
}
136136
}

0 commit comments

Comments
 (0)