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.
This commit is contained in:
Sosthène Guédon 2024-04-05 11:31:59 +02:00
parent 804fa58ee7
commit ec6700a96b
No known key found for this signature in database
GPG Key ID: 36DA48A4C827B354

View File

@ -15,12 +15,6 @@ pub trait VecDrop {
}
impl<T> VecDrop for [MaybeUninit<T>] {
unsafe fn drop_with_len(&mut self, _len: usize) {
// Case of a view, drop does nothing
}
}
impl<T, const N: usize> VecDrop for [MaybeUninit<T>; 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<T, const N: usize> VecDrop for [MaybeUninit<T>; N] {
}
}
impl<T, const N: usize> VecDrop for [MaybeUninit<T>; N] {
unsafe fn drop_with_len(&mut self, len: usize) {
VecDrop::drop_with_len(self.as_mut_slice(), len)
}
}
/// <div class="warn">This is private API and should not be used</div>
pub struct VecInner<B: ?Sized + VecDrop> {
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<Droppable, 2> = Vec::new();
let mut v: Box<VecView<Droppable>> = 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<Droppable, 2> = Vec::new();
let mut v: Box<VecView<Droppable>> = 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<i32, 4> = Vec::new();