Skip to content

Commit a0925fb

Browse files
committed
Auto merge of #76790 - ssomers:btree_slice_slasher_returns, r=Mark-Simulacrum
BTreeMap: avoid slices even more Epilogue to #73971: it seems the compiler is unable to realize that creating a slice and `get_unchecked`-ing one element is a simple fetch. So try to spell it out for the only remaining but often invoked case. Also, the previous code doesn't seem fair game to me, using `get_unchecked` to reach beyond the end of a slice. Although the local function `slice_insert` also does that. r? `@Mark-Simulacrum`
2 parents f3c923a + 378b643 commit a0925fb

File tree

1 file changed

+29
-16
lines changed
  • library/alloc/src/collections/btree

1 file changed

+29
-16
lines changed

library/alloc/src/collections/btree/node.rs

+29-16
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,22 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
465465
unsafe { &mut (*self.node.as_ptr()) }
466466
}
467467

468+
/// Borrows a mutable reference to one of the keys stored in the node.
469+
///
470+
/// # Safety
471+
/// The node has more than `idx` initialized elements.
472+
pub unsafe fn key_mut_at(&mut self, idx: usize) -> &mut K {
473+
unsafe { self.reborrow_mut().into_key_mut_at(idx) }
474+
}
475+
476+
/// Borrows a mutable reference to one of the values stored in the node.
477+
///
478+
/// # Safety
479+
/// The node has more than `idx` initialized elements.
480+
pub unsafe fn val_mut_at(&mut self, idx: usize) -> &mut V {
481+
unsafe { self.reborrow_mut().into_val_mut_at(idx) }
482+
}
483+
468484
fn keys_mut(&mut self) -> &mut [K] {
469485
// SAFETY: the caller will not be able to call further methods on self
470486
// until the key slice reference is dropped, as we have unique access
@@ -555,15 +571,14 @@ impl<'a, K, V, Type> NodeRef<marker::ValMut<'a>, K, V, Type> {
555571
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
556572
/// Adds a key/value pair to the end of the node.
557573
pub fn push(&mut self, key: K, val: V) {
558-
assert!(self.len() < CAPACITY);
559-
560-
let idx = self.len();
561-
574+
let len = &mut self.as_leaf_mut().len;
575+
let idx = *len as usize;
576+
assert!(idx < CAPACITY);
577+
*len += 1;
562578
unsafe {
563-
ptr::write(self.keys_mut().get_unchecked_mut(idx), key);
564-
ptr::write(self.vals_mut().get_unchecked_mut(idx), val);
579+
ptr::write(self.key_mut_at(idx), key);
580+
ptr::write(self.val_mut_at(idx), val);
565581
}
566-
self.as_leaf_mut().len += 1;
567582
}
568583

569584
/// Adds a key/value pair to the beginning of the node.
@@ -600,17 +615,15 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
600615
/// the end of the node.
601616
pub fn push(&mut self, key: K, val: V, edge: Root<K, V>) {
602617
assert!(edge.height == self.height - 1);
603-
assert!(self.len() < CAPACITY);
604-
605-
let idx = self.len();
606618

619+
let len = &mut self.as_leaf_mut().len;
620+
let idx = *len as usize;
621+
assert!(idx < CAPACITY);
622+
*len += 1;
607623
unsafe {
608-
ptr::write(self.keys_mut().get_unchecked_mut(idx), key);
609-
ptr::write(self.vals_mut().get_unchecked_mut(idx), val);
624+
ptr::write(self.key_mut_at(idx), key);
625+
ptr::write(self.val_mut_at(idx), val);
610626
self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node);
611-
612-
self.as_leaf_mut().len += 1;
613-
614627
Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link();
615628
}
616629
}
@@ -903,7 +916,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
903916
/// The returned pointer points to the inserted value.
904917
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
905918
self.leafy_insert_fit(key, val);
906-
unsafe { self.node.vals_mut().get_unchecked_mut(self.idx) }
919+
unsafe { self.node.val_mut_at(self.idx) }
907920
}
908921
}
909922

0 commit comments

Comments
 (0)