diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index 17b4689e4a0ee..66bfaf9617d2a 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -130,6 +130,16 @@ fn full_range( } } +impl NodeRef { + /// Duplicates a NodeRef, even for a non-immutable borrow type. + /// # Safety + /// Never visit the same KV twice, and never end up with overlapping + /// value references. + unsafe fn fork(self) -> (Self, Self) { + unsafe { (ptr::read(&self), self) } + } +} + impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { /// Creates a pair of leaf edges delimiting a specified range in or underneath a node. /// @@ -180,10 +190,8 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> K: Borrow, R: RangeBounds, { - // We duplicate the root NodeRef here -- we will never visit the same KV - // twice, and never end up with overlapping value references. - let self2 = unsafe { ptr::read(&self) }; - range_search(self, self2, range) + let (self1, self2) = unsafe { self.fork() }; + range_search(self1, self2, range) } /// Splits a unique reference into a pair of leaf edges delimiting the full range of the tree. @@ -195,10 +203,8 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> Handle, K, V, marker::Leaf>, marker::Edge>, Handle, K, V, marker::Leaf>, marker::Edge>, ) { - // We duplicate the root NodeRef here -- we will never visit the same KV - // twice, and never end up with overlapping value references. - let self2 = unsafe { ptr::read(&self) }; - full_range(self, self2) + let (self1, self2) = unsafe { self.fork() }; + full_range(self1, self2) } } @@ -212,10 +218,8 @@ impl NodeRef { Handle, marker::Edge>, Handle, marker::Edge>, ) { - // We duplicate the root NodeRef here -- we will never access it in a way - // that overlaps references obtained from the root. - let self2 = unsafe { ptr::read(&self) }; - full_range(self, self2) + let (self1, self2) = unsafe { self.fork() }; + full_range(self1, self2) } }