about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Hughes <j@distanthills.org>2022-03-14 06:55:36 -0400
committerJacob Hughes <j@distanthills.org>2022-06-14 13:54:10 -0400
commit417b20835d9409ecfc9aa62e25368a5c1040b7ee (patch)
tree33168f2cd7e28795700567edc80a24f26597125c
parentdc5951a6e5c64d9348a96e7c161d07b221b26dd2 (diff)
downloadrust-417b20835d9409ecfc9aa62e25368a5c1040b7ee.tar.gz
rust-417b20835d9409ecfc9aa62e25368a5c1040b7ee.zip
btreemap-alloc: fix clear impl
-rw-r--r--library/alloc/src/collections/btree/map.rs21
1 files changed, 6 insertions, 15 deletions
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index da2964aa5d7..95d9c3142dd 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -571,11 +571,12 @@ impl<K, V, A: Allocator> BTreeMap<K, V, A> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn clear(&mut self) {
-        let alloc = unsafe {
-            // drop all elements and retrieve allocator
-            ptr::read(self).into_iter().into_alloc()
-        };
-        *self = BTreeMap::new_in(alloc);
+        // avoid moving the allocator
+        mem::drop(BTreeMap {
+            root: mem::replace(&mut self.root, None),
+            length: mem::replace(&mut self.length, 0),
+            alloc: ManuallyDrop::new(&*self.alloc),
+        });
     }
 
     /// Makes a new empty BTreeMap with a reasonable choice for B.
@@ -1594,11 +1595,6 @@ impl<K, V, A: Allocator> IntoIterator for BTreeMap<K, V, A> {
 #[stable(feature = "btree_drop", since = "1.7.0")]
 impl<K, V, A: Allocator> Drop for IntoIter<K, V, A> {
     fn drop(&mut self) {
-        self.dealloc()
-    }
-}
-impl<K, V, A: Allocator> IntoIter<K, V, A> {
-    fn dealloc(&mut self) {
         struct DropGuard<'a, K, V, A: Allocator>(&'a mut IntoIter<K, V, A>);
 
         impl<'a, K, V, A: Allocator> Drop for DropGuard<'a, K, V, A> {
@@ -1649,11 +1645,6 @@ impl<K, V, A: Allocator> IntoIter<K, V, A> {
             Some(unsafe { self.range.deallocating_next_back_unchecked(&self.alloc) })
         }
     }
-    fn into_alloc(mut self) -> A {
-        self.dealloc(); // Deallocate, then don't drop as drop will also call dealloc
-        let iter = ManuallyDrop::new(self);
-        unsafe { ptr::read(&iter.alloc) }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]