fix: key skipped label collisions by label pair, not net pair - #721
fix: key skipped label collisions by label pair, not net pair#721DPS0340 wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
collisionKey used only globalConnNetId, so every label pair drawn from the same two nets collapsed into a single key. Once the search gave up on one pair, findNextCollidingPair skipped all the others silently — on the larger boards a single net pair covers over a hundred label pairs (max 136 on bug-report-20260706T220324Z). Include pinIds, which identifies the individual label and stays stable across relocations. No board in the current corpus changes: the overlaps that remain are all the only overlap for their net pair, so the aliasing never fires today. The added tests pin the behaviour directly — reverting the fix fails them.
368a30f to
474cf4e
Compare
|
Correcting myself on #721 — I told you in my audit comment on #719 that it "changes no board today" and flagged it as the easiest to decline. That was measured wrong, and the PR is worth more than I said. What I measured was the final overlap count (43 before, 43 after) and concluded no effect. What I should have measured is what the key actually collapses. On current Five skipped keys across four boards, and the largest suppresses ten label pairs after the search gives up on one of them. Those nine were never examined — they just look like overlaps the solver rejected. With this PR the keys become label-specific: so abandoning one pair no longer silences the rest. The final overlap count staying at 43 is real — the extra pairs it now examines happen to have no better placement available on these boards. So it is not a visible fix today, but "changes no board" understated it: it's a search-coverage bug where the solver was skipping work it had never done. Sorry for the mislead. My earlier framing would have been a reasonable basis to close it, and I don't think that's the right call anymore. Still yours to decide — #718/#719 remain the ones with the largest measured effect. |
Latent bug found while investigating the 7 remaining label-label overlaps from #720. It changes no board today — I'll be upfront about that — but it's a real aliasing defect with a direct test.
The bug
NetLabelNetLabelCollisionSolvergives up on a collision when it exhausts its candidate positions, recording the pair inskippedCollisionKeyssofindNextCollidingPairwon't retry it. The key was:That identifies a pair of nets, not a pair of labels. Any two labels from netA and netB share one key, so abandoning the search for one pair silently suppresses every other pair on those same nets — including ones that were never examined and might well have been resolvable.
Scale of the aliasing across the corpus:
So one skip could mask up to 135 unexamined pairs.
The fix
Include
pinIdsin the key. It identifies the individual label and is stable across relocations of that label, so distinct pairs stay distinct while a label being moved keeps its identity.Honest scope: no board changes
I measured before and after across every imported bug report:
Identical. I checked why, rather than shipping and claiming an improvement: among label pairs that actually overlap today, no two share a net-pair key. The 5 skipped keys are each the only overlap for their nets, so the aliasing never fires on this corpus. It's latent.
I considered dropping the change for that reason. I kept it because the defect is provable independently of whether a fixture happens to trigger it, and because a board that does trigger it would fail in a confusing way — overlaps that were never examined would look like overlaps the search had rejected.
Verification
Three tests pin the key's contract directly:
pinIdsorderConfirmed they bite: reverting
collisionKeyto the old net-only version fails the first test (2 pass / 1 fail).Full suite 151 pass / 0 fail / 4 skip,
tsc --noEmitclean, biome clean.Diff: 1 source file (+17/-1) plus one test file. Independent of #699/#720.