Skip to content

Commit 5c39f5c

Browse files
committed
fix: BinaryHeap elements are dropped twice
1 parent 6877eed commit 5c39f5c

File tree

5 files changed

+67
-29
lines changed

5 files changed

+67
-29
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212
* Fixed `pool` example in docstring.
1313
* Fixed undefined behavior in `Vec::truncate()`, `Vec::swap_remove_unchecked()`,
1414
and `Hole::move_to()` (internal to the binary heap implementation).
15+
* Fixed `BinaryHeap` elements are being dropped twice
1516

1617
### Added
1718

src/binary_heap.rs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,6 @@ where
537537
}
538538
}
539539

540-
impl<T, K, const N: usize> Drop for BinaryHeap<T, K, N> {
541-
fn drop(&mut self) {
542-
unsafe { ptr::drop_in_place(self.data.as_mut_slice()) }
543-
}
544-
}
545-
546540
impl<T, K, const N: usize> fmt::Debug for BinaryHeap<T, K, N>
547541
where
548542
K: Kind,
@@ -577,6 +571,45 @@ mod tests {
577571
static mut _B: BinaryHeap<i32, Min, 16> = BinaryHeap::new();
578572
}
579573

574+
#[test]
575+
fn drop() {
576+
droppable!();
577+
578+
{
579+
let mut v: BinaryHeap<Droppable, Max, 2> = BinaryHeap::new();
580+
v.push(Droppable::new()).ok().unwrap();
581+
v.push(Droppable::new()).ok().unwrap();
582+
v.pop().unwrap();
583+
}
584+
585+
assert_eq!(unsafe { COUNT }, 0);
586+
587+
{
588+
let mut v: BinaryHeap<Droppable, Max, 2> = BinaryHeap::new();
589+
v.push(Droppable::new()).ok().unwrap();
590+
v.push(Droppable::new()).ok().unwrap();
591+
}
592+
593+
assert_eq!(unsafe { COUNT }, 0);
594+
595+
{
596+
let mut v: BinaryHeap<Droppable, Min, 2> = BinaryHeap::new();
597+
v.push(Droppable::new()).ok().unwrap();
598+
v.push(Droppable::new()).ok().unwrap();
599+
v.pop().unwrap();
600+
}
601+
602+
assert_eq!(unsafe { COUNT }, 0);
603+
604+
{
605+
let mut v: BinaryHeap<Droppable, Min, 2> = BinaryHeap::new();
606+
v.push(Droppable::new()).ok().unwrap();
607+
v.push(Droppable::new()).ok().unwrap();
608+
}
609+
610+
assert_eq!(unsafe { COUNT }, 0);
611+
}
612+
580613
#[test]
581614
fn min() {
582615
let mut heap = BinaryHeap::<_, Min, 16>::new();

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ pub use pool::singleton::arc::Arc;
8585
pub use string::String;
8686
pub use vec::Vec;
8787

88+
#[macro_use]
89+
#[cfg(test)]
90+
mod test_helpers;
91+
8892
mod deque;
8993
mod histbuf;
9094
mod indexmap;

src/test_helpers.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
macro_rules! droppable {
2+
() => {
3+
#[derive(Eq, Ord, PartialEq, PartialOrd)]
4+
struct Droppable(i32);
5+
impl Droppable {
6+
fn new() -> Self {
7+
unsafe {
8+
COUNT += 1;
9+
Droppable(COUNT)
10+
}
11+
}
12+
}
13+
impl Drop for Droppable {
14+
fn drop(&mut self) {
15+
unsafe {
16+
COUNT -= 1;
17+
}
18+
}
19+
}
20+
21+
static mut COUNT: i32 = 0;
22+
};
23+
}

src/vec.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -901,29 +901,6 @@ mod tests {
901901
assert!(v.is_full());
902902
}
903903

904-
macro_rules! droppable {
905-
() => {
906-
struct Droppable;
907-
impl Droppable {
908-
fn new() -> Self {
909-
unsafe {
910-
COUNT += 1;
911-
}
912-
Droppable
913-
}
914-
}
915-
impl Drop for Droppable {
916-
fn drop(&mut self) {
917-
unsafe {
918-
COUNT -= 1;
919-
}
920-
}
921-
}
922-
923-
static mut COUNT: i32 = 0;
924-
};
925-
}
926-
927904
#[test]
928905
fn drop() {
929906
droppable!();

0 commit comments

Comments
 (0)