about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-07 12:30:55 +0000
committerbors <bors@rust-lang.org>2018-05-07 12:30:55 +0000
commit62889702c9868682a3112a19c75321508d9eb6e6 (patch)
tree53e852b1e191e001a0c32f9c883583496187dc51 /src/liballoc
parentc88992d00169f15d8ff9edac8901245b4d21e1c1 (diff)
parent9f8f366eeabee6273abf3628bb75ecd3b4b57f22 (diff)
downloadrust-62889702c9868682a3112a19c75321508d9eb6e6.tar.gz
rust-62889702c9868682a3112a19c75321508d9eb6e6.zip
Auto merge of #50487 - nikic:heap-manually-drop, r=Gankro
Use ManuallyDrop instead of Option in BinaryHeap 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. However I've seen this pattern copied from here to other crates where it is not optimized away, so I think it would be good to change it.
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/binary_heap.rs11
1 files changed, 5 insertions, 6 deletions
diff --git a/src/liballoc/binary_heap.rs b/src/liballoc/binary_heap.rs
index 668b61c51d8..fcadcb544c4 100644
--- a/src/liballoc/binary_heap.rs
+++ b/src/liballoc/binary_heap.rs
@@ -157,7 +157,7 @@
 
 use core::ops::{Deref, DerefMut};
 use core::iter::{FromIterator, FusedIterator};
-use core::mem::{swap, size_of};
+use core::mem::{swap, size_of, ManuallyDrop};
 use core::ptr;
 use core::fmt;
 
@@ -864,8 +864,7 @@ impl<T: Ord> BinaryHeap<T> {
 /// position with the value that was originally removed.
 struct Hole<'a, T: 'a> {
     data: &'a mut [T],
-    /// `elt` is always `Some` from new until drop.
-    elt: Option<T>,
+    elt: ManuallyDrop<T>,
     pos: usize,
 }
 
@@ -879,7 +878,7 @@ impl<'a, T> Hole<'a, T> {
         let elt = ptr::read(&data[pos]);
         Hole {
             data,
-            elt: Some(elt),
+            elt: ManuallyDrop::new(elt),
             pos,
         }
     }
@@ -892,7 +891,7 @@ impl<'a, T> Hole<'a, T> {
     /// Returns a reference to the element removed.
     #[inline]
     fn element(&self) -> &T {
-        self.elt.as_ref().unwrap()
+        &self.elt
     }
 
     /// Returns a reference to the element at `index`.
@@ -925,7 +924,7 @@ impl<'a, T> Drop for Hole<'a, T> {
         // fill the hole again
         unsafe {
             let pos = self.pos;
-            ptr::write(self.data.get_unchecked_mut(pos), self.elt.take().unwrap());
+            ptr::copy_nonoverlapping(&*self.elt, self.data.get_unchecked_mut(pos), 1);
         }
     }
 }