Skip to content

Commit 9f8f366

Browse files
committedMay 6, 2018
Use ManuallyDrop instead of Option in Hole implementation
The Option is always Some until drop, where it becomes None. Make this more explicit and avoid unwraps by using ManuallyDrop. This change should be performance-neutral as LLVM already optimizes the unwraps away in the inlined code.
1 parent 6f721f5 commit 9f8f366

File tree

1 file changed

+5
-6
lines changed

1 file changed

+5
-6
lines changed
 

‎src/liballoc/binary_heap.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
157157

158158
use core::ops::{Deref, DerefMut};
159159
use core::iter::{FromIterator, FusedIterator};
160-
use core::mem::{swap, size_of};
160+
use core::mem::{swap, size_of, ManuallyDrop};
161161
use core::ptr;
162162
use core::fmt;
163163

@@ -864,8 +864,7 @@ impl<T: Ord> BinaryHeap<T> {
864864
/// position with the value that was originally removed.
865865
struct Hole<'a, T: 'a> {
866866
data: &'a mut [T],
867-
/// `elt` is always `Some` from new until drop.
868-
elt: Option<T>,
867+
elt: ManuallyDrop<T>,
869868
pos: usize,
870869
}
871870

@@ -879,7 +878,7 @@ impl<'a, T> Hole<'a, T> {
879878
let elt = ptr::read(&data[pos]);
880879
Hole {
881880
data,
882-
elt: Some(elt),
881+
elt: ManuallyDrop::new(elt),
883882
pos,
884883
}
885884
}
@@ -892,7 +891,7 @@ impl<'a, T> Hole<'a, T> {
892891
/// Returns a reference to the element removed.
893892
#[inline]
894893
fn element(&self) -> &T {
895-
self.elt.as_ref().unwrap()
894+
&self.elt
896895
}
897896

898897
/// Returns a reference to the element at `index`.
@@ -925,7 +924,7 @@ impl<'a, T> Drop for Hole<'a, T> {
925924
// fill the hole again
926925
unsafe {
927926
let pos = self.pos;
928-
ptr::write(self.data.get_unchecked_mut(pos), self.elt.take().unwrap());
927+
ptr::copy_nonoverlapping(&*self.elt, self.data.get_unchecked_mut(pos), 1);
929928
}
930929
}
931930
}

0 commit comments

Comments
 (0)