about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-05-06 16:55:04 +0200
committerNikita Popov <nikita.ppv@gmail.com>2018-05-06 16:55:40 +0200
commit9f8f366eeabee6273abf3628bb75ecd3b4b57f22 (patch)
tree62ff11799111acb1f37e308647a694538a22b7dd /src/liballoc
parent6f721f54c6fb1de9cf00eb9d2d050f818c882871 (diff)
downloadrust-9f8f366eeabee6273abf3628bb75ecd3b4b57f22.tar.gz
rust-9f8f366eeabee6273abf3628bb75ecd3b4b57f22.zip
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.
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);
         }
     }
 }