Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTreeMap: tag internal functions with preconditions as unsafe #68418

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 42 additions & 40 deletions src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {

let mut in_edge = leaf.first_edge();
while let Ok(kv) = in_edge.right_kv() {
let (k, v) = kv.into_kv();
let (k, v) = unsafe { kv.into_kv() };
in_edge = kv.right_edge();

out_node.push(k.clone(), v.clone());
unsafe { out_node.push(k.clone(), v.clone()) };
out_tree.length += 1;
}
}
Expand All @@ -170,10 +170,10 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
let mut out_tree = clone_subtree(internal.first_edge().descend());

{
let mut out_node = out_tree.root.push_level();
let mut out_node = unsafe { out_tree.root.push_level() };
let mut in_edge = internal.first_edge();
while let Ok(kv) = in_edge.right_kv() {
let (k, v) = kv.into_kv();
let (k, v) = unsafe { kv.into_kv() };
in_edge = kv.right_edge();

let k = (*k).clone();
Expand All @@ -189,7 +189,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
(root, length)
};

out_node.push(k, v, subroot);
unsafe { out_node.push(k, v, subroot) };
out_tree.length += 1 + sublength;
}
}
Expand Down Expand Up @@ -218,7 +218,7 @@ where

fn get(&self, key: &Q) -> Option<&K> {
match search::search_tree(self.root.as_ref(), key) {
Found(handle) => Some(handle.into_kv().0),
Found(handle) => Some(unsafe { handle.into_kv().0 }),
GoDown(_) => None,
}
}
Expand All @@ -237,7 +237,7 @@ where
fn replace(&mut self, key: K) -> Option<K> {
self.ensure_root_is_owned();
match search::search_tree::<marker::Mut<'_>, K, (), K>(self.root.as_mut(), &key) {
Found(handle) => Some(mem::replace(handle.into_kv_mut().0, key)),
Found(handle) => Some(mem::replace(unsafe { handle.into_kv_mut().0 }, key)),
GoDown(handle) => {
VacantEntry { key, handle, length: &mut self.length, _marker: PhantomData }
.insert(());
Expand Down Expand Up @@ -536,7 +536,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
Q: Ord,
{
match search::search_tree(self.root.as_ref(), key) {
Found(handle) => Some(handle.into_kv().1),
Found(handle) => Some(unsafe { handle.into_kv().1 }),
GoDown(_) => None,
}
}
Expand All @@ -563,7 +563,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
Q: Ord,
{
match search::search_tree(self.root.as_ref(), k) {
Found(handle) => Some(handle.into_kv()),
Found(handle) => Some(unsafe { handle.into_kv() }),
GoDown(_) => None,
}
}
Expand Down Expand Up @@ -592,7 +592,8 @@ impl<K: Ord, V> BTreeMap<K, V> {
K: Borrow<T>,
{
let front = first_leaf_edge(self.root.as_ref());
front.right_kv().ok().map(Handle::into_kv)
let handle = front.right_kv().ok()?;
Some(unsafe { handle.into_kv() })
}

/// Returns the first entry in the map for in-place manipulation.
Expand Down Expand Up @@ -623,7 +624,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
match self.length {
0 => None,
_ => Some(OccupiedEntry {
handle: self.root.as_mut().first_kv(),
handle: unsafe { self.root.as_mut().first_kv() },
length: &mut self.length,
_marker: PhantomData,
}),
Expand Down Expand Up @@ -653,7 +654,8 @@ impl<K: Ord, V> BTreeMap<K, V> {
K: Borrow<T>,
{
let back = last_leaf_edge(self.root.as_ref());
back.left_kv().ok().map(Handle::into_kv)
let handle = back.left_kv().ok()?;
unsafe { Some(handle.into_kv()) }
}

/// Returns the last entry in the map for in-place manipulation.
Expand Down Expand Up @@ -684,7 +686,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
match self.length {
0 => None,
_ => Some(OccupiedEntry {
handle: self.root.as_mut().last_kv(),
handle: unsafe { self.root.as_mut().last_kv() },
length: &mut self.length,
_marker: PhantomData,
}),
Expand Down Expand Up @@ -744,7 +746,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
Q: Ord,
{
match search::search_tree(self.root.as_mut(), key) {
Found(handle) => Some(handle.into_kv_mut().1),
Found(handle) => Some(unsafe { handle.into_kv_mut().1 }),
GoDown(_) => None,
}
}
Expand Down Expand Up @@ -995,7 +997,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
for (key, value) in iter {
// Try to push key-value pair into the current leaf node.
if cur_node.len() < node::CAPACITY {
cur_node.push(key, value);
unsafe { cur_node.push(key, value) };
} else {
// No space left, go up and push there.
let mut open_node;
Expand All @@ -1015,7 +1017,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
}
Err(node) => {
// We are at the top, create a new root node and push there.
open_node = node.into_root_mut().push_level();
open_node = unsafe { node.into_root_mut().push_level() };
break;
}
}
Expand All @@ -1025,9 +1027,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
let tree_height = open_node.height() - 1;
let mut right_tree = node::Root::new_leaf();
for _ in 0..tree_height {
right_tree.push_level();
unsafe { right_tree.push_level() };
}
open_node.push(key, value, right_tree);
unsafe { open_node.push(key, value, right_tree) };

// Go down to the right-most leaf again.
cur_node = last_leaf_edge(open_node.forget_type()).into_node();
Expand All @@ -1050,7 +1052,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
Ok(left) => left,
Err(_) => unreachable!(),
};
last_kv.bulk_steal_left(node::MIN_LEN - right_child_len);
unsafe { last_kv.bulk_steal_left(node::MIN_LEN - right_child_len) };
last_edge = last_kv.right_edge();
}

Expand Down Expand Up @@ -1102,7 +1104,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
let mut right = Self::new();
right.root = node::Root::new_leaf();
for _ in 0..(self.root.as_ref().height()) {
right.root.push_level();
unsafe { right.root.push_level() };
}

{
Expand All @@ -1116,7 +1118,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
GoDown(handle) => handle,
};

split_edge.move_suffix(&mut right_node);
unsafe { split_edge.move_suffix(&mut right_node) };

match (split_edge.force(), right_node.force()) {
(Internal(edge), Internal(node)) => {
Expand Down Expand Up @@ -1186,7 +1188,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
break;
}
}
self.root.pop_level();
unsafe { self.root.pop_level() };
}
}

Expand All @@ -1197,15 +1199,15 @@ impl<K: Ord, V> BTreeMap<K, V> {
let mut cur_node = self.root.as_mut();

while let Internal(node) = cur_node.force() {
let mut last_kv = node.last_kv();
let mut last_kv = unsafe { node.last_kv() };

if last_kv.can_merge() {
cur_node = last_kv.merge().descend();
cur_node = unsafe { last_kv.merge() }.descend();
} else {
let right_len = last_kv.reborrow().right_edge().descend().len();
// `MINLEN + 1` to avoid readjust if merge happens on the next level.
if right_len < node::MIN_LEN + 1 {
last_kv.bulk_steal_left(node::MIN_LEN + 1 - right_len);
unsafe { last_kv.bulk_steal_left(node::MIN_LEN + 1 - right_len) };
}
cur_node = last_kv.right_edge().descend();
}
Expand All @@ -1223,14 +1225,14 @@ impl<K: Ord, V> BTreeMap<K, V> {
let mut cur_node = self.root.as_mut();

while let Internal(node) = cur_node.force() {
let mut first_kv = node.first_kv();
let mut first_kv = unsafe { node.first_kv() };

if first_kv.can_merge() {
cur_node = first_kv.merge().descend();
cur_node = unsafe { first_kv.merge().descend() };
} else {
let left_len = first_kv.reborrow().left_edge().descend().len();
if left_len < node::MIN_LEN + 1 {
first_kv.bulk_steal_right(node::MIN_LEN + 1 - left_len);
unsafe { first_kv.bulk_steal_right(node::MIN_LEN + 1 - left_len) };
}
cur_node = first_kv.left_edge().descend();
}
Expand Down Expand Up @@ -2387,7 +2389,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
let mut ins_edge;

let mut cur_parent = match self.handle.insert(self.key, value) {
(Fit(handle), _) => return handle.into_kv_mut().1,
(Fit(handle), _) => return unsafe { handle.into_kv_mut().1 },
(Split(left, k, v, right), ptr) => {
ins_k = k;
ins_v = v;
Expand All @@ -2409,7 +2411,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
}
},
Err(root) => {
root.push_level().push(ins_k, ins_v, ins_edge);
unsafe { root.push_level().push(ins_k, ins_v, ins_edge) };
return unsafe { &mut *out_ptr };
}
}
Expand All @@ -2431,7 +2433,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// ```
#[stable(feature = "map_entry_keys", since = "1.10.0")]
pub fn key(&self) -> &K {
self.handle.reborrow().into_kv().0
unsafe { self.handle.reborrow().into_kv().0 }
}

/// Take ownership of the key and value from the map.
Expand Down Expand Up @@ -2475,7 +2477,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self) -> &V {
self.handle.reborrow().into_kv().1
unsafe { self.handle.reborrow().into_kv().1 }
}

/// Gets a mutable reference to the value in the entry.
Expand Down Expand Up @@ -2506,7 +2508,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut V {
self.handle.kv_mut().1
unsafe { self.handle.kv_mut().1 }
}

/// Converts the entry into a mutable reference to its value.
Expand All @@ -2532,7 +2534,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_mut(self) -> &'a mut V {
self.handle.into_kv_mut().1
unsafe { self.handle.into_kv_mut().1 }
}

/// Sets the value of the entry with the `OccupiedEntry`'s key,
Expand Down Expand Up @@ -2584,17 +2586,17 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {

let (small_leaf, old_key, old_val) = match self.handle.force() {
Leaf(leaf) => {
let (hole, old_key, old_val) = leaf.remove();
let (hole, old_key, old_val) = unsafe { leaf.remove() };
(hole.into_node(), old_key, old_val)
}
Internal(mut internal) => {
let key_loc = internal.kv_mut().0 as *mut K;
let val_loc = internal.kv_mut().1 as *mut V;
let key_loc = unsafe { internal.kv_mut().0 as *mut K };
let val_loc = unsafe { internal.kv_mut().1 as *mut V };

let to_remove = first_leaf_edge(internal.right_edge().descend()).right_kv().ok();
let to_remove = unsafe { unwrap_unchecked(to_remove) };

let (hole, key, val) = to_remove.remove();
let (hole, key, val) = unsafe { to_remove.remove() };

let old_key = unsafe { mem::replace(&mut *key_loc, key) };
let old_val = unsafe { mem::replace(&mut *val_loc, val) };
Expand All @@ -2612,7 +2614,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
Merged(parent) => {
if parent.len() == 0 {
// We must be at the root
parent.into_root_mut().pop_level();
unsafe { parent.into_root_mut().pop_level() };
break;
} else {
cur_node = parent.forget_type();
Expand Down Expand Up @@ -2653,7 +2655,7 @@ fn handle_underfull_node<K, V>(
};

if handle.can_merge() {
Merged(handle.merge().into_node())
Merged(unsafe { handle.merge() }.into_node())
} else {
if is_left {
handle.steal_left();
Expand Down
Loading