Skip to content

Commit b60788e

Browse files
committed
slice iter: rm all overflowing_* and switch conditions to mv dependent code close
1 parent a7ee7c8 commit b60788e

File tree

1 file changed

+64
-72
lines changed

1 file changed

+64
-72
lines changed

library/core/src/slice/iter.rs

Lines changed: 64 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,15 +1601,15 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
16011601
#[inline]
16021602
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
16031603
let len = self.len();
1604-
if n >= len {
1605-
self.v = &self.v[..0]; // cheaper than &[]
1606-
None
1607-
} else {
1604+
if n < len {
16081605
let start = (len - 1 - n) * self.chunk_size;
16091606
let end = start + (self.v.len() - start).min(self.chunk_size);
16101607
let nth_back = &self.v[start..end];
16111608
self.v = &self.v[..start];
16121609
Some(nth_back)
1610+
} else {
1611+
self.v = &self.v[..0]; // cheaper than &[]
1612+
None
16131613
}
16141614
}
16151615
}
@@ -1770,10 +1770,7 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
17701770
#[inline]
17711771
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
17721772
let len = self.len();
1773-
if n >= len {
1774-
self.v = &mut [];
1775-
None
1776-
} else {
1773+
if n < len {
17771774
let start = (len - 1 - n) * self.chunk_size;
17781775
let end = match start.checked_add(self.chunk_size) {
17791776
Some(res) => cmp::min(self.v.len(), res),
@@ -1786,6 +1783,9 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
17861783
self.v = head;
17871784
// SAFETY: Nothing else points to or will point to the contents of this slice.
17881785
Some(unsafe { &mut *nth_back })
1786+
} else {
1787+
self.v = &mut [];
1788+
None
17891789
}
17901790
}
17911791
}
@@ -1952,15 +1952,15 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
19521952
#[inline]
19531953
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
19541954
let len = self.len();
1955-
if n >= len {
1956-
self.v = &self.v[..0]; // cheaper than &[]
1957-
None
1958-
} else {
1955+
if n < len {
19591956
let start = (len - 1 - n) * self.chunk_size;
19601957
let end = start + self.chunk_size;
19611958
let nth_back = &self.v[start..end];
19621959
self.v = &self.v[..start];
19631960
Some(nth_back)
1961+
} else {
1962+
self.v = &self.v[..0]; // cheaper than &[]
1963+
None
19641964
}
19651965
}
19661966
}
@@ -2111,10 +2111,7 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
21112111
#[inline]
21122112
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
21132113
let len = self.len();
2114-
if n >= len {
2115-
self.v = &mut [];
2116-
None
2117-
} else {
2114+
if n < len {
21182115
let start = (len - 1 - n) * self.chunk_size;
21192116
let end = start + self.chunk_size;
21202117
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
@@ -2124,6 +2121,9 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
21242121
self.v = head;
21252122
// SAFETY: Nothing else points to or will point to the contents of this slice.
21262123
Some(unsafe { &mut *nth_back })
2124+
} else {
2125+
self.v = &mut [];
2126+
None
21272127
}
21282128
}
21292129
}
@@ -2307,16 +2307,12 @@ impl<'a, T> Iterator for RChunks<'a, T> {
23072307
if self.v.is_empty() {
23082308
None
23092309
} else {
2310-
let len = self.v.len();
2311-
let chunksz = cmp::min(len, self.chunk_size);
2312-
// SAFETY: split_at_unchecked just requires the argument be less
2313-
// than the length. This could only happen if the expression `len -
2314-
// chunksz` overflows. This could only happen if `chunksz > len`,
2315-
// which is impossible as we initialize it as the `min` of `len` and
2316-
// `self.chunk_size`.
2317-
let (fst, snd) = unsafe { self.v.split_at_unchecked(len - chunksz) };
2318-
self.v = fst;
2319-
Some(snd)
2310+
let idx = self.v.len().saturating_sub(self.chunk_size);
2311+
// SAFETY: self.chunk_size() > 0, so 0 <= idx < self.v.len().
2312+
// Thus `idx` is in-bounds for `self.v` and can be used as a valid argument for `split_at_mut_unchecked`.
2313+
let (rest, chunk) = unsafe { self.v.split_at_unchecked(idx) };
2314+
self.v = rest;
2315+
Some(chunk)
23202316
}
23212317
}
23222318

@@ -2389,17 +2385,16 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
23892385
#[inline]
23902386
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
23912387
let len = self.len();
2392-
if n >= len {
2393-
self.v = &self.v[..0]; // cheaper than &[]
2394-
None
2395-
} else {
2396-
// can't underflow because `n < len`
2388+
if n < len {
23972389
let offset_from_end = (len - 1 - n) * self.chunk_size;
23982390
let end = self.v.len() - offset_from_end;
23992391
let start = end.saturating_sub(self.chunk_size);
24002392
let nth_back = &self.v[start..end];
24012393
self.v = &self.v[end..];
24022394
Some(nth_back)
2395+
} else {
2396+
self.v = &self.v[..0]; // cheaper than &[]
2397+
None
24032398
}
24042399
}
24052400
}
@@ -2471,17 +2466,13 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
24712466
if self.v.is_empty() {
24722467
None
24732468
} else {
2474-
let sz = cmp::min(self.v.len(), self.chunk_size);
2475-
let len = self.v.len();
2476-
// SAFETY: split_at_mut_unchecked just requires the argument be less
2477-
// than the length. This could only happen if the expression
2478-
// `len - sz` overflows. This could only happen if `sz >
2479-
// len`, which is impossible as we initialize it as the `min` of
2480-
// `self.v.len()` (e.g. `len`) and `self.chunk_size`.
2481-
let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
2482-
self.v = head;
2469+
let idx = self.v.len().saturating_sub(self.chunk_size);
2470+
// SAFETY: self.chunk_size() > 0, so 0 <= idx < self.v.len().
2471+
// Thus `idx` is in-bounds for `self.v` and can be used as a valid argument for `split_at_mut_unchecked`.
2472+
let (rest, chunk) = unsafe { self.v.split_at_mut_unchecked(idx) };
2473+
self.v = rest;
24832474
// SAFETY: Nothing else points to or will point to the contents of this slice.
2484-
Some(unsafe { &mut *tail })
2475+
Some(unsafe { &mut *chunk })
24852476
}
24862477
}
24872478

@@ -2502,12 +2493,9 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
25022493

25032494
#[inline]
25042495
fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2505-
let (end, overflow) = n.overflowing_mul(self.chunk_size);
2506-
if end >= self.v.len() || overflow {
2507-
self.v = &mut [];
2508-
None
2509-
} else {
2510-
// Can't underflow because of the check above
2496+
if let Some(end) = n.checked_mul(self.chunk_size)
2497+
&& end < self.v.len()
2498+
{
25112499
let end = self.v.len() - end;
25122500
let start = match end.checked_sub(self.chunk_size) {
25132501
Some(sum) => sum,
@@ -2522,6 +2510,9 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
25222510
self.v = head;
25232511
// SAFETY: Nothing else points to or will point to the contents of this slice.
25242512
Some(unsafe { &mut *nth })
2513+
} else {
2514+
self.v = &mut [];
2515+
None
25252516
}
25262517
}
25272518

@@ -2566,10 +2557,7 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
25662557
#[inline]
25672558
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
25682559
let len = self.len();
2569-
if n >= len {
2570-
self.v = &mut [];
2571-
None
2572-
} else {
2560+
if n < len {
25732561
// can't underflow because `n < len`
25742562
let offset_from_end = (len - 1 - n) * self.chunk_size;
25752563
let end = self.v.len() - offset_from_end;
@@ -2581,6 +2569,9 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
25812569
self.v = tail;
25822570
// SAFETY: Nothing else points to or will point to the contents of this slice.
25832571
Some(unsafe { &mut *nth_back })
2572+
} else {
2573+
self.v = &mut [];
2574+
None
25842575
}
25852576
}
25862577
}
@@ -2711,14 +2702,14 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
27112702

27122703
#[inline]
27132704
fn nth(&mut self, n: usize) -> Option<Self::Item> {
2714-
let (end, overflow) = n.overflowing_mul(self.chunk_size);
2715-
if end >= self.v.len() || overflow {
2705+
if let Some(end) = n.checked_mul(self.chunk_size)
2706+
&& end < self.v.len()
2707+
{
2708+
self.v = &self.v[..self.v.len() - end];
2709+
self.next()
2710+
} else {
27162711
self.v = &self.v[..0]; // cheaper than &[]
27172712
None
2718-
} else {
2719-
let (fst, _) = self.v.split_at(self.v.len() - end);
2720-
self.v = fst;
2721-
self.next()
27222713
}
27232714
}
27242715

@@ -2751,10 +2742,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
27512742
#[inline]
27522743
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
27532744
let len = self.len();
2754-
if n >= len {
2755-
self.v = &self.v[..0]; // cheaper than &[]
2756-
None
2757-
} else {
2745+
if n < len {
27582746
// now that we know that `n` corresponds to a chunk,
27592747
// none of these operations can underflow/overflow
27602748
let offset = (len - n) * self.chunk_size;
@@ -2763,6 +2751,9 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
27632751
let nth_back = &self.v[start..end];
27642752
self.v = &self.v[end..];
27652753
Some(nth_back)
2754+
} else {
2755+
self.v = &self.v[..0]; // cheaper than &[]
2756+
None
27662757
}
27672758
}
27682759
}
@@ -2875,16 +2866,17 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
28752866

28762867
#[inline]
28772868
fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2878-
let (end, overflow) = n.overflowing_mul(self.chunk_size);
2879-
if end >= self.v.len() || overflow {
2880-
self.v = &mut [];
2881-
None
2882-
} else {
2883-
let len = self.v.len();
2869+
if let Some(end) = n.checked_mul(self.chunk_size)
2870+
&& end < self.v.len()
2871+
{
2872+
let idx = self.v.len() - end;
28842873
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
2885-
let (fst, _) = unsafe { self.v.split_at_mut(len - end) };
2874+
let (fst, _) = unsafe { self.v.split_at_mut(idx) };
28862875
self.v = fst;
28872876
self.next()
2877+
} else {
2878+
self.v = &mut [];
2879+
None
28882880
}
28892881
}
28902882

@@ -2919,10 +2911,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
29192911
#[inline]
29202912
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
29212913
let len = self.len();
2922-
if n >= len {
2923-
self.v = &mut [];
2924-
None
2925-
} else {
2914+
if n < len {
29262915
// now that we know that `n` corresponds to a chunk,
29272916
// none of these operations can underflow/overflow
29282917
let offset = (len - n) * self.chunk_size;
@@ -2935,6 +2924,9 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
29352924
self.v = tail;
29362925
// SAFETY: Nothing else points to or will point to the contents of this slice.
29372926
Some(unsafe { &mut *nth_back })
2927+
} else {
2928+
self.v = &mut [];
2929+
None
29382930
}
29392931
}
29402932
}

0 commit comments

Comments
 (0)