Skip to content

Commit 26f725b

Browse files
committed
Make RawTable::insert_no_grow unsafe
For performance reasons, this method _assumes_ that there is sufficient capacity for the new element, and it misbehaves otherwise, breaking invariants or even segfaulting. The necessary conditions could be checked, but if we're to keep it lean, it should be `unsafe`, so the burden is on the caller to ensure capacity. Fixes #253.
1 parent bbb5d3b commit 26f725b

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

src/raw/mod.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -872,19 +872,17 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
872872
/// This does not check if the given element already exists in the table.
873873
#[cfg_attr(feature = "inline-more", inline)]
874874
#[cfg(any(feature = "raw", feature = "rustc-internal-api"))]
875-
pub fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket<T> {
876-
unsafe {
877-
let (index, old_ctrl) = self.table.prepare_insert_slot(hash);
878-
let bucket = self.table.bucket(index);
875+
pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket<T> {
876+
let (index, old_ctrl) = self.table.prepare_insert_slot(hash);
877+
let bucket = self.table.bucket(index);
879878

880-
// If we are replacing a DELETED entry then we don't need to update
881-
// the load counter.
882-
self.table.growth_left -= special_is_empty(old_ctrl) as usize;
879+
// If we are replacing a DELETED entry then we don't need to update
880+
// the load counter.
881+
self.table.growth_left -= special_is_empty(old_ctrl) as usize;
883882

884-
bucket.write(value);
885-
self.table.items += 1;
886-
bucket
887-
}
883+
bucket.write(value);
884+
self.table.items += 1;
885+
bucket
888886
}
889887

890888
/// Temporary removes a bucket, applying the given function to the removed

src/rustc_entry.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,10 @@ impl<'a, K, V, A: Allocator + Clone> RustcVacantEntry<'a, K, V, A> {
574574
/// ```
575575
#[cfg_attr(feature = "inline-more", inline)]
576576
pub fn insert(self, value: V) -> &'a mut V {
577-
let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
578-
unsafe { &mut bucket.as_mut().1 }
577+
unsafe {
578+
let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
579+
&mut bucket.as_mut().1
580+
}
579581
}
580582

581583
/// Sets the value of the entry with the RustcVacantEntry's key,
@@ -596,7 +598,7 @@ impl<'a, K, V, A: Allocator + Clone> RustcVacantEntry<'a, K, V, A> {
596598
/// ```
597599
#[cfg_attr(feature = "inline-more", inline)]
598600
pub fn insert_entry(self, value: V) -> RustcOccupiedEntry<'a, K, V, A> {
599-
let bucket = self.table.insert_no_grow(self.hash, (self.key, value));
601+
let bucket = unsafe { self.table.insert_no_grow(self.hash, (self.key, value)) };
600602
RustcOccupiedEntry {
601603
key: None,
602604
elem: bucket,

0 commit comments

Comments
 (0)