1
Fork 0

Guarantee vec.clear/truncate is O(1) for trivial types

This commit is contained in:
Kornel 2019-09-11 11:46:53 +01:00
parent 74d5c70b17
commit 223600ac2c

View file

@ -685,21 +685,25 @@ impl<T> Vec<T> {
/// [`drain`]: #method.drain /// [`drain`]: #method.drain
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn truncate(&mut self, len: usize) { pub fn truncate(&mut self, len: usize) {
let current_len = self.len; if mem::needs_drop::<T>() {
unsafe { let current_len = self.len;
let mut ptr = self.as_mut_ptr().add(self.len); unsafe {
// Set the final length at the end, keeping in mind that let mut ptr = self.as_mut_ptr().add(self.len);
// dropping an element might panic. Works around a missed // Set the final length at the end, keeping in mind that
// optimization, as seen in the following issue: // dropping an element might panic. Works around a missed
// https://github.com/rust-lang/rust/issues/51802 // optimization, as seen in the following issue:
let mut local_len = SetLenOnDrop::new(&mut self.len); // https://github.com/rust-lang/rust/issues/51802
let mut local_len = SetLenOnDrop::new(&mut self.len);
// drop any extra elements // drop any extra elements
for _ in len..current_len { for _ in len..current_len {
local_len.decrement_len(1); local_len.decrement_len(1);
ptr = ptr.offset(-1); ptr = ptr.offset(-1);
ptr::drop_in_place(ptr); ptr::drop_in_place(ptr);
}
} }
} else if len <= self.len {
self.len = len;
} }
} }