From: Javier Sagredo Date: Fri, 19 Jun 2026 16:21:11 +0000 (+0200) Subject: Fix equality constraints surfacing every fam-instance X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;ds=inline;p=classgraph.git Fix equality constraints surfacing every fam-instance The instance-view equality edges (added in 9f81486) call addFamilyLinksFromArgs with predClassQn = null to surface type families mentioned inside an equality (e.g. `Norm` in `Norm a ~ Int`). But the relevance filter that keeps only the fam-instances whose LHS matches the use site was gated behind `if (predClassQn)`, so the null call skipped it and pulled in *every* instance of the family. Concretely: drilling into STS instances and filtering down to ShelleyUTXOW still showed the `State` of every rule, because ShelleyUTXOW's context has `State (EraRule "UTXO" era) ~ …` and the unfiltered call dumped all ~21 `State` instances. Apply the relevance filter (replaceFamilyApp unification) regardless of predClassQn; only the resolution-chain step stays gated on it. Now the filtered view shows just `State (ShelleyUTXOW era)` plus a placeholder for ShelleyUTXOW's own unresolved `State (EraRule "UTXO" era)` reference. Co-Authored-By: Claude Opus 4.8 (1M context) --- diff --git a/data/viewer.js b/data/viewer.js index d26d496..84fc084 100644 --- a/data/viewer.js +++ b/data/viewer.js @@ -759,11 +759,17 @@ // noise. Run the relevance check *before* creating the // fam-instance node so irrelevant rows are skipped entirely. for (const fi of (famInstsByFamily.get(famNodeId) || [])) { - let resolvedArgs = null; - if (predClassQn) { - resolvedArgs = args.map(a => replaceFamilyApp(a, fa, fi)); - if (resolvedArgs.some(a => a === null)) continue; - } + // Relevance filter — keep only fam-instances whose LHS can + // actually describe the family-application used here. + // replaceFamilyApp returns null for an arg that mentions `fa` + // but whose use-site args don't unify with this fi's LHS; an + // arg that doesn't mention `fa` comes back unchanged. This runs + // regardless of predClassQn: without it, an equality constraint + // like `State (EraRule "UTXO" era) ~ …` (predClassQn = null) + // would pull in *every* `State` instance instead of only the + // ones matching this use site. + const resolvedArgs = args.map(a => replaceFamilyApp(a, fa, fi)); + if (resolvedArgs.some(a => a === null)) continue; anyRelevant = true; const fiNodeId = ensureFamInstanceNode(fi); @@ -784,7 +790,7 @@ // also pull a class node into the graph alongside it — it // would just be a redundant box with a green arrow that says // the same thing. - if (predClassQn && resolvedArgs) { + if (predClassQn) { const reduced = resolvedArgs.map(reduceTypeArg); const matched = findMatchingInstances(predClassQn, reduced); if (matched.length > 0) {