From 4bfb8d309754311f6b123c9f1b0946694b10d611 Mon Sep 17 00:00:00 2001 From: Igor Malovitsa Date: Thu, 17 Sep 2026 03:33:49 +0000 Subject: [PATCH] Fix get_trie_ref on a read zipper that owns its root ZipperHead read zippers own their root node, and get_trie_ref borrowed the root for the zipper's whole lifetime, which panics for an owned root. The TrieRef only needs to borrow the zipper. --- src/zipper.rs | 2 +- src/zipper_head.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/zipper.rs b/src/zipper.rs index fcede695..8e9289c8 100644 --- a/src/zipper.rs +++ b/src/zipper.rs @@ -1999,7 +1999,7 @@ pub(crate) mod read_zipper_core { PathMap::new_with_root_in(root_node, root_val, self.alloc.clone()) } fn get_trie_ref(&self) -> TrieRef<'_, V, A> { - TrieRefBorrowed::new_with_key_and_path_in(self.focus_parent_borrowed(), || self.val(), self.node_key(), b"", self.alloc.clone()).into() + TrieRefBorrowed::new_with_key_and_path_in(self.focus_parent(), || self.val(), self.node_key(), b"", self.alloc.clone()).into() } fn get_focus(&self) -> OpaqueAbstractNodeRef<'_, V, A> { self.get_focus_at([]) diff --git a/src/zipper_head.rs b/src/zipper_head.rs index cab1cfa9..dbab6a21 100644 --- a/src/zipper_head.rs +++ b/src/zipper_head.rs @@ -1515,4 +1515,26 @@ mod tests { paths.sort(); assert_eq!(paths, vec![b"ax".to_vec(), b"bx".to_vec(), b"c".to_vec(), b"dx".to_vec()]); } + + /// `get_trie_ref`, `get_focus` and forks from a head's read zipper, which owns its root node + #[test] + fn head_read_zipper_trie_refs() { + let mut map = PathMap::::new(); + for p in [&[1u8, 2, 1][..], &[1, 2, 1, 0], &[1, 3], &[0]] { map.set_val_at(p, 7); } + let zh = map.zipper_head(); + for path in [&[][..], &[1u8], &[1u8, 2], &[9u8]] { + let mut rz = zh.read_zipper_at_path(path).unwrap(); + for step in [&[][..], &[2u8], &[2u8, 1]] { + rz.reset(); + rz.descend_to(step); + let tr = rz.get_trie_ref(); + assert_eq!(tr.val(), rz.val(), "{path:?} {step:?}"); + assert_eq!(tr.child_mask(), rz.child_mask(), "{path:?} {step:?}"); + let _ = rz.get_focus(); + let fork = rz.fork_read_zipper(); + assert_eq!(fork.get_trie_ref().val(), rz.val(), "{path:?} {step:?}"); + assert_eq!(fork.trie_ref_at_path(&[0u8]).val(), rz.val_at(&[0u8]), "{path:?} {step:?}"); + } + } + } }