From ec6700a96b22dab7b6a4693d3d8fcccf9f28c932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 5 Apr 2024 11:31:59 +0200 Subject: [PATCH] Fix memory leak on VecView drop Drop must also be implemented on `VecView` for the cases wher the `VecView` is owned even if it is `!Sized`. This can happen when it is boxed. --- src/vec.rs | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/vec.rs b/src/vec.rs index f7c3efbb66..bb972336bc 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -15,12 +15,6 @@ pub trait VecDrop { } impl VecDrop for [MaybeUninit] { - unsafe fn drop_with_len(&mut self, _len: usize) { - // Case of a view, drop does nothing - } -} - -impl VecDrop for [MaybeUninit; N] { unsafe fn drop_with_len(&mut self, len: usize) { // NOTE(unsafe) avoid bound checks in the slicing operation // &mut buffer[..len] @@ -31,6 +25,12 @@ impl VecDrop for [MaybeUninit; N] { } } +impl VecDrop for [MaybeUninit; N] { + unsafe fn drop_with_len(&mut self, len: usize) { + VecDrop::drop_with_len(self.as_mut_slice(), len) + } +} + ///
This is private API and should not be used
pub struct VecInner { len: usize, @@ -1953,7 +1953,7 @@ mod tests { use static_assertions::assert_not_impl_any; - use crate::Vec; + use super::{Vec, VecView}; // Ensure a `Vec` containing `!Send` values stays `!Send` itself. assert_not_impl_any!(Vec<*const (), 4>: Send); @@ -2014,6 +2014,33 @@ mod tests { assert_eq!(Droppable::count(), 0); } + #[test] + fn drop_vecview() { + droppable!(); + + { + let v: Vec = Vec::new(); + let mut v: Box> = Box::new(v); + v.push(Droppable::new()).ok().unwrap(); + v.push(Droppable::new()).ok().unwrap(); + assert_eq!(Droppable::count(), 2); + v.pop().unwrap(); + assert_eq!(Droppable::count(), 1); + } + + assert_eq!(Droppable::count(), 0); + + { + let v: Vec = Vec::new(); + let mut v: Box> = Box::new(v); + v.push(Droppable::new()).ok().unwrap(); + v.push(Droppable::new()).ok().unwrap(); + assert_eq!(Droppable::count(), 2); + } + + assert_eq!(Droppable::count(), 0); + } + #[test] fn eq() { let mut xs: Vec = Vec::new();