From 39ee1174b0d63011cfb55deb1d0e3c50f2f7454e Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 28 Jan 2019 15:55:56 +0100 Subject: [PATCH] Check whether vector value needs to be dropped in Vec#truncate Fixes #17633. --- src/liballoc/vec.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index ba3b3dfbfc2e1..4c1b507b80e14 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -687,20 +687,23 @@ impl Vec { #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, len: usize) { let current_len = self.len; - unsafe { - let mut ptr = self.as_mut_ptr().add(self.len); - // Set the final length at the end, keeping in mind that - // dropping an element might panic. Works around a missed - // optimization, as seen in the following issue: - // https://github.com/rust-lang/rust/issues/51802 - let mut local_len = SetLenOnDrop::new(&mut self.len); - - // drop any extra elements - for _ in len..current_len { - local_len.decrement_len(1); - ptr = ptr.offset(-1); - ptr::drop_in_place(ptr); + if mem::needs_drop::() { + unsafe { + let mut ptr = self.as_mut_ptr().add(self.len); + // Set the final length at the end, keeping in mind that + // dropping an element might panic. Works around a missed + // optimization, as seen in the following issue: + // https://github.com/rust-lang/rust/issues/51802 + let mut local_len = SetLenOnDrop::new(&mut self.len); + // drop any extra elements + for _ in len..current_len { + local_len.decrement_len(1); + ptr = ptr.offset(-1); + ptr::drop_in_place(ptr); + } } + } else if current_len > len { + self.len = len; } }