Skip to content

Commit 243c5cc

Browse files
committed
Auto merge of rust-lang#133662 - paolobarbolini:vec-extend-with-via-repeatn, r=<try>
Use `iter::repeat_n` to implement `Vec::extend_with` This replaces the `Vec::extend_with` manual implementation, which is used by `Vec::resize` and `Vec` `SpecFromElem`, with `iter::repeat_n`. I've compared the codegen output between: 1. the current `Vec::resize` impl 2. this branch 3. this branch + rust-lang#130887 3 gives the closest codegen output to 1, with some output improvements. 2 doesn't look good: https://rust.godbolt.org/z/Yrc83EhjY. May also help rust-lang#120050?
2 parents 76f3ff6 + 4bf7072 commit 243c5cc

File tree

1 file changed

+1
-25
lines changed

1 file changed

+1
-25
lines changed

library/alloc/src/vec/mod.rs

+1-25
Original file line numberDiff line numberDiff line change
@@ -3112,31 +3112,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
31123112
#[track_caller]
31133113
/// Extend the vector by `n` clones of value.
31143114
fn extend_with(&mut self, n: usize, value: T) {
3115-
self.reserve(n);
3116-
3117-
unsafe {
3118-
let mut ptr = self.as_mut_ptr().add(self.len());
3119-
// Use SetLenOnDrop to work around bug where compiler
3120-
// might not realize the store through `ptr` through self.set_len()
3121-
// don't alias.
3122-
let mut local_len = SetLenOnDrop::new(&mut self.len);
3123-
3124-
// Write all elements except the last one
3125-
for _ in 1..n {
3126-
ptr::write(ptr, value.clone());
3127-
ptr = ptr.add(1);
3128-
// Increment the length in every step in case clone() panics
3129-
local_len.increment_len(1);
3130-
}
3131-
3132-
if n > 0 {
3133-
// We can write the last element directly without cloning needlessly
3134-
ptr::write(ptr, value);
3135-
local_len.increment_len(1);
3136-
}
3137-
3138-
// len set by scope guard
3139-
}
3115+
self.extend_trusted(iter::repeat_n(value, n));
31403116
}
31413117
}
31423118

0 commit comments

Comments
 (0)