about summary refs log tree commit diff
path: root/src/liballoc/collections
diff options
context:
space:
mode:
authorTrevor Spiteri <tspiteri@ieee.org>2020-04-04 14:24:26 +0200
committerTrevor Spiteri <tspiteri@ieee.org>2020-04-04 14:30:33 +0200
commit2b718e8d9ca6efdccf4d72647cb3d3101e15b7fa (patch)
tree35051115f6fd6fb728e25c6619456a03fed85e83 /src/liballoc/collections
parent1b521f57735663de9373679cf8c6502622036bf1 (diff)
downloadrust-2b718e8d9ca6efdccf4d72647cb3d3101e15b7fa.tar.gz
rust-2b718e8d9ca6efdccf4d72647cb3d3101e15b7fa.zip
use ManuallyDrop instead of forget inside collections
This commit changes some usage of mem::forget into mem::ManuallyDrop
in some Vec, VecDeque, BTreeMap and Box methods.

Before the commit, the generated IR for some of the methods was
longer, and even after optimization, some unwinding artifacts were
still present.
Diffstat (limited to 'src/liballoc/collections')
-rw-r--r--src/liballoc/collections/btree/map.rs16
-rw-r--r--src/liballoc/collections/vec_deque.rs11
2 files changed, 13 insertions, 14 deletions
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index bbeced1751d..36770ee416c 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -4,9 +4,10 @@ use core::fmt::Debug;
 use core::hash::{Hash, Hasher};
 use core::iter::{FromIterator, FusedIterator, Peekable};
 use core::marker::PhantomData;
+use core::mem::{self, ManuallyDrop};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, RangeBounds};
-use core::{fmt, mem, ptr};
+use core::{fmt, ptr};
 
 use super::node::{self, marker, ForceResult::*, Handle, InsertResult::*, NodeRef};
 use super::search::{self, SearchResult::*};
@@ -190,9 +191,9 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
                             // We can't destructure subtree directly
                             // because BTreeMap implements Drop
                             let (subroot, sublength) = unsafe {
+                                let subtree = ManuallyDrop::new(subtree);
                                 let root = ptr::read(&subtree.root);
                                 let length = subtree.length;
-                                mem::forget(subtree);
                                 (root, length)
                             };
 
@@ -1515,15 +1516,14 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
     type IntoIter = IntoIter<K, V>;
 
     fn into_iter(self) -> IntoIter<K, V> {
-        if self.root.is_none() {
-            mem::forget(self);
+        let me = ManuallyDrop::new(self);
+        if me.root.is_none() {
             return IntoIter { front: None, back: None, length: 0 };
         }
 
-        let root1 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
-        let root2 = unsafe { unwrap_unchecked(ptr::read(&self.root)).into_ref() };
-        let len = self.length;
-        mem::forget(self);
+        let root1 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
+        let root2 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
+        let len = me.length;
 
         IntoIter {
             front: Some(root1.first_leaf_edge()),
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 94532521a90..c17a37c7bae 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -12,7 +12,7 @@ use core::cmp::{self, Ordering};
 use core::fmt;
 use core::hash::{Hash, Hasher};
 use core::iter::{once, repeat_with, FromIterator, FusedIterator};
-use core::mem::{self, replace};
+use core::mem::{self, replace, ManuallyDrop};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, IndexMut, RangeBounds, Try};
 use core::ptr::{self, NonNull};
@@ -2898,12 +2898,12 @@ impl<T> From<Vec<T>> for VecDeque<T> {
     /// This avoids reallocating where possible, but the conditions for that are
     /// strict, and subject to change, and so shouldn't be relied upon unless the
     /// `Vec<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
-    fn from(mut other: Vec<T>) -> Self {
+    fn from(other: Vec<T>) -> Self {
         unsafe {
+            let mut other = ManuallyDrop::new(other);
             let other_buf = other.as_mut_ptr();
             let mut buf = RawVec::from_raw_parts(other_buf, other.capacity());
             let len = other.len();
-            mem::forget(other);
 
             // We need to extend the buf if it's not a power of two, too small
             // or doesn't have at least one free space
@@ -2955,6 +2955,7 @@ impl<T> From<VecDeque<T>> for Vec<T> {
         other.make_contiguous();
 
         unsafe {
+            let other = ManuallyDrop::new(other);
             let buf = other.buf.ptr();
             let len = other.len();
             let cap = other.cap();
@@ -2962,9 +2963,7 @@ impl<T> From<VecDeque<T>> for Vec<T> {
             if other.head != 0 {
                 ptr::copy(buf.add(other.tail), buf, len);
             }
-            let out = Vec::from_raw_parts(buf, len, cap);
-            mem::forget(other);
-            out
+            Vec::from_raw_parts(buf, len, cap)
         }
     }
 }