Skip to content
Merged
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
7 changes: 6 additions & 1 deletion src/write_zipper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,10 @@ impl <'a, 'path, V: Clone + Send + Sync + Unpin, A: Allocator + 'a> WriteZipperC
/// Internal method to re-borrow a WriteZipperCore without the `'path` lifetime
fn as_static_path_zipper(&mut self) -> &mut WriteZipperCore<'a, 'static, V, A> {
self.prepare_buffers();
debug_assert!(!self.key.origin_path.is_slice() || self.key.origin_path.len() == 0);
debug_assert!(
!self.key.origin_path.is_slice() || self.key.origin_path.len() == 0,
"a prepared zipper must not retain a borrowed origin path"
);
unsafe{ &mut *(self as *mut WriteZipperCore<V, A>).cast() }
}

Expand Down Expand Up @@ -2784,6 +2787,8 @@ impl<'k> KeyFields<'k> {
self.prefix_buf.reserve(path_len.saturating_sub(self.prefix_buf.len()));
if was_unallocated {
self.prefix_buf.extend(unsafe{ self.origin_path.as_slice_unchecked() });
//The path now lives in `prefix_buf`; release the borrowed slice.
self.origin_path.make_len();
}
}
if self.prefix_idx.capacity() < stack_depth {
Expand Down
23 changes: 23 additions & 0 deletions src/zipper_head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,29 @@ mod tests {
assert_eq!(paths, vec![b"ax".to_vec(), b"bx".to_vec(), b"c".to_vec(), b"dx".to_vec()]);
}

/// A `ZipperHead` from a write zipper made with a borrowed path, and the zipper used afterwards
#[test]
fn zipper_head_from_write_zipper_at_borrowed_path() {
let mut map = PathMap::<u64>::new();
map.set_val_at(&[1u8, 2, 3], 7);
{
let path = [1u8, 2];
let mut wz = map.write_zipper_at_path(&path);
{
let zh = wz.zipper_head();
let mut child = zh.write_zipper_at_exclusive_path(&[4u8]).unwrap();
child.set_val(1);
}
assert_eq!(wz.origin_path(), &[1u8, 2]);
wz.descend_to(&[5u8]);
wz.set_val(2);
assert_eq!(wz.origin_path(), &[1u8, 2, 5]);
}
assert_eq!(map.val_at(&[1u8, 2, 4]), Some(&1));
assert_eq!(map.val_at(&[1u8, 2, 5]), Some(&2));
assert_eq!(map.val_at(&[1u8, 2, 3]), Some(&7));
}

/// An exclusive zipper at the head's own root, requested more than once, from a head whose
/// root sits partway into a node
#[test]
Expand Down