Skip to content

Commit 6c32590

Browse files
committed
Override RepeatN::fold too
1 parent 8652062 commit 6c32590

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

library/alloc/src/vec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2887,7 +2887,7 @@ impl<T, A: Allocator> Vec<T, A> {
28872887
// Since the loop executes user code which can panic we have to update
28882888
// the length every step to correctly drop what we've written.
28892889
// NB can't overflow since we would have had to alloc the address space
2890-
local_len.increment_len(1);
2890+
local_len.increment_len_unchecked(1);
28912891
});
28922892
}
28932893
} else {

library/alloc/src/vec/set_len_on_drop.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ impl<'a> SetLenOnDrop<'a> {
1414
SetLenOnDrop { local_len: *len, len }
1515
}
1616

17+
/// # Safety
18+
/// `self.current_len() + increment` must not overflow.
1719
#[inline]
18-
pub(super) fn increment_len(&mut self, increment: usize) {
19-
self.local_len += increment;
20+
pub(super) unsafe fn increment_len_unchecked(&mut self, increment: usize) {
21+
// SAFETY: This is our precondition
22+
self.local_len = unsafe { self.local_len.unchecked_add(increment) };
2023
}
2124

2225
#[inline]

library/core/src/iter/sources/repeat_n.rs

+29
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl<A> Drop for RepeatN<A> {
112112

113113
trait SpecRepeatN<A> {
114114
unsafe fn spec_next_unchecked(&mut self) -> A;
115+
fn spec_fold<B, F: FnMut(B, A) -> B>(self, b: B, f: F) -> B;
115116
}
116117

117118
impl<A: Clone> SpecRepeatN<A> for RepeatN<A> {
@@ -126,6 +127,18 @@ impl<A: Clone> SpecRepeatN<A> for RepeatN<A> {
126127
A::clone(&self.element)
127128
}
128129
}
130+
131+
default fn spec_fold<B, F: FnMut(B, A) -> B>(mut self, mut b: B, mut f: F) -> B {
132+
let mut count = self.count;
133+
if let Some(element) = self.take_element() {
134+
while count > 1 {
135+
count -= 1;
136+
b = f(b, element.clone());
137+
}
138+
b = f(b, element);
139+
}
140+
b
141+
}
129142
}
130143

131144
impl<A: Copy> SpecRepeatN<A> for RepeatN<A> {
@@ -136,6 +149,17 @@ impl<A: Copy> SpecRepeatN<A> for RepeatN<A> {
136149
// so skip having a branch that would need to be optimized out.
137150
*self.element
138151
}
152+
153+
fn spec_fold<B, F: FnMut(B, A) -> B>(self, mut b: B, mut f: F) -> B {
154+
let mut count = self.count;
155+
let element = *self.element;
156+
157+
while count > 0 {
158+
count -= 1;
159+
b = f(b, element);
160+
}
161+
b
162+
}
139163
}
140164

141165
#[unstable(feature = "iter_repeat_n", issue = "104434")]
@@ -175,6 +199,11 @@ impl<A: Clone> Iterator for RepeatN<A> {
175199
}
176200
}
177201

202+
#[inline]
203+
fn fold<B, F: FnMut(B, A) -> B>(self, init: B, f: F) -> B {
204+
self.spec_fold(init, f)
205+
}
206+
178207
#[inline]
179208
fn last(mut self) -> Option<A> {
180209
self.take_element()

0 commit comments

Comments
 (0)