From 7faa9ab637195c43d584a4a7834e34bdaa15ee8c Mon Sep 17 00:00:00 2001 From: Igor Malovitsa Date: Tue, 27 Oct 2026 16:25:39 +0000 Subject: [PATCH] Fix meet_into keeping its own focus value when the meet is the source's meet_into took any Identity from pmeet to mean its own value was the result. Identity(COUNTER_IDENT) means the source's value is, so a destination holding {1,2} met with a source holding {2} kept {1,2}. Integer values never return COUNTER_IDENT, which is why only the algebraic fuzzer's bitmask value type showed it. --- src/write_zipper.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/write_zipper.rs b/src/write_zipper.rs index bde799aa..51463647 100644 --- a/src/write_zipper.rs +++ b/src/write_zipper.rs @@ -2136,7 +2136,9 @@ impl <'a, 'path, V: Clone + Send + Sync + Unpin, A: Allocator + 'a> WriteZipperC let new_status = match self_val.pmeet(src_val) { AlgebraicResult::Element(new_val) => {self.set_val(new_val); AlgebraicStatus::Element }, AlgebraicResult::None => {self.remove_val(prune); AlgebraicStatus::None }, - AlgebraicResult::Identity(_) => { AlgebraicStatus::Identity } + AlgebraicResult::Identity(mask) if mask & SELF_IDENT > 0 => { AlgebraicStatus::Identity }, + //The meet is the source's value + AlgebraicResult::Identity(_) => { self.set_val(src_val.clone()); AlgebraicStatus::Element }, }; (new_status, false) }, @@ -8248,4 +8250,18 @@ mod tests { assert!(map.write_zipper_at_path(b"missing").fork_read_zipper().is_none()); assert!(map.into_write_zipper(b"missing").fork_read_zipper().is_none()); } + + /// `meet_into` must store the meet of the focus values even when it equals the source's value + /// (`pmeet` reports that as `Identity(COUNTER_IDENT)`) + #[test] + fn write_zipper_meet_into_focus_value_from_source() { + let mut dst = PathMap::::new(); + dst.set_val_at(b"", ByteMask::from_iter([1u8, 2])); + let mut src = PathMap::::new(); + src.set_val_at(b"", ByteMask::from_iter([2u8])); + let status = dst.write_zipper().meet_into(&src.read_zipper(), false); + assert_eq!(status, AlgebraicStatus::Element); + assert_eq!(dst.val_at(b""), Some(&ByteMask::from_iter([2u8]))); + assert_eq!(dst.val_at(b""), src.meet(&dst).val_at(b"")); + } }