Skip to content

Commit e29b27b

Browse files
committed
replace advance_by returning usize with Result<(), NonZeroUsize>
1 parent 69db91b commit e29b27b

File tree

31 files changed

+340
-271
lines changed

31 files changed

+340
-271
lines changed

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::iter::{FusedIterator, TrustedLen};
2+
use core::num::NonZeroUsize;
23
use core::{array, fmt, mem::MaybeUninit, ops::Try, ptr};
34

45
use crate::alloc::{Allocator, Global};
@@ -54,15 +55,16 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
5455
}
5556

5657
#[inline]
57-
fn advance_by(&mut self, n: usize) -> usize {
58-
if self.inner.len < n {
58+
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
59+
let rem = if self.inner.len < n {
5960
let len = self.inner.len;
6061
self.inner.clear();
6162
len - n
6263
} else {
6364
self.inner.drain(..n);
6465
0
65-
}
66+
};
67+
NonZeroUsize::new(rem).map_or(Ok(()), Err)
6668
}
6769

6870
#[inline]
@@ -182,15 +184,16 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
182184
}
183185

184186
#[inline]
185-
fn advance_back_by(&mut self, n: usize) -> usize {
187+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
186188
let len = self.inner.len;
187-
if len >= n {
189+
let rem = if len >= n {
188190
self.inner.truncate(len - n);
189191
0
190192
} else {
191193
self.inner.clear();
192194
n - len
193-
}
195+
};
196+
NonZeroUsize::new(rem).map_or(Ok(()), Err)
194197
}
195198

196199
fn try_rfold<B, F, R>(&mut self, mut init: B, mut f: F) -> R

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

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
2+
use core::num::NonZeroUsize;
23
use core::ops::Try;
34
use core::{fmt, mem, slice};
45

@@ -55,13 +56,15 @@ impl<'a, T> Iterator for Iter<'a, T> {
5556
}
5657
}
5758

58-
fn advance_by(&mut self, n: usize) -> usize {
59+
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
5960
let remaining = self.i1.advance_by(n);
60-
if remaining == 0 {
61-
return 0;
61+
match remaining {
62+
Ok(()) => return Ok(()),
63+
Err(n) => {
64+
mem::swap(&mut self.i1, &mut self.i2);
65+
self.i1.advance_by(n.get())
66+
}
6267
}
63-
mem::swap(&mut self.i1, &mut self.i2);
64-
self.i1.advance_by(remaining)
6568
}
6669

6770
#[inline]
@@ -125,13 +128,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
125128
}
126129
}
127130

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;
131+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
132+
match self.i2.advance_back_by(n) {
133+
Ok(()) => return Ok(()),
134+
Err(n) => {
135+
mem::swap(&mut self.i1, &mut self.i2);
136+
self.i2.advance_back_by(n.get())
137+
}
132138
}
133-
mem::swap(&mut self.i1, &mut self.i2);
134-
self.i2.advance_back_by(remaining)
135139
}
136140

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

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

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
2+
use core::num::NonZeroUsize;
23
use core::ops::Try;
34
use core::{fmt, mem, slice};
45

@@ -47,13 +48,14 @@ impl<'a, T> Iterator for IterMut<'a, T> {
4748
}
4849
}
4950

50-
fn advance_by(&mut self, n: usize) -> usize {
51-
let remaining = self.i1.advance_by(n);
52-
if remaining == 0 {
53-
return 0;
51+
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
52+
match self.i1.advance_by(n) {
53+
Ok(()) => return Ok(()),
54+
Err(remaining) => {
55+
mem::swap(&mut self.i1, &mut self.i2);
56+
self.i1.advance_by(remaining.get())
57+
}
5458
}
55-
mem::swap(&mut self.i1, &mut self.i2);
56-
self.i1.advance_by(remaining)
5759
}
5860

5961
#[inline]
@@ -117,13 +119,14 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
117119
}
118120
}
119121

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;
122+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
123+
match self.i2.advance_back_by(n) {
124+
Ok(()) => return Ok(()),
125+
Err(remaining) => {
126+
mem::swap(&mut self.i1, &mut self.i2);
127+
self.i2.advance_back_by(remaining.get())
128+
}
124129
}
125-
mem::swap(&mut self.i1, &mut self.i2);
126-
self.i2.advance_back_by(remaining)
127130
}
128131

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

library/alloc/src/vec/into_iter.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use core::iter::{
1111
};
1212
use core::marker::PhantomData;
1313
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
14+
use core::num::NonZeroUsize;
1415
#[cfg(not(no_global_oom_handling))]
1516
use core::ops::Deref;
1617
use core::ptr::{self, NonNull};
@@ -213,7 +214,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
213214
}
214215

215216
#[inline]
216-
fn advance_by(&mut self, n: usize) -> usize {
217+
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
217218
let step_size = self.len().min(n);
218219
let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
219220
if T::IS_ZST {
@@ -227,7 +228,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
227228
unsafe {
228229
ptr::drop_in_place(to_drop);
229230
}
230-
n - step_size
231+
NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
231232
}
232233

233234
#[inline]
@@ -310,7 +311,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
310311
}
311312

312313
#[inline]
313-
fn advance_back_by(&mut self, n: usize) -> usize {
314+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
314315
let step_size = self.len().min(n);
315316
if T::IS_ZST {
316317
// SAFETY: same as for advance_by()
@@ -324,7 +325,7 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
324325
unsafe {
325326
ptr::drop_in_place(to_drop);
326327
}
327-
n - step_size
328+
NonZeroUsize::new(n - step_size).map_or(Ok(()), Err)
328329
}
329330
}
330331

library/alloc/tests/vec.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use core::alloc::{Allocator, Layout};
22
use core::assert_eq;
33
use core::iter::IntoIterator;
4+
use core::num::NonZeroUsize;
45
use core::ptr::NonNull;
56
use std::alloc::System;
67
use std::assert_matches::assert_matches;
@@ -1064,20 +1065,20 @@ fn test_into_iter_leak() {
10641065
#[test]
10651066
fn test_into_iter_advance_by() {
10661067
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);
1068+
assert_eq!(i.advance_by(0), Ok(()));
1069+
assert_eq!(i.advance_back_by(0), Ok(()));
10691070
assert_eq!(i.as_slice(), [1, 2, 3, 4, 5]);
10701071

1071-
assert_eq!(i.advance_by(1), 0);
1072-
assert_eq!(i.advance_back_by(1), 0);
1072+
assert_eq!(i.advance_by(1), Ok(()));
1073+
assert_eq!(i.advance_back_by(1), Ok(()));
10731074
assert_eq!(i.as_slice(), [2, 3, 4]);
10741075

1075-
assert_eq!(i.advance_back_by(usize::MAX), usize::MAX - 3);
1076+
assert_eq!(i.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 3).unwrap()));
10761077

1077-
assert_eq!(i.advance_by(usize::MAX), usize::MAX);
1078+
assert_eq!(i.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap()));
10781079

1079-
assert_eq!(i.advance_by(0), 0);
1080-
assert_eq!(i.advance_back_by(0), 0);
1080+
assert_eq!(i.advance_by(0), Ok(()));
1081+
assert_eq!(i.advance_back_by(0), Ok(()));
10811082

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

11271128
let mut it = vec![C, C].into_iter();
1128-
assert_eq!(it.advance_by(1), 0);
1129+
assert_eq!(it.advance_by(1), Ok(()));
11291130
drop(it);
11301131

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

library/core/src/array/iter.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Defines the `IntoIter` owned iterator for arrays.
22
3+
use crate::num::NonZeroUsize;
34
use crate::{
45
fmt,
56
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
@@ -284,7 +285,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
284285
self.next_back()
285286
}
286287

287-
fn advance_by(&mut self, n: usize) -> usize {
288+
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
288289
// This also moves the start, which marks them as conceptually "dropped",
289290
// so if anything goes bad then our drop impl won't double-free them.
290291
let range_to_drop = self.alive.take_prefix(n);
@@ -296,7 +297,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
296297
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
297298
}
298299

299-
remaining
300+
NonZeroUsize::new(remaining).map_or(Ok(()), Err)
300301
}
301302
}
302303

@@ -333,7 +334,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
333334
})
334335
}
335336

336-
fn advance_back_by(&mut self, n: usize) -> usize {
337+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
337338
// This also moves the end, which marks them as conceptually "dropped",
338339
// so if anything goes bad then our drop impl won't double-free them.
339340
let range_to_drop = self.alive.take_suffix(n);
@@ -345,7 +346,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
345346
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
346347
}
347348

348-
remaining
349+
NonZeroUsize::new(remaining).map_or(Ok(()), Err)
349350
}
350351
}
351352

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::num::NonZeroUsize;
12
use crate::ops::{NeverShortCircuit, Try};
23

34
/// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics.
@@ -26,7 +27,7 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
2627
}
2728

2829
#[inline]
29-
fn advance_by(&mut self, n: usize) -> usize {
30+
fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
3031
I::advance_by(self.0, n)
3132
}
3233

@@ -62,7 +63,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
6263
}
6364

6465
#[inline]
65-
fn advance_back_by(&mut self, n: usize) -> usize {
66+
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
6667
I::advance_back_by(self.0, n)
6768
}
6869

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen};
2+
use crate::num::NonZeroUsize;
23
use crate::ops::Try;
34

45
/// An iterator that links two iterators together, in a chain.
@@ -95,32 +96,32 @@ where
9596
}
9697

9798
#[inline]
98-
fn advance_by(&mut self, mut n: usize) -> usize {
99+
fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
99100
if let Some(ref mut a) = self.a {
100-
n = a.advance_by(n);
101-
if n == 0 {
102-
return n;
103-
}
101+
n = match a.advance_by(n) {
102+
Ok(()) => return Ok(()),
103+
Err(k) => k.get(),
104+
};
104105
self.a = None;
105106
}
106107

107108
if let Some(ref mut b) = self.b {
108-
n = b.advance_by(n);
109+
return b.advance_by(n);
109110
// we don't fuse the second iterator
110111
}
111112

112-
n
113+
NonZeroUsize::new(n).map_or(Ok(()), Err)
113114
}
114115

115116
#[inline]
116117
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
117118
if let Some(ref mut a) = self.a {
118119
n = match a.advance_by(n) {
119-
0 => match a.next() {
120+
Ok(()) => match a.next() {
120121
None => 0,
121122
x => return x,
122123
},
123-
k => k,
124+
Err(k) => k.get(),
124125
};
125126

126127
self.a = None;
@@ -181,32 +182,32 @@ where
181182
}
182183

183184
#[inline]
184-
fn advance_back_by(&mut self, mut n: usize) -> usize {
185+
fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> {
185186
if let Some(ref mut b) = self.b {
186-
n = b.advance_back_by(n);
187-
if n == 0 {
188-
return n;
189-
}
187+
n = match b.advance_back_by(n) {
188+
Ok(()) => return Ok(()),
189+
Err(k) => k.get(),
190+
};
190191
self.b = None;
191192
}
192193

193194
if let Some(ref mut a) = self.a {
194-
n = a.advance_back_by(n);
195+
return a.advance_back_by(n);
195196
// we don't fuse the second iterator
196197
}
197198

198-
n
199+
NonZeroUsize::new(n).map_or(Ok(()), Err)
199200
}
200201

201202
#[inline]
202203
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
203204
if let Some(ref mut b) = self.b {
204205
n = match b.advance_back_by(n) {
205-
0 => match b.next_back() {
206+
Ok(()) => match b.next_back() {
206207
None => 0,
207208
x => return x,
208209
},
209-
k => k,
210+
Err(k) => k.get(),
210211
};
211212

212213
self.b = None;

0 commit comments

Comments
 (0)