Skip to content

Commit 36f5141

Browse files
Use iter::repeat_n to implement Vec::extend_with
This replaces the manual `Vec::extend_with` implementation with `iter::repeat_n` and `Vec::extend_trusted`. This simplifies the code and gets LLVM to remove the special case for the last element when `T` is trivial to clone.
1 parent b4f1098 commit 36f5141

File tree

1 file changed

+3
-26
lines changed

1 file changed

+3
-26
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3445,34 +3445,11 @@ impl<T, A: Allocator, const N: usize> Vec<[T; N], A> {
34453445
}
34463446

34473447
impl<T: Clone, A: Allocator> Vec<T, A> {
3448-
#[cfg(not(no_global_oom_handling))]
34493448
/// Extend the vector by `n` clones of value.
3449+
#[cfg(not(no_global_oom_handling))]
3450+
#[inline]
34503451
fn extend_with(&mut self, n: usize, value: T) {
3451-
self.reserve(n);
3452-
3453-
unsafe {
3454-
let mut ptr = self.as_mut_ptr().add(self.len());
3455-
// Use SetLenOnDrop to work around bug where compiler
3456-
// might not realize the store through `ptr` through self.set_len()
3457-
// don't alias.
3458-
let mut local_len = SetLenOnDrop::new(&mut self.len);
3459-
3460-
// Write all elements except the last one
3461-
for _ in 1..n {
3462-
ptr::write(ptr, value.clone());
3463-
ptr = ptr.add(1);
3464-
// Increment the length in every step in case clone() panics
3465-
local_len.increment_len(1);
3466-
}
3467-
3468-
if n > 0 {
3469-
// We can write the last element directly without cloning needlessly
3470-
ptr::write(ptr, value);
3471-
local_len.increment_len(1);
3472-
}
3473-
3474-
// len set by scope guard
3475-
}
3452+
self.extend_trusted(iter::repeat_n(value, n));
34763453
}
34773454
}
34783455

0 commit comments

Comments
 (0)