ByteNode::pjoin / join_into (dense_byte_node.rs ~2051 / ~2140) treat a None result from joining two CoFrees as unreachable!() — an unconditional panic, release builds included. A CoFree with neither value nor onward node is exactly how a dense node represents a dangling path after remove_branches(prune = false), and joining two of them at the same byte yields None.
let dangling_c = || { let mut m = PathMap::<()>::new();
for k in [b"ca".as_slice(), b"cb", b"d", b"e", b"f"] { m.set_val_at(k, ()); } // dense root
let mut wz = m.write_zipper(); wz.descend_to(b"c"); wz.remove_branches(false); drop(wz); m };
let _ = dangling_c().join(&dangling_c()); // panics: internal error: entered unreachable code
Fix: a byte dangling in both operands stays dangling in the result (write an empty CoFree; identity for both sides). The same patch also routes CoFree::join_into through TrieNodeODRc::join_into, which was the one remaining make_mut on a possibly-sentinel child.
ByteNode::pjoin / join_into (dense_byte_node.rs ~2051 / ~2140)treat a None result from joining two CoFrees as unreachable!() — an unconditional panic, release builds included. A CoFree with neither value nor onward node is exactly how a dense node represents a dangling path afterremove_branches(prune = false), and joining two of them at the same byte yields None.Fix: a byte dangling in both operands stays dangling in the result (write an empty CoFree; identity for both sides). The same patch also routes CoFree::join_into through TrieNodeODRc::join_into, which was the one remaining make_mut on a possibly-sentinel child.