diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 74bcac2b5414d..8c2f52172ee70 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1881,7 +1881,18 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - self.truncate(0) + let elems: *mut [T] = self.as_mut_slice(); + + // SAFETY: + // - `elems` comes directly from `as_mut_slice` and is therefore valid. + // - Setting `self.len` before calling `drop_in_place` means that, + // if an element's `Drop` impl panics, the vector's `Drop` impl will + // do nothing (leaking the rest of the elements) instead of dropping + // some twice. + unsafe { + self.len = 0; + ptr::drop_in_place(elems); + } } /// Returns the number of elements in the vector, also referred to diff --git a/src/test/codegen/vec-clear.rs b/src/test/codegen/vec-clear.rs deleted file mode 100644 index 15bfe421e9d35..0000000000000 --- a/src/test/codegen/vec-clear.rs +++ /dev/null @@ -1,11 +0,0 @@ -// compile-flags: -O - -#![crate_type = "lib"] - -// CHECK-LABEL: @vec_clear -#[no_mangle] -pub fn vec_clear(x: &mut Vec) { - // CHECK-NOT: load - // CHECK-NOT: icmp - x.clear() -}