about summary refs log tree commit diff
diff options
context:
space:
mode:
authorC Jones <code@calebjones.net>2018-05-07 19:42:28 -0400
committerC Jones <code@calebjones.net>2018-05-07 22:14:34 -0400
commitf3a3599e090cb6aa63a327351738d7633c934728 (patch)
treee67ceaa2524f895251d81c2214e91210da948f38
parentddacf037fdc8bfb845bde2ce41ea4b9b6de445c7 (diff)
downloadrust-f3a3599e090cb6aa63a327351738d7633c934728.tar.gz
rust-f3a3599e090cb6aa63a327351738d7633c934728.zip
Add debug asserts and fix some violations
-rw-r--r--src/liballoc/btree/map.rs5
-rw-r--r--src/liballoc/btree/node.rs11
2 files changed, 16 insertions, 0 deletions
diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs
index a88631b1e67..7ed7fd204fd 100644
--- a/src/liballoc/btree/map.rs
+++ b/src/liballoc/btree/map.rs
@@ -246,6 +246,9 @@ impl<K, Q: ?Sized> super::Recover<Q> for BTreeMap<K, ()>
     }
 
     fn replace(&mut self, key: K) -> Option<K> {
+        if self.root.is_shared_root() {
+            self.root = node::Root::new_leaf();
+        }
         match search::search_tree::<marker::Mut, K, (), K>(self.root.as_mut(), &key) {
             Found(handle) => Some(mem::replace(handle.into_kv_mut().0, key)),
             GoDown(handle) => {
@@ -889,6 +892,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn entry(&mut self, key: K) -> Entry<K, V> {
+        // FIXME(@porglezomp) Avoid allocating if we don't insert
         if self.root.is_shared_root() {
             self.root = node::Root::new_leaf();
         }
@@ -1026,6 +1030,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
         let total_num = self.len();
 
         let mut right = Self::new();
+        right.root = node::Root::new_leaf();
         for _ in 0..(self.root.as_ref().height()) {
             right.root.push_level();
         }
diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs
index ce770d384f8..17eee65178e 100644
--- a/src/liballoc/btree/node.rs
+++ b/src/liballoc/btree/node.rs
@@ -195,6 +195,10 @@ impl<K, V> Root<K, V> {
     }
 
     pub fn shared_empty_root() -> Self {
+        // Ensuring that the shared node hasn't been corrupted by any mutations
+        debug_assert!(EMPTY_ROOT_NODE.parent == ptr::null());
+        debug_assert!(EMPTY_ROOT_NODE.parent_idx == 0);
+        debug_assert!(EMPTY_ROOT_NODE.len == 0);
         Root {
             node: unsafe {
                 BoxedNode::from_ptr(NonNull::new_unchecked(
@@ -246,6 +250,7 @@ impl<K, V> Root<K, V> {
     /// new node the root. This increases the height by 1 and is the opposite of `pop_level`.
     pub fn push_level(&mut self)
             -> NodeRef<marker::Mut, K, V, marker::Internal> {
+        debug_assert!(!self.is_shared_root());
         let mut new_node = Box::new(unsafe { InternalNode::new() });
         new_node.edges[0] = unsafe { BoxedNode::from_ptr(self.node.as_ptr()) };
 
@@ -474,6 +479,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
             marker::Edge
         >
     > {
+        debug_assert!(!self.is_shared_root());
         let node = self.node;
         let ret = self.ascend().ok();
         Global.dealloc(node.as_opaque(), Layout::new::<LeafNode<K, V>>());
@@ -631,6 +637,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
     pub fn push(&mut self, key: K, val: V) {
         // Necessary for correctness, but this is an internal module
         debug_assert!(self.len() < CAPACITY);
+        debug_assert!(!self.is_shared_root());
 
         let idx = self.len();
 
@@ -646,6 +653,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
     pub fn push_front(&mut self, key: K, val: V) {
         // Necessary for correctness, but this is an internal module
         debug_assert!(self.len() < CAPACITY);
+        debug_assert!(!self.is_shared_root());
 
         unsafe {
             slice_insert(self.keys_mut(), 0, key);
@@ -959,6 +967,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
     fn insert_fit(&mut self, key: K, val: V) -> *mut V {
         // Necessary for correctness, but in a private module
         debug_assert!(self.node.len() < CAPACITY);
+        debug_assert!(!self.node.is_shared_root());
 
         unsafe {
             slice_insert(self.node.keys_mut(), self.idx, key);
@@ -1136,6 +1145,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
     ///   allocated node.
     pub fn split(mut self)
             -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
+        debug_assert!(!self.node.is_shared_root());
         unsafe {
             let mut new_node = Box::new(LeafNode::new());
 
@@ -1173,6 +1183,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
     /// now adjacent key/value pairs to the left and right of this handle.
     pub fn remove(mut self)
             -> (Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>, K, V) {
+        debug_assert!(!self.node.is_shared_root());
         unsafe {
             let k = slice_remove(self.node.keys_mut(), self.idx);
             let v = slice_remove(self.node.vals_mut(), self.idx);