mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-03 07:14:45 +00:00
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:
parent
804fa58ee7
commit
ec6700a96b
41
src/vec.rs
41
src/vec.rs
@ -15,12 +15,6 @@ pub trait VecDrop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> VecDrop for [MaybeUninit<T>] {
|
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) {
|
unsafe fn drop_with_len(&mut self, len: usize) {
|
||||||
// NOTE(unsafe) avoid bound checks in the slicing operation
|
// NOTE(unsafe) avoid bound checks in the slicing operation
|
||||||
// &mut buffer[..len]
|
// &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>
|
/// <div class="warn">This is private API and should not be used</div>
|
||||||
pub struct VecInner<B: ?Sized + VecDrop> {
|
pub struct VecInner<B: ?Sized + VecDrop> {
|
||||||
len: usize,
|
len: usize,
|
||||||
@ -1953,7 +1953,7 @@ mod tests {
|
|||||||
|
|
||||||
use static_assertions::assert_not_impl_any;
|
use static_assertions::assert_not_impl_any;
|
||||||
|
|
||||||
use crate::Vec;
|
use super::{Vec, VecView};
|
||||||
|
|
||||||
// Ensure a `Vec` containing `!Send` values stays `!Send` itself.
|
// Ensure a `Vec` containing `!Send` values stays `!Send` itself.
|
||||||
assert_not_impl_any!(Vec<*const (), 4>: Send);
|
assert_not_impl_any!(Vec<*const (), 4>: Send);
|
||||||
@ -2014,6 +2014,33 @@ mod tests {
|
|||||||
assert_eq!(Droppable::count(), 0);
|
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]
|
#[test]
|
||||||
fn eq() {
|
fn eq() {
|
||||||
let mut xs: Vec<i32, 4> = Vec::new();
|
let mut xs: Vec<i32, 4> = Vec::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user