Skip to content

Fix: ProductZipper crashes - #135

Merged
luketpeterson merged 7 commits into
Adam-Vandervorst:masterfrom
imlvts:fix/product-zipper-factor-bookkeeping-root
Sep 25, 2026
Merged

luketpeterson merged 7 commits into
Adam-Vandervorst:masterfrom
imlvts:fix/product-zipper-factor-bookkeeping-root

Conversation

@imlvts

@imlvts imlvts commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Fix the default k-path walk looping forever at a leaf
With nothing below the base and no sibling, k_path_default_internal never
reached its exit and spun. It also let k = 0 step sideways from the base.
Stop when back at the base.

Fix ProductZipper factor bookkeeping at the root
A factor was entered below a primary path that doesn't exist, and a
sibling step at depth 0 dropped the factor record although the core
zipper can't leave the factor there. Later moves then saw factor roots
the zipper didn't know about, and is_shared unwrapped None.

A secondary factor's root isn't a child of the node above it, so the
core zipper's parent lookup unwrapped None. Ask the factor's TrieRef
instead.
With nothing below the base and no sibling, k_path_default_internal never
reached its exit and spun. It also let k = 0 step sideways from the base.
Stop when back at the base.
A factor was entered below a primary path that doesn't exist, and a
sibling step at depth 0 dropped the factor record although the core
zipper can't leave the factor there. Later moves then saw factor roots
the zipper didn't know about, and is_shared unwrapped None.
@imlvts
imlvts force-pushed the fix/product-zipper-factor-bookkeeping-root branch 3 times, most recently from 1b71605 to 2c47b5b Compare September 23, 2026 15:10
Comment thread src/product_zipper.rs
#[inline]
fn ensure_descend_next_factor(&mut self) {
if self.factor_paths.len() < self.secondaries.len() && self.z.child_count() == 0 {
if self.factor_paths.len() < self.secondaries.len() && self.z.child_count() == 0 && self.z.path_exists() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this used to be there, but it cost performance and it wasn't clear why this was needed.

@luketpeterson luketpeterson Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the does_not_enter_factor_at_nonexistent_path test to demonstrate why the check is needed. Hopefully cost of the check is minimal because it's only paid when stepping across factors.

Fixing to_next_sibling_byte and to_prev_sibling_byte on Generic and Dependent PZs when the zipper is at the root
Adding test to demonstrate the need for an exists check in the Concrete PZ when descending across factors
…rvative fix, but it leaves a lot of sharing on the table. This will be revisited in Adam-Vandervorst#136
@luketpeterson

Copy link
Copy Markdown
Collaborator

Ready to merge this. Ended up doing something conservative for is_shared & shared_node_id which is valid but leaves a lot of sharing on the table. Will be revisited in #136

Merging.

@luketpeterson
luketpeterson merged commit e4b167c into Adam-Vandervorst:master Sep 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants