diff --git a/src/map.rs b/src/map.rs index 1396a9a..49b59d6 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1020,15 +1020,11 @@ where // the new bin will also be a tree bin. if both the high // bin and the low bin are non-empty, we have to // allocate a new TreeBin. - Shared::boxed( - BinEntry::Tree(TreeBin::new( - // safety: we have just created `low` and its `next` - // nodes and have never shared them - unsafe { low.into_box() }, - guard, - )), - &self.collector, - ) + // safety: we have just created `low` and its `next` nodes using `Shared::boxed` + // and have never shared them + let low_bin = unsafe { BinEntry::Tree(TreeBin::new(low.as_ptr(), guard)) }; + + Shared::boxed(low_bin, &self.collector) } else { // if not, we can re-use the old bin here, since it will // be swapped for a Moved entry while we are still @@ -1048,15 +1044,12 @@ where unsafe { TreeBin::drop_tree_nodes(high, false, guard) }; high_linear } else if low_count != 0 { - Shared::boxed( - BinEntry::Tree(TreeBin::new( - // safety: we have just created `high` and its `next` - // nodes and have never shared them - unsafe { high.into_box() }, - guard, - )), - &self.collector, - ) + // safety: we have just created `high` and its `next` nodes using `Shared::boxed` + // and have never shared them + let high_bin = + unsafe { BinEntry::Tree(TreeBin::new(high.as_ptr(), guard)) }; + + Shared::boxed(high_bin, &self.collector) } else { reused_bin = true; // since we also don't use the created low nodes here, @@ -2793,18 +2786,11 @@ where tail = new_tree_node; e = e_deref.next.load(Ordering::SeqCst, guard); } - tab.store_bin( - index, - Shared::boxed( - BinEntry::Tree(TreeBin::new( - // safety: we have just created `head` and its `next` - // nodes and have never shared them - unsafe { head.into_box() }, - guard, - )), - &self.collector, - ), - ); + + // safety: we have just created `head` and its `next` nodes using `Shared::boxed` + // and have never shared them + let head_bin = unsafe { BinEntry::Tree(TreeBin::new(head.as_ptr(), guard)) }; + tab.store_bin(index, Shared::boxed(head_bin, &self.collector)); drop(lock); // make sure the old bin entries get dropped e = bin; diff --git a/src/node.rs b/src/node.rs index ca28aff..9665eb1 100644 --- a/src/node.rs +++ b/src/node.rs @@ -241,9 +241,13 @@ where /// Constructs a new bin from the given nodes. /// /// Nodes are arranged into an ordered red-black tree. - pub(crate) fn new(bin: Box>>, guard: &Guard<'_>) -> Self { + /// + /// # Safety + /// + /// The `bin` pointer was created from a `Box` and never shared. + pub(crate) unsafe fn new(bin: *mut Linked>, guard: &Guard<'_>) -> Self { let mut root = Shared::null(); - let bin = Shared::from(Box::into_raw(bin)); + let bin = Shared::from(bin); // safety: We own the nodes for creating this new TreeBin, so they are // not shared with another thread and cannot get invalidated.