From 0c143bae6ed1cffec6ff2459bba51eb5ea7665f9 Mon Sep 17 00:00:00 2001 From: Mat Strange Date: Fri, 23 Oct 2026 16:44:13 +0100 Subject: [PATCH] #4001: the part comparison lists every field of Part `same_content` destructures `Document` field by field, so a new field does not build until someone decides whether a change to it counts. `same_parts` did not do the same for `Part`: it compared the three fields it knew about by hand, so a new one would have been silently ignored, and a command that changed only it would have counted as a no-op. Same rule, same guarantee. --- crates/doc/src/lib.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/doc/src/lib.rs b/crates/doc/src/lib.rs index d694e5071..a7fcc4879 100644 --- a/crates/doc/src/lib.rs +++ b/crates/doc/src/lib.rs @@ -186,10 +186,17 @@ fn same_blocks(a: &Blocks, b: &Blocks) -> bool { a.len() == b.len() && a.iter().zip(b).all(|(x, y)| Arc::ptr_eq(x, y) || **x == **y) } -/// The same parts: the same kinds, the same text bodies and the same blocks. +/// The same parts: the same keys, and each part the same. fn same_parts(a: &BTreeMap, b: &BTreeMap) -> bool { - a.len() == b.len() - && a.iter().zip(b).all(|((k1, p1), (k2, p2))| k1 == k2 && p1.kind == p2.kind && p1.body == p2.body && same_blocks(&p1.blocks, &p2.blocks)) + a.len() == b.len() && a.iter().zip(b).all(|((k1, p1), (k2, p2))| k1 == k2 && same_part(p1, p2)) +} + +/// The same part: the same kind, text body and blocks. Every field is listed, so a new one +/// does not build until someone decides whether a change to it counts. +fn same_part(a: &Part, b: &Part) -> bool { + let Part { kind, blocks, body } = a; + let Part { kind: other_kind, blocks: other_blocks, body: other_body } = b; + kind == other_kind && body == other_body && same_blocks(blocks, other_blocks) } /// The same bytes: the same content. The bytes are compared by address first — a changed