]> Repositorios git - classgraph.git/commitdiff
Fix equality constraints surfacing every fam-instance main
authorJavier Sagredo <[email protected]>
Fri, 19 Jun 2026 16:21:11 +0000 (18:21 +0200)
committerJavier Sagredo <[email protected]>
Fri, 19 Jun 2026 16:21:11 +0000 (18:21 +0200)
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) <[email protected]>
data/viewer.js

index d26d49673c81fe477abac45fa34efb3b7e500615..84fc084045a747a3b162d075dd76b610c724d4e7 100644 (file)
         // noise. Run the relevance check *before* creating the
         // fam-instance node so irrelevant rows are skipped entirely.
         for (const fi of (famInstsByFamily.get(famNodeId) || [])) {
         // 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);
           anyRelevant = true;
 
           const fiNodeId = ensureFamInstanceNode(fi);
           // 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.
           // 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) {
             const reduced = resolvedArgs.map(reduceTypeArg);
             const matched = findMatchingInstances(predClassQn, reduced);
             if (matched.length > 0) {