on master help sign in
Pass known unions through polymorphic gates
commit4e472b5f0e450fb3193b0e0ef239b2301f6d9c92 authoriko <mail@iko.soy> dateSat 31 Oct 2026, 05:08 (4 hours ago) parent0bf6178
13 files changed+748−108
docs/compiler.md+1−1 docs/status.md+7−6 jibb-dev/lib/jibb.hoon+11 tests/golden/types-union-polymorphic-identity/about.txt+4 tests/golden/types-union-polymorphic-identity/module-trees.txt+16 tests/golden/types-union-polymorphic-identity/modules.txt+2 tests/golden/types-union-polymorphic-identity/modules/ui/one.jibb+4 tests/golden/types-union-polymorphic-identity/modules/ui/two.jibb+4 tests/golden/types-union-polymorphic-identity/source.jibb+33 tests/golden/types-union-polymorphic-identity/tokens.txt+368 tests/golden/types-union-polymorphic-identity/tree.txt+152 tests/golden/types-union-polymorphic-identity/types.txt+36 tests/lib/jibb.hoon+110−101
docs/compiler.md+1−1
@@ -56,7 +56,7 @@ The core is split into chapters, `+| %name`, in this order:
5656| `%span-check` | `+check-spans`, which `+golden` runs on every tree, and `+check-spans-test` |
5757| `%type-inference` | The initial inference fragment and its unification helpers; not yet a module type checker |
5858
59−The inference fragment supports fixed auras, unrestricted `@`, one-way widening into it and toward aura-family ancestors, generic variables and gates, faced and unfaced cells, cell sample binders, known record field reads, a cell pattern of two or more binders, a complete two-arm loobean branch, a complete two-arm unit-shaped branch, closed local mold aliases and acyclic forward value references. For a supported single syntactic top-level recursive gate, the checker infers the sample first and uses that exact sample, including its field faces, in a monomorphic self placeholder. The completed body must unify with the placeholder before the gate is generalized; incompatible recursive arguments can report the call and argument sites. Uses of generalized top-level definitions instantiate their schemes independently. For a complete loobean branch with one direct self-call arm, the checker can infer the other arm independently and use its closed, fully resolved type to seed the recursive result; it then checks the whole body. Open or pending base types do not seed the result, and other branch shapes still depend on the existing partial inference. A supported single local recursive gate also uses a monomorphic self reference while its body is checked, then generalizes variables free of its enclosing environment; captured variables remain shared. Acyclic local value definitions can refer forward. The checker collects written capitals per `++` before inference, excluding nested definitions: a capital used in an enclosing definition is shared with its locals, even when written later, while a capital introduced only in a local definition is generalized there. Sibling locals can introduce independent capitals with the same spelling; generic mold parameters keep their own scope. Top-level groups of syntactic gates are inferred together with monomorphic placeholders and shared substitutions, then generalized only after the whole group checks; downstream uses and library interfaces instantiate those schemes independently. A dependency graph identifies groups with two iterative depth-first passes; its conservative local-reference edges can reject otherwise valid programs. Supported local mutually recursive gate groups also use shared monomorphic placeholders and generalize only after the group checks, preserving captured outer variables. Some proven non-gate value cycles are diagnosed; other mixed gate/value cycles, polymorphic recursion, unresolved literal constraints and unresolved branch joins remain unsupported. Acyclic simple local mold aliases can also refer forward, and are scoped to the body, not its gate's sample. Nonrecursive generic aliases of supported molds can be applied at exact arity, including locally and through library interfaces; their parameters are lexical. Closed, provably disjoint nonrecursive unions and tagged single-case molds support contextual term values, `~` and `|=%tag` constructors. A null-headed cell can match a union case but does not supply a `|=%$` constructor; unresolved tags and nulls remain pending, with distinct partial-inference diagnostics. Nonrecursive top-level generic union molds with provably disjoint cases also support contextual tags and constructors at exact arity; their arguments are retained through generalization and supported library interfaces. Nonrecursive generic aliases can reorder, repeat or omit parameters while preserving a supported union’s origin, including through local scopes and library interfaces. A generic union declared directly inside a body and recursive molds remain unsupported. A value with type variable `A` can fit a field whose type is that same `A`, including in generic union payloads and nested or repeated record fields. A differing-variable face constraint remains unsupported. When inference forces two distinct explicitly written capitals equal, it reports both source sites; forcing a capital to a concrete type remains unsupported in this fragment. It can infer and generalize atom constraints arising from explicit capitals or bare sample binders, preserve those constraints through aliases, instantiate them independently, and print multiple constraints. Unresolved decimal variables default to `@ud` for inferred types without gates; defaulting inside gate types and other constraint cases remain incomplete. It does not yet check a module, complete imports, general patterns, general deferred constraints, recursive molds, dependency cycles or most errors with both conflicting excerpts. Definite cast and call mismatches, incompatible branches and overlapping union cases report both sites and excerpts. Concrete branch results can join at an explicitly present parent aura or `@`. Some known tuple and record positions acquire matching faces; other variable-dependent face merges, general branch tag context and ambiguous call-result propagation remain unsupported; function compatibility involving nested `@` and variable-dependent joins remain unsupported except for equal types. For a single recursive gate outside a group, the reporting path repeats inference rather than instantiating its generalized interface inside its own body; a group report uses its stored schemes. This adds work, and the current dependency pass can take quadratic time on long forward chains; the milestone's speed target remains unverified. A separate conservative pass reports unions whose cases are provably disjoint or overlapping and leaves other cases unresolved; it does not claim the mold is checked. Unsupported forms are reported as such, and the partial output says the module has not been checked.
59+The inference fragment supports fixed auras, unrestricted `@`, one-way widening into it and toward aura-family ancestors, generic variables and gates, faced and unfaced cells, cell sample binders, known record field reads, a cell pattern of two or more binders, a complete two-arm loobean branch, a complete two-arm unit-shaped branch, closed local mold aliases and acyclic forward value references. For a supported single syntactic top-level recursive gate, the checker infers the sample first and uses that exact sample, including its field faces, in a monomorphic self placeholder. The completed body must unify with the placeholder before the gate is generalized; incompatible recursive arguments can report the call and argument sites. Uses of generalized top-level definitions instantiate their schemes independently. For a complete loobean branch with one direct self-call arm, the checker can infer the other arm independently and use its closed, fully resolved type to seed the recursive result; it then checks the whole body. Open or pending base types do not seed the result, and other branch shapes still depend on the existing partial inference. A supported single local recursive gate also uses a monomorphic self reference while its body is checked, then generalizes variables free of its enclosing environment; captured variables remain shared. Acyclic local value definitions can refer forward. The checker collects written capitals per `++` before inference, excluding nested definitions: a capital used in an enclosing definition is shared with its locals, even when written later, while a capital introduced only in a local definition is generalized there. Sibling locals can introduce independent capitals with the same spelling; generic mold parameters keep their own scope. Top-level groups of syntactic gates are inferred together with monomorphic placeholders and shared substitutions, then generalized only after the whole group checks; downstream uses and library interfaces instantiate those schemes independently. A dependency graph identifies groups with two iterative depth-first passes; its conservative local-reference edges can reject otherwise valid programs. Supported local mutually recursive gate groups also use shared monomorphic placeholders and generalize only after the group checks, preserving captured outer variables. Some proven non-gate value cycles are diagnosed; other mixed gate/value cycles, polymorphic recursion, unresolved literal constraints and unresolved branch joins remain unsupported. Acyclic simple local mold aliases can also refer forward, and are scoped to the body, not its gate's sample. Nonrecursive generic aliases of supported molds can be applied at exact arity, including locally and through library interfaces; their parameters are lexical. Closed, provably disjoint nonrecursive unions and tagged single-case molds support contextual term values, `~` and `|=%tag` constructors. A null-headed cell can match a union case but does not supply a `|=%$` constructor; unresolved tags and nulls remain pending, with distinct partial-inference diagnostics. Nonrecursive top-level generic union molds with provably disjoint cases also support contextual tags and constructors at exact arity; their arguments are retained through generalization and supported library interfaces. Nonrecursive generic aliases can reorder, repeat or omit parameters while preserving a supported union’s origin, including through local scopes and library interfaces. A generic union declared directly inside a body and recursive molds remain unsupported. A directly known named union can instantiate an unconstrained generic gate sample while retaining its origin, generic arguments and faces. Unnamed, pending-tag, recursive, unknown-atom and variable-bound union origins remain unsupported. A value with type variable `A` can fit a field whose type is that same `A`, including in generic union payloads and nested or repeated record fields. A differing-variable face constraint remains unsupported. When inference forces two distinct explicitly written capitals equal, it reports both source sites; forcing a capital to a concrete type remains unsupported in this fragment. It can infer and generalize atom constraints arising from explicit capitals or bare sample binders, preserve those constraints through aliases, instantiate them independently, and print multiple constraints. Unresolved decimal variables default to `@ud` for inferred types without gates; defaulting inside gate types and other constraint cases remain incomplete. It does not yet check a module, complete imports, general patterns, general deferred constraints, recursive molds, dependency cycles or most errors with both conflicting excerpts. Definite cast and call mismatches, incompatible branches and overlapping union cases report both sites and excerpts. Concrete branch results can join at an explicitly present parent aura or `@`. Some known tuple and record positions acquire matching faces; other variable-dependent face merges, general branch tag context and ambiguous call-result propagation remain unsupported; function compatibility involving nested `@` and variable-dependent joins remain unsupported except for equal types. For a single recursive gate outside a group, the reporting path repeats inference rather than instantiating its generalized interface inside its own body; a group report uses its stored schemes. This adds work, and the current dependency pass can take quadratic time on long forward chains; the milestone's speed target remains unverified. A separate conservative pass reports unions whose cases are provably disjoint or overlapping and leaves other cases unresolved; it does not claim the mold is checked. Unsupported forms are reported as such, and the partial output says the module has not been checked.
6060
6161A single-arm cell pattern can bind two or more positions, with its last binder capturing the remaining tail. Duplicate and shadowed names are rejected. A definite non-cell spine fails; an intermediate union or collection that might contain a cell remains unsupported. For a known non-union cell, a separate one-arm rule also accepts structured patterns, including nested literal and wildcard positions, when the existing coverage proof establishes the whole pattern. It binds payloads with their original types and checks result context; unknown, partially covered, union or recursive spines stay unsupported.
6262
docs/status.md+7−6
@@ -19,7 +19,7 @@ On 2026-10-30, @iko decided that Jibb drops `$?`, so a `+$` takes a union's case
1919
2020## Milestone 2: in progress
2121
22−The repository spec records the subsequent type-system and prelude decisions; those changes also need synchronization to the Claude document. An initial inference fragment and a standalone Hoon type reader are being tested. The fragment explicitly reports that it does not check a module; partial bridges pass Hoon `*` in supported nonrecursive molds, selected Hoon atoms, term singletons, the null singleton, the two loobean singletons and their exact fork, nested faced or unfaced cells, supported disjoint unions and opaque standard collections from `/sur` molds and marks into inference. Collections retain their names and supported arguments for printing and unification; nested supported union arguments are retained too. The bridge trusts unchanged results from the source-aware reader; a materialized type graph alone cannot reveal cases Hoon already collapsed. The source-validated standard prelude `list` mold shares this representation with imported lists; other Jibb-written collection molds and most prelude collection operations remain unsupported; malformed names and arities fail closed. Selected self-recursive `/sur` molds, including Tlon `notes.import-node` with list-wrapped self references, cross as opaque module-and-name identities; aliases, foreign references, recursive marks, unfolding and construction remain unsupported. The reader handles mark samples, including a source-proved nonrecursive union from a single Ford-imported `/sur` core, recursive molds whose origins can be verified through Ford imports, nested collections, direct ordered maps, including source-validated named operands such as Tlon `notes.log`, certain ordered-map fields, direct `$^` unions whose cases can be proved disjoint, and one verified explicit union argument in a list, set, map or unit. Tagged `$%` cases can additionally use restricted local named payload molds, bare `~` fields and one level of local named tagged unions, as in real Tlon `notes`, with bounded source proof; unsupported or ambiguous dependencies fail closed. Ambiguous recursive origins fail closed; recognizable explicit unions are checked from source before Hoon can collapse their cases, as @iko confirmed for imported `$%`, `$?` and `$^`, while other nested unions, nested ordered maps, general union disjointness and complete import integration remain unfinished. Opt-in structured reader APIs preserve successful graphs and distinguish definite unsupported-aura and core evidence from failures the reader cannot prove; unverified union disjointness and name-only vase recognition remain unsupported. They revalidate and re-walk failed types. An opt-in partial checker entry point consumes unchanged reader results and reports definite aura or core errors at imported mold use sites when their inputs are unique. Ordered replay covers nested cell samples, record and function casts, and non-generic same-module aliases; unsupported prefixes, cycles and shadowing stop it. Union molds, generic applications, transitive modules and unsupported reader outcomes remain generic. Replay repeats inference and may add work. The partial checker resolves a subset of ordinary library imports in dependency order using supplied Jibb sources and a source-derived partial prelude interface, caches completed interfaces per run, detects missing sources and cycles, and resolves nested fields of imported values with independent scheme instantiation. The source-backed internal prelude defines `poke` and the public prelude re-exports it as a transparent type. A dedicated trusted preparation path supplies a private comparison scheme to the Jibb-written `gth` wrapper; ordinary imports cannot access them. Primitive execution and jet recognition are unfinished, and addition, decrement and length remain unavailable until arithmetic constraints distinguish their results from loobeans. The partial checker resolves its supported source shape and rejects ordinary imports of the private path. An imported API with one mark and a matching direct `+$ poke` declaration can export a constructor and retain agent/mark metadata when the representation has the supported agent case. A separate partial analysis resolves supported API path declarations and their full and diff mark types, including the todo paths; it does not create requests or check an API module. Complete private module checking, other API shapes, request gates, root API and kind checking, stores, `ask`, `pure`, lowering and runtime effects remain unfinished. A possible store or root API with `+$ poke` reports unsupported kind or scope, while definite duplicates and unrelated shadowing still report conflicts. The prelude includes the doc-exact generic `cmd` union; the prelude inventory is incomplete. The inference fragment supports unrestricted `@`, selected one-way widenings including aura-family ancestors, generalized atom constraints arising from explicit capitals or bare sample binders, acyclic local value definitions with captures, selected single self-recursive top-level and local gates, simple and nonrecursive generic mold aliases, selected faced record casts and field reads, and contextual tags, `~` and constructors for closed disjoint unions, including direct nonrecursive generic unions and propagation through complete loobean and unit-shaped branches in casts and known union-sample calls, including nested branches. Known loobean result context also propagates through supported complete branches and binder-only cell arms; binder-only arms over union subjects remain unsupported. A known gate with an unresolved result variable can receive a known enclosing result type before its arguments are inferred; unknown calls and unresolved targets remain conservative. Multi-argument calls form a right-nested sample, retain known faces and shared type variables, and can use known sample positions to contextualize list and union arguments. A definite mismatch points to the failing argument when the fragment can establish it, otherwise to the combined sample; unsupported contextual forms still fail closed. For a supported recursive gate, the checker infers the sample first and uses its exact type, including field faces, for one monomorphic self reference. It generalizes after the body is checked; subsequent uses instantiate it independently. Incompatible recursive arguments can report the gate and argument sites. For a complete loobean branch with one direct self-call arm, a separately inferred closed base type can seed the recursive result before the whole body is checked. Open or pending base types do not seed it; other branch shapes remain subject to the fragment’s existing limits. A supported single local recursive gate also uses a monomorphic self reference and generalizes variables free of the enclosing environment after checking its body; captured variables remain shared. The checker collects written capitals per `++` before inference, excluding nested definitions: a capital used in an enclosing definition is shared with its locals even when written later, while a capital introduced only in a local definition is generalized there. Sibling locals can introduce independent capitals with the same spelling; generic mold parameters keep their own scope. Top-level groups of syntactic gates are inferred together with monomorphic placeholders and shared substitutions, then generalized only after the whole group checks; downstream uses and library interfaces instantiate those schemes independently. A dependency graph identifies groups with two iterative depth-first passes; its conservative local-reference edges can reject otherwise valid programs. Supported local mutually recursive gate groups also use shared monomorphic placeholders and generalize only after the group checks, preserving captured outer variables. A bounded dependency proof reports certain non-gate cycles through values and gates when an explicit atom or loobean result cast and simple unshadowed expressions establish the cycle. Other mixed gate/value cycles, polymorphic recursion, unresolved literal constraints and unresolved branch joins remain unsupported. Reporting repeats inference for a single recursive gate outside a group; grouped reports use the stored schemes. Its performance cost remains unmeasured. A single-arm cell pattern accepts two or more binders, the last capturing the remaining tail; duplicate and shadowed binders are rejected. A structured single-arm pattern also works for a known non-union cell when coverage is proven, including nested literal and wildcard positions. Intermediate union or collection tails, nested patterns, wildcards and faced records remain unsupported. String interpolation accepts known atom auras, unrestricted `@`, tapes and isolated decimal literals; a known cell asks for a printer, and an explicitly generic atom asks for an aura. Loobeans, term singletons, non-tape collections, open types and a type fixed only later remain unsupported. A known closed union with two or more arms supports patterns that provably cover or exclude each remaining case, including payload binders, imported and generic cases, and binder-free catch-alls. Partial boolean patterns can split known `?` positions into their two noun values, up to 64 alternatives across the union; binders retain their original case type. Missing alternatives and covered arms are reported. Other partial patterns, expansions above the limit, binders spanning distinct cases, differing arm result types and some complex two-arm subjects remain unsupported. A cast or known call sample can supply result context through whole-case arms and supported finite loobean refinements for a known union accessed by a wing, including nested cell and list positions; other partial-pattern context and non-wing subjects remain unsupported. The Grammar’s `step` block infers in this fragment, but its module is not yet checked. A bare tag proved absent from a known union reports the union and tag sites in casts, single-argument calls, unit payloads, list items and supported branch arms; imported unnamed unions print their cases. Ordered fit replay can identify a missing tag nested in a syntactic tuple, stopping at an earlier mismatch or uncertainty. Known faced records support uniquely named field changes, including nested wings, with field context passed to replacements and the original record type retained. Missing fields, empty changes and definite mismatches report sites; the expected-type site is the edit because the original field declaration location is not retained. Unknown or partly unfaced spines, ambiguous fields and repeated edits remain unsupported. A known record cast supplies field context to its tuple or record initializer, including nested list and union fields; mismatch diagnostics use the cast mold because the original field declaration location is not retained. Isolated cart-style `init` and `update` expressions infer, while the complete cart-store fails closed because its kind and declaration scope remain unchecked. Uncontextualized list literals infer a fresh element type, including empty and nested lists, with independently generalized uses. Unresolved item tags and uncertain widening remain unsupported. Backtick unit construction uses the validated standard prelude unit template, infers its payload without losing pending constraints, and makes the prelude’s `some` available. Ordinary result annotations also let its `bind`, `biff`, `both`, `clap`, `clef` and `flit` infer. A known unit in a cast, call, list item or record field supplies context to its payload, including nested units and lists; mismatches identify the payload and context. Unrelated union identities, some variable-dependent fits, and missing or altered prelude unit templates remain unsupported. Contextual null-headed cells fit their cases, but do not supply a `|=%$` constructor; unresolved nulls remain pending and are reported separately from tags. A known union of `~` and a null-headed cell supports a complete `~` / `[~ value]` branch in either order, including shadow checks; unknown subjects, missing or duplicate arms, and unresolved branch results remain unsupported. This fragment infers the prelude’s `fall` and `need` signatures. With the validated prelude list and a known cast or gate sample, empty, nonempty and nested list literals infer their element types, including contextual union tags; a mismatched element names both sites. In that context `~` and zero-valued terms fit an empty list, and two-item unfaced cells form cons lists, including nested cons and imported-list contexts; invalid heads or tails name both sites. A known gate sample also supplies context to matching positions in a single tuple or record argument, including nested cells; zero literals can fit list positions. A bound zero constant remains unsupported rather than a definite mismatch, and an unknown callee does not supply context. Faced or longer cells and a missing or altered prelude list fail closed. A known list result also supplies context through complete loobean, unit-shaped and list-shaped branches, including recursive and nested branches. For a known standard list with a supported element type, a complete `~` / `[item rest]` branch infers the element and tail types in either arm order and checks binders for shadowing. Unknown subjects, unsupported element types and other or incomplete list patterns remain unsupported. A value with type variable `A` can fit a field whose type is that same `A`, including in generic union payloads and nested or repeated record fields. Other variable-dependent face merges remain unsupported. Forced equality of distinct written capitals now reports both source sites, following @iko’s decision; forcing one to a concrete type remains unsupported. Imported record spines with repeated faces fail closed where used, but only with a generic unsupported diagnostic. Hoon may erase unfaced nested-cell boundaries, so the check can conservatively reject valid names in distinct erased scopes. Supported closed unions print using an in-scope name or imported alias; an unnamed nongeneric union prints its cases, parenthesized when nested. The latter is print-only. Generic union types retain all arguments in their printed name; if that name is unavailable, the partial printer reports the limitation. Different import faces for the same origin remain compatible; compatibility across distinct union origins and some generic-argument comparisons remain unsupported. Nonrecursive generic aliases can reorder, repeat or omit parameters while retaining a union’s origin, including through local scopes and library interfaces. A generic union declared directly inside a body remains unsupported, as do differing-variable face constraints in a union payload. A transitive generic union whose name is unavailable is reported as unsupported instead of hiding its arguments. Unfixed decimal literals default to `@ud` in gate-free inferred types; recursive molds, general branch tag context, other constraint cases and defaulting inside gate types still need work. Collection recognition checks the originating core and fails closed on shadows or unsupported Ford subject shapes; a wrapper regression also rejects forged subjects, samples and tails. Its golden fixtures include three real Tlon files. A Clay test passes a Ford-built nested union through the reader into partial inference. The partial prelude includes `murn`, `join`, `snip`, `rear` and the newly agreed shared-type `clap`, parsed but still awaiting checker and backend validation, and [prelude-inventory.md](prelude-inventory.md) is a source audit, not the complete inventory or signatures. The milestone remains unfinished.
22+The repository spec records the subsequent type-system and prelude decisions; those changes also need synchronization to the Claude document. An initial inference fragment and a standalone Hoon type reader are being tested. The fragment explicitly reports that it does not check a module; partial bridges pass Hoon `*` in supported nonrecursive molds, selected Hoon atoms, term singletons, the null singleton, the two loobean singletons and their exact fork, nested faced or unfaced cells, supported disjoint unions and opaque standard collections from `/sur` molds and marks into inference. Collections retain their names and supported arguments for printing and unification; nested supported union arguments are retained too. The bridge trusts unchanged results from the source-aware reader; a materialized type graph alone cannot reveal cases Hoon already collapsed. The source-validated standard prelude `list` mold shares this representation with imported lists; other Jibb-written collection molds and most prelude collection operations remain unsupported; malformed names and arities fail closed. Selected self-recursive `/sur` molds, including Tlon `notes.import-node` with list-wrapped self references, cross as opaque module-and-name identities; aliases, foreign references, recursive marks, unfolding and construction remain unsupported. The reader handles mark samples, including a source-proved nonrecursive union from a single Ford-imported `/sur` core, recursive molds whose origins can be verified through Ford imports, nested collections, direct ordered maps, including source-validated named operands such as Tlon `notes.log`, certain ordered-map fields, direct `$^` unions whose cases can be proved disjoint, and one verified explicit union argument in a list, set, map or unit. Tagged `$%` cases can additionally use restricted local named payload molds, bare `~` fields and one level of local named tagged unions, as in real Tlon `notes`, with bounded source proof; unsupported or ambiguous dependencies fail closed. Ambiguous recursive origins fail closed; recognizable explicit unions are checked from source before Hoon can collapse their cases, as @iko confirmed for imported `$%`, `$?` and `$^`, while other nested unions, nested ordered maps, general union disjointness and complete import integration remain unfinished. Opt-in structured reader APIs preserve successful graphs and distinguish definite unsupported-aura and core evidence from failures the reader cannot prove; unverified union disjointness and name-only vase recognition remain unsupported. They revalidate and re-walk failed types. An opt-in partial checker entry point consumes unchanged reader results and reports definite aura or core errors at imported mold use sites when their inputs are unique. Ordered replay covers nested cell samples, record and function casts, and non-generic same-module aliases; unsupported prefixes, cycles and shadowing stop it. Union molds, generic applications, transitive modules and unsupported reader outcomes remain generic. Replay repeats inference and may add work. The partial checker resolves a subset of ordinary library imports in dependency order using supplied Jibb sources and a source-derived partial prelude interface, caches completed interfaces per run, detects missing sources and cycles, and resolves nested fields of imported values with independent scheme instantiation. The source-backed internal prelude defines `poke` and the public prelude re-exports it as a transparent type. A dedicated trusted preparation path supplies a private comparison scheme to the Jibb-written `gth` wrapper; ordinary imports cannot access them. Primitive execution and jet recognition are unfinished, and addition, decrement and length remain unavailable until arithmetic constraints distinguish their results from loobeans. The partial checker resolves its supported source shape and rejects ordinary imports of the private path. An imported API with one mark and a matching direct `+$ poke` declaration can export a constructor and retain agent/mark metadata when the representation has the supported agent case. A separate partial analysis resolves supported API path declarations and their full and diff mark types, including the todo paths; it does not create requests or check an API module. Complete private module checking, other API shapes, request gates, root API and kind checking, stores, `ask`, `pure`, lowering and runtime effects remain unfinished. A possible store or root API with `+$ poke` reports unsupported kind or scope, while definite duplicates and unrelated shadowing still report conflicts. The prelude includes the doc-exact generic `cmd` union; the prelude inventory is incomplete. The inference fragment supports unrestricted `@`, selected one-way widenings including aura-family ancestors, generalized atom constraints arising from explicit capitals or bare sample binders, acyclic local value definitions with captures, selected single self-recursive top-level and local gates, simple and nonrecursive generic mold aliases, selected faced record casts and field reads, and contextual tags, `~` and constructors for closed disjoint unions, including direct nonrecursive generic unions and propagation through complete loobean and unit-shaped branches in casts and known union-sample calls, including nested branches. Known loobean result context also propagates through supported complete branches and binder-only cell arms; binder-only arms over union subjects remain unsupported. A directly known named union can instantiate an unconstrained generic gate sample with its origin, generic arguments and faces preserved; unnamed, pending, recursive and variable-bound cases remain unsupported. A known gate with an unresolved result variable can receive a known enclosing result type before its arguments are inferred; unknown calls and unresolved targets remain conservative. Multi-argument calls form a right-nested sample, retain known faces and shared type variables, and can use known sample positions to contextualize list and union arguments. A definite mismatch points to the failing argument when the fragment can establish it, otherwise to the combined sample; unsupported contextual forms still fail closed. For a supported recursive gate, the checker infers the sample first and uses its exact type, including field faces, for one monomorphic self reference. It generalizes after the body is checked; subsequent uses instantiate it independently. Incompatible recursive arguments can report the gate and argument sites. For a complete loobean branch with one direct self-call arm, a separately inferred closed base type can seed the recursive result before the whole body is checked. Open or pending base types do not seed it; other branch shapes remain subject to the fragment’s existing limits. A supported single local recursive gate also uses a monomorphic self reference and generalizes variables free of the enclosing environment after checking its body; captured variables remain shared. The checker collects written capitals per `++` before inference, excluding nested definitions: a capital used in an enclosing definition is shared with its locals even when written later, while a capital introduced only in a local definition is generalized there. Sibling locals can introduce independent capitals with the same spelling; generic mold parameters keep their own scope. Top-level groups of syntactic gates are inferred together with monomorphic placeholders and shared substitutions, then generalized only after the whole group checks; downstream uses and library interfaces instantiate those schemes independently. A dependency graph identifies groups with two iterative depth-first passes; its conservative local-reference edges can reject otherwise valid programs. Supported local mutually recursive gate groups also use shared monomorphic placeholders and generalize only after the group checks, preserving captured outer variables. A bounded dependency proof reports certain non-gate cycles through values and gates when an explicit atom or loobean result cast and simple unshadowed expressions establish the cycle. Other mixed gate/value cycles, polymorphic recursion, unresolved literal constraints and unresolved branch joins remain unsupported. Reporting repeats inference for a single recursive gate outside a group; grouped reports use the stored schemes. Its performance cost remains unmeasured. A single-arm cell pattern accepts two or more binders, the last capturing the remaining tail; duplicate and shadowed binders are rejected. A structured single-arm pattern also works for a known non-union cell when coverage is proven, including nested literal and wildcard positions. Intermediate union or collection tails, nested patterns, wildcards and faced records remain unsupported. String interpolation accepts known atom auras, unrestricted `@`, tapes and isolated decimal literals; a known cell asks for a printer, and an explicitly generic atom asks for an aura. Loobeans, term singletons, non-tape collections, open types and a type fixed only later remain unsupported. A known closed union with two or more arms supports patterns that provably cover or exclude each remaining case, including payload binders, imported and generic cases, and binder-free catch-alls. Partial boolean patterns can split known `?` positions into their two noun values, up to 64 alternatives across the union; binders retain their original case type. Missing alternatives and covered arms are reported. Other partial patterns, expansions above the limit, binders spanning distinct cases, differing arm result types and some complex two-arm subjects remain unsupported. A cast or known call sample can supply result context through whole-case arms and supported finite loobean refinements for a known union accessed by a wing, including nested cell and list positions; other partial-pattern context and non-wing subjects remain unsupported. The Grammar’s `step` block infers in this fragment, but its module is not yet checked. A bare tag proved absent from a known union reports the union and tag sites in casts, single-argument calls, unit payloads, list items and supported branch arms; imported unnamed unions print their cases. Ordered fit replay can identify a missing tag nested in a syntactic tuple, stopping at an earlier mismatch or uncertainty. Known faced records support uniquely named field changes, including nested wings, with field context passed to replacements and the original record type retained. Missing fields, empty changes and definite mismatches report sites; the expected-type site is the edit because the original field declaration location is not retained. Unknown or partly unfaced spines, ambiguous fields and repeated edits remain unsupported. A known record cast supplies field context to its tuple or record initializer, including nested list and union fields; mismatch diagnostics use the cast mold because the original field declaration location is not retained. Isolated cart-style `init` and `update` expressions infer, while the complete cart-store fails closed because its kind and declaration scope remain unchecked. Uncontextualized list literals infer a fresh element type, including empty and nested lists, with independently generalized uses. Unresolved item tags and uncertain widening remain unsupported. Backtick unit construction uses the validated standard prelude unit template, infers its payload without losing pending constraints, and makes the prelude’s `some` available. Ordinary result annotations also let its `bind`, `biff`, `both`, `clap`, `clef` and `flit` infer. A known unit in a cast, call, list item or record field supplies context to its payload, including nested units and lists; mismatches identify the payload and context. Unrelated union identities, some variable-dependent fits, and missing or altered prelude unit templates remain unsupported. Contextual null-headed cells fit their cases, but do not supply a `|=%$` constructor; unresolved nulls remain pending and are reported separately from tags. A known union of `~` and a null-headed cell supports a complete `~` / `[~ value]` branch in either order, including shadow checks; unknown subjects, missing or duplicate arms, and unresolved branch results remain unsupported. This fragment infers the prelude’s `fall` and `need` signatures. With the validated prelude list and a known cast or gate sample, empty, nonempty and nested list literals infer their element types, including contextual union tags; a mismatched element names both sites. In that context `~` and zero-valued terms fit an empty list, and two-item unfaced cells form cons lists, including nested cons and imported-list contexts; invalid heads or tails name both sites. A known gate sample also supplies context to matching positions in a single tuple or record argument, including nested cells; zero literals can fit list positions. A bound zero constant remains unsupported rather than a definite mismatch, and an unknown callee does not supply context. Faced or longer cells and a missing or altered prelude list fail closed. A known list result also supplies context through complete loobean, unit-shaped and list-shaped branches, including recursive and nested branches. For a known standard list with a supported element type, a complete `~` / `[item rest]` branch infers the element and tail types in either arm order and checks binders for shadowing. Unknown subjects, unsupported element types and other or incomplete list patterns remain unsupported. A value with type variable `A` can fit a field whose type is that same `A`, including in generic union payloads and nested or repeated record fields. Other variable-dependent face merges remain unsupported. Forced equality of distinct written capitals now reports both source sites, following @iko’s decision; forcing one to a concrete type remains unsupported. Imported record spines with repeated faces fail closed where used, but only with a generic unsupported diagnostic. Hoon may erase unfaced nested-cell boundaries, so the check can conservatively reject valid names in distinct erased scopes. Supported closed unions print using an in-scope name or imported alias; an unnamed nongeneric union prints its cases, parenthesized when nested. The latter is print-only. Generic union types retain all arguments in their printed name; if that name is unavailable, the partial printer reports the limitation. Different import faces for the same origin remain compatible; compatibility across distinct union origins and some generic-argument comparisons remain unsupported. Nonrecursive generic aliases can reorder, repeat or omit parameters while retaining a union’s origin, including through local scopes and library interfaces. A generic union declared directly inside a body remains unsupported, as do differing-variable face constraints in a union payload. A transitive generic union whose name is unavailable is reported as unsupported instead of hiding its arguments. Unfixed decimal literals default to `@ud` in gate-free inferred types; recursive molds, general branch tag context, other constraint cases and defaulting inside gate types still need work. Collection recognition checks the originating core and fails closed on shadows or unsupported Ford subject shapes; a wrapper regression also rejects forged subjects, samples and tails. Its golden fixtures include three real Tlon files. A Clay test passes a Ford-built nested union through the reader into partial inference. The partial prelude includes `murn`, `join`, `snip`, `rear` and the newly agreed shared-type `clap`, parsed but still awaiting checker and backend validation, and [prelude-inventory.md](prelude-inventory.md) is a source audit, not the complete inventory or signatures. The milestone remains unfinished.
2323
2424The shared prelude interface reserves every name present in the supplied vendored source and makes only supported inferred entries available, including `list`, `unit`, `same`, `fall`, `need`, `lure`, `weld`, `snoc` and `turn`. The validated standard `list` mold is injected when the prelude’s own gates are inferred; `weld` and `turn` have ordinary explicit result casts. An absent or altered `list` is not injected, and an altered declaration cannot leak through direct or transitive mold aliases. List-dependent prelude mold aliases remain unsupported because their templates are prepared before injection. Unsupported entries such as most list helpers remain reserved but unavailable; backend validation of the helpers remains outstanding. All callers use the same prelude origin, so a library can export a type containing unqualified `(unit A)` to another module. Preparation rejects empty, malformed, conflicting or import-bearing source; the prepared value is trusted and must come unchanged from `+prepare-prelude`. The module-scope fixture compares the prepared and source-taking paths against the real prelude and a two-module golden under eval and on the ship. The source and checker remain incomplete, so this does not establish complete shadowing coverage or a checked module.
2525
@@ -39,8 +39,8 @@ What the plan asks for, and where it is:
3939
4040Besides the plan's list:
4141
42−- 573 golden cases: 357 that parse and 216 that fail, each failure at a stated line and column. One failing case has an unclear expectation (corpus question 3). The newer type-output cases exercise only the partial inference fragment. Each case's `about.txt` quotes the doc's words it tests.
43−- The 573-case corpus passed under `urbit eval` in 77.6 s. The fake ship passed all 582 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 44.1 s for sync and 56.7 s for tests. The importer golden compares 214 projections; `tools/clay-fixtures` builds the example Hoon fixtures through Clay, checks a recursive Ford import's origin, and passes Clay-built types through the Clay-built importer and partial checker.
42+- 574 golden cases: 358 that parse and 216 that fail, each failure at a stated line and column. One failing case has an unclear expectation (corpus question 3). The newer type-output cases exercise only the partial inference fragment. Each case's `about.txt` quotes the doc's words it tests.
43+- The 574-case corpus passed under `urbit eval` in 77.9 s. The fake ship passed all 583 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 43.4 s for sync and 54.7 s for tests. The importer golden compares 214 projections; `tools/clay-fixtures` builds the example Hoon fixtures through Clay, checks a recursive Ford import's origin, and passes Clay-built types through the Clay-built importer and partial checker.
4444- `tools/testdata/selftest` (22 checks), `tools/testdata/ship-selftest` and `tools/testdata/clay-fixtures-selftest` test the tools themselves; the last checks temporary Clay fixture cleanup and signal handling without a ship.
4545- Two independent audits before 7c739b7, one of which compared the library with a reference parser written in Python from the doc over about 19,000 generated programs. Before ab797a9, a second Python parser, written from the decisions, agreed with the library on 8,000 generated programs and 900 hand-written probes.
4646- Speed: starting `urbit eval` and building the library takes about 8 s. After that, a 2,000-line module of 400 definitions parses in about a second. Loops over definitions, arms, lines and items grow no stack; nesting costs a few stack frames a level, and 100,000 nested brackets still parse (library section 3).
@@ -116,14 +116,15 @@ Besides the plan's list:
116116| ad0265e | 2026-10-31 | Infer proven single-case patterns and the prelude command union |
117117| 413b12b | 2026-10-31 | Propagate known result context into generic calls and batch ship deletions |
118118| c690076 | 2026-10-31 | Propagate loobean context, infer predicate helpers, and import named ordered-map operands |
119−| This change | 2026-10-31 | Bridge recursive Tlon lists and prepare a private comparison interface |
119+| 0bf6178 | 2026-10-31 | Bridge recursive Tlon lists and prepare a private comparison interface |
120+| This change | 2026-10-31 | Pass known named unions through polymorphic gates |
120121
121122## Checking it
122123
123124On a machine set up as [development.md](development.md) says:
124125
125126```
126−tools/golden # 573 cases under urbit eval
127+tools/golden # 574 cases under urbit eval
127128tools/importer-test # the Hoon importer fixture projection
128129tools/type-import-test # the importer/checker bridge fixture
129130tools/type-tlon-test # the real Tlon reader/checker fixture
@@ -136,7 +137,7 @@ tools/testdata/selftest # the tools themselves
136137tools/doc-blocks docs/spec # the doc's examples are golden cases
137138tools/ship start
138139tools/ship gen-tests --check # tests/lib/jibb.hoon is up to date
139−tools/ship test # the same 573 cases as -test arms on the ship
140+tools/ship test # the same 574 cases as -test arms on the ship
140141tools/testdata/ship-selftest
141142tools/testdata/clay-fixtures-selftest # scratch fixture cleanup without a ship
142143tools/ship check-commit # |commit stores .jibb files
jibb-dev/lib/jibb.hoon+11
@@ -5057,6 +5057,8 @@
50575057 ^- ifit
50585058 =/ uncertain=?
50595059 |(?=(%var -.actual) ?=(%avar -.actual) ?=(%nvar -.actual) ?=(%var -.expected) ?=(%avar -.expected) ?=(%nvar -.expected))
5060+ =/ actual-open=?
5061+ |(?=(%var -.actual) ?=(%avar -.actual) ?=(%nvar -.actual))
50605062 =. actual (itype-walk actual sub)
50615063 =. expected (itype-walk expected sub)
50625064 ?: =(actual expected) [%ok sub next]
@@ -5080,6 +5082,15 @@
50805082 =/ unified=(unit isub) (itype-unify-args args.actual args.expected sub)
50815083 ?^ unified [%ok u.unified next]
50825084 [%unknown ~]
5085+ :: A known union can instantiate an unconstrained sample directly;
5086+ :: preserve unknown results for variable-bound union origins.
5087+ ?: &(!actual-open ?=(%union -.actual) ?=(%var -.expected))
5088+ ?~ origin.actual [%unknown ~]
5089+ =/ normalized=itype (itype-normalize actual sub)
5090+ ?: |((itype-has-tag normalized) (itype-has-recursive normalized) (itype-has-any-atom actual sub)) [%unknown ~]
5091+ =/ unified=(unit isub) (itype-unify actual expected sub)
5092+ ?~ unified [%unknown ~]
5093+ [%ok u.unified next]
50835094 :: A concrete union value in a tuple may acquire the expected field's
50845095 :: face. A variable-bound union still needs face propagation support.
50855096 ?: &(!uncertain ?=(%union -.actual) ?=(%face -.expected))
tests/golden/types-union-polymorphic-identity/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, unions and type variables: named disjoint unions retain their origin and type arguments when passed through polymorphic gates.
2+tests: Local, imported and generic unions pass through identity; independently instantiated arguments and same-capital reuse retain their types. Different origins, incompatible generic arguments and explicit-capital forcing stay unsupported or report their established error. Faced results, self-application and unresolved tags check that constraints are not lost. The module report remains partial.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/types-union-polymorphic-identity/module-trees.txtnew file+16
@@ -0,0 +1,16 @@
1+/ui/one.jibb
2+(module
3+ (mold 1:1 tag
4+ (union 2:3 (const 2:3 %left) (const 3:3 %right)))
5+ (value 4:1 pass
6+ (gate 4:9
7+ (face 4:12 x (ref 4:14 tag))
8+ (wing 4:18 x))))
9+/ui/two.jibb
10+(module
11+ (mold 1:1 tag
12+ (union 2:3 (const 2:3 %left) (const 3:3 %right)))
13+ (value 4:1 pass
14+ (gate 4:9
15+ (face 4:12 x (ref 4:14 tag))
16+ (wing 4:18 x))))
tests/golden/types-union-polymorphic-identity/modules.txtnew file+2
@@ -0,0 +1,2 @@
1+/ui/one.jibb
2+/ui/two.jibb
tests/golden/types-union-polymorphic-identity/modules/ui/one.jibbnew file+4
@@ -0,0 +1,4 @@
1++$ tag
2+ %left
3+ %right
4+++ pass |= x=tag x
tests/golden/types-union-polymorphic-identity/modules/ui/two.jibbnew file+4
@@ -0,0 +1,4 @@
1++$ tag
2+ %left
3+ %right
4+++ pass |= x=tag x
tests/golden/types-union-polymorphic-identity/source.jibbnew file+33
@@ -0,0 +1,33 @@
1+/= one /ui/one
2+/= two /ui/two
3++$ local-msg
4+ %left
5+ %right
6++$ other-msg
7+ %left
8+ %right
9++$ choice |$ [A]
10+ [%some value=A]
11+ %none
12+++ local-id |= x x
13+++ select-first |= [a=A b=A] a
14+++ use-local |= x=local-msg (local-id x)
15+++ use-other |= x=other-msg (local-id x)
16+++ use-import |= x=tag.one (local-id x)
17+++ use-different |= [a=local-msg b=other-msg] (select-first a b)
18+++ use-import-origins |= [a=tag.one b=tag.two] (select-first a b)
19+++ generic |= x=(choice A) (local-id x)
20+++ as-text |= x=(choice @t) (generic x)
21+++ as-ship |= x=(choice @p) (generic x)
22+++ repeated |= [a=(choice A) b=(choice A)] (select-first a b)
23+++ mismatch |= [a=(choice @t) b=(choice @p)] (select-first a b)
24+++ face-result |= x=local-msg (local-id [field=x flag=%.y])
25+++ explicit |= [x=A y=local-msg] (select-first x y)
26+++ pending |= x=local-msg
27+ ~& %dangling
28+ (local-id x)
29+++ unresolved (local-id %dangling)
30+++ same-choice |= [a=(choice A) b=(choice A)] (select-first a b)
31+++ distinct-choice |= [a=(choice A) b=(choice B)] (select-first a b)
32+++ self-apply |= x (x x)
33+++ faced-choice |= x=(choice A) ^- [item=(choice A) flag=?] [item=(local-id x) flag=%.y]
tests/golden/types-union-polymorphic-identity/tokens.txtnew file+368
@@ -0,0 +1,368 @@
1+1:1 glyph /=
2+1:4 name one
3+1:8 glyph /
4+1:9 tight knot ui
5+1:11 tight glyph /
6+1:12 tight knot one
7+2:1 NEWLINE
8+2:1 glyph /=
9+2:4 name two
10+2:8 glyph /
11+2:9 tight knot ui
12+2:11 tight glyph /
13+2:12 tight knot two
14+3:1 NEWLINE
15+3:1 glyph +$
16+3:4 name local-msg
17+4:3 INDENT
18+4:3 lit %left
19+5:3 NEWLINE
20+5:3 lit %right
21+6:1 DEDENT
22+6:1 NEWLINE
23+6:1 glyph +$
24+6:4 name other-msg
25+7:3 INDENT
26+7:3 lit %left
27+8:3 NEWLINE
28+8:3 lit %right
29+9:1 DEDENT
30+9:1 NEWLINE
31+9:1 glyph +$
32+9:4 name choice
33+9:11 glyph |$
34+9:14 glyph [
35+9:15 tight tvar A
36+9:16 tight glyph ]
37+10:3 INDENT
38+10:3 glyph [
39+10:4 tight lit %some
40+10:10 name value
41+10:15 tight glyph =
42+10:16 tight tvar A
43+10:17 tight glyph ]
44+11:3 NEWLINE
45+11:3 lit %none
46+12:1 DEDENT
47+12:1 NEWLINE
48+12:1 glyph ++
49+12:4 name local-id
50+12:13 glyph |=
51+12:16 name x
52+12:18 name x
53+13:1 NEWLINE
54+13:1 glyph ++
55+13:4 name select-first
56+13:17 glyph |=
57+13:20 glyph [
58+13:21 tight name a
59+13:22 tight glyph =
60+13:23 tight tvar A
61+13:25 name b
62+13:26 tight glyph =
63+13:27 tight tvar A
64+13:28 tight glyph ]
65+13:30 name a
66+14:1 NEWLINE
67+14:1 glyph ++
68+14:4 name use-local
69+14:14 glyph |=
70+14:17 name x
71+14:18 tight glyph =
72+14:19 tight name local-msg
73+14:29 glyph (
74+14:30 tight name local-id
75+14:39 name x
76+14:40 tight glyph )
77+15:1 NEWLINE
78+15:1 glyph ++
79+15:4 name use-other
80+15:14 glyph |=
81+15:17 name x
82+15:18 tight glyph =
83+15:19 tight name other-msg
84+15:29 glyph (
85+15:30 tight name local-id
86+15:39 name x
87+15:40 tight glyph )
88+16:1 NEWLINE
89+16:1 glyph ++
90+16:4 name use-import
91+16:15 glyph |=
92+16:18 name x
93+16:19 tight glyph =
94+16:20 tight wing tag.one
95+16:28 glyph (
96+16:29 tight name local-id
97+16:38 name x
98+16:39 tight glyph )
99+17:1 NEWLINE
100+17:1 glyph ++
101+17:4 name use-different
102+17:18 glyph |=
103+17:21 glyph [
104+17:22 tight name a
105+17:23 tight glyph =
106+17:24 tight name local-msg
107+17:34 name b
108+17:35 tight glyph =
109+17:36 tight name other-msg
110+17:45 tight glyph ]
111+17:47 glyph (
112+17:48 tight name select-first
113+17:61 name a
114+17:63 name b
115+17:64 tight glyph )
116+18:1 NEWLINE
117+18:1 glyph ++
118+18:4 name use-import-origins
119+18:23 glyph |=
120+18:26 glyph [
121+18:27 tight name a
122+18:28 tight glyph =
123+18:29 tight wing tag.one
124+18:37 name b
125+18:38 tight glyph =
126+18:39 tight wing tag.two
127+18:46 tight glyph ]
128+18:48 glyph (
129+18:49 tight name select-first
130+18:62 name a
131+18:64 name b
132+18:65 tight glyph )
133+19:1 NEWLINE
134+19:1 glyph ++
135+19:4 name generic
136+19:12 glyph |=
137+19:15 name x
138+19:16 tight glyph =
139+19:17 tight glyph (
140+19:18 tight name choice
141+19:25 tvar A
142+19:26 tight glyph )
143+19:28 glyph (
144+19:29 tight name local-id
145+19:38 name x
146+19:39 tight glyph )
147+20:1 NEWLINE
148+20:1 glyph ++
149+20:4 name as-text
150+20:12 glyph |=
151+20:15 name x
152+20:16 tight glyph =
153+20:17 tight glyph (
154+20:18 tight name choice
155+20:25 aura @t
156+20:27 tight glyph )
157+20:29 glyph (
158+20:30 tight name generic
159+20:38 name x
160+20:39 tight glyph )
161+21:1 NEWLINE
162+21:1 glyph ++
163+21:4 name as-ship
164+21:12 glyph |=
165+21:15 name x
166+21:16 tight glyph =
167+21:17 tight glyph (
168+21:18 tight name choice
169+21:25 aura @p
170+21:27 tight glyph )
171+21:29 glyph (
172+21:30 tight name generic
173+21:38 name x
174+21:39 tight glyph )
175+22:1 NEWLINE
176+22:1 glyph ++
177+22:4 name repeated
178+22:13 glyph |=
179+22:16 glyph [
180+22:17 tight name a
181+22:18 tight glyph =
182+22:19 tight glyph (
183+22:20 tight name choice
184+22:27 tvar A
185+22:28 tight glyph )
186+22:30 name b
187+22:31 tight glyph =
188+22:32 tight glyph (
189+22:33 tight name choice
190+22:40 tvar A
191+22:41 tight glyph )
192+22:42 tight glyph ]
193+22:44 glyph (
194+22:45 tight name select-first
195+22:58 name a
196+22:60 name b
197+22:61 tight glyph )
198+23:1 NEWLINE
199+23:1 glyph ++
200+23:4 name mismatch
201+23:13 glyph |=
202+23:16 glyph [
203+23:17 tight name a
204+23:18 tight glyph =
205+23:19 tight glyph (
206+23:20 tight name choice
207+23:27 aura @t
208+23:29 tight glyph )
209+23:31 name b
210+23:32 tight glyph =
211+23:33 tight glyph (
212+23:34 tight name choice
213+23:41 aura @p
214+23:43 tight glyph )
215+23:44 tight glyph ]
216+23:46 glyph (
217+23:47 tight name select-first
218+23:60 name a
219+23:62 name b
220+23:63 tight glyph )
221+24:1 NEWLINE
222+24:1 glyph ++
223+24:4 name face-result
224+24:16 glyph |=
225+24:19 name x
226+24:20 tight glyph =
227+24:21 tight name local-msg
228+24:31 glyph (
229+24:32 tight name local-id
230+24:41 glyph [
231+24:42 tight name field
232+24:47 tight glyph =
233+24:48 tight name x
234+24:50 name flag
235+24:54 tight glyph =
236+24:55 tight lit %.y
237+24:58 tight glyph ]
238+24:59 tight glyph )
239+25:1 NEWLINE
240+25:1 glyph ++
241+25:4 name explicit
242+25:13 glyph |=
243+25:16 glyph [
244+25:17 tight name x
245+25:18 tight glyph =
246+25:19 tight tvar A
247+25:21 name y
248+25:22 tight glyph =
249+25:23 tight name local-msg
250+25:32 tight glyph ]
251+25:34 glyph (
252+25:35 tight name select-first
253+25:48 name x
254+25:50 name y
255+25:51 tight glyph )
256+26:1 NEWLINE
257+26:1 glyph ++
258+26:4 name pending
259+26:12 glyph |=
260+26:15 name x
261+26:16 tight glyph =
262+26:17 tight name local-msg
263+27:3 INDENT
264+27:3 glyph ~&
265+27:6 lit %dangling
266+28:5 INDENT
267+28:5 glyph (
268+28:6 tight name local-id
269+28:15 name x
270+28:16 tight glyph )
271+29:1 DEDENT
272+29:1 DEDENT
273+29:1 NEWLINE
274+29:1 glyph ++
275+29:4 name unresolved
276+29:15 glyph (
277+29:16 tight name local-id
278+29:25 lit %dangling
279+29:34 tight glyph )
280+30:1 NEWLINE
281+30:1 glyph ++
282+30:4 name same-choice
283+30:16 glyph |=
284+30:19 glyph [
285+30:20 tight name a
286+30:21 tight glyph =
287+30:22 tight glyph (
288+30:23 tight name choice
289+30:30 tvar A
290+30:31 tight glyph )
291+30:33 name b
292+30:34 tight glyph =
293+30:35 tight glyph (
294+30:36 tight name choice
295+30:43 tvar A
296+30:44 tight glyph )
297+30:45 tight glyph ]
298+30:47 glyph (
299+30:48 tight name select-first
300+30:61 name a
301+30:63 name b
302+30:64 tight glyph )
303+31:1 NEWLINE
304+31:1 glyph ++
305+31:4 name distinct-choice
306+31:20 glyph |=
307+31:23 glyph [
308+31:24 tight name a
309+31:25 tight glyph =
310+31:26 tight glyph (
311+31:27 tight name choice
312+31:34 tvar A
313+31:35 tight glyph )
314+31:37 name b
315+31:38 tight glyph =
316+31:39 tight glyph (
317+31:40 tight name choice
318+31:47 tvar B
319+31:48 tight glyph )
320+31:49 tight glyph ]
321+31:51 glyph (
322+31:52 tight name select-first
323+31:65 name a
324+31:67 name b
325+31:68 tight glyph )
326+32:1 NEWLINE
327+32:1 glyph ++
328+32:4 name self-apply
329+32:15 glyph |=
330+32:18 name x
331+32:20 glyph (
332+32:21 tight name x
333+32:23 name x
334+32:24 tight glyph )
335+33:1 NEWLINE
336+33:1 glyph ++
337+33:4 name faced-choice
338+33:17 glyph |=
339+33:20 name x
340+33:21 tight glyph =
341+33:22 tight glyph (
342+33:23 tight name choice
343+33:30 tvar A
344+33:31 tight glyph )
345+33:33 glyph ^-
346+33:36 glyph [
347+33:37 tight name item
348+33:41 tight glyph =
349+33:42 tight glyph (
350+33:43 tight name choice
351+33:50 tvar A
352+33:51 tight glyph )
353+33:53 name flag
354+33:57 tight glyph =
355+33:58 tight glyph ?
356+33:59 tight glyph ]
357+33:61 glyph [
358+33:62 tight name item
359+33:66 tight glyph =
360+33:67 tight glyph (
361+33:68 tight name local-id
362+33:77 name x
363+33:78 tight glyph )
364+33:80 name flag
365+33:84 tight glyph =
366+33:85 tight lit %.y
367+33:88 tight glyph ]
368+33:89 NEWLINE
tests/golden/types-union-polymorphic-identity/tree.txtnew file+152
@@ -0,0 +1,152 @@
1+(module
2+ (jibb 1:1 one /ui/one)
3+ (jibb 2:1 two /ui/two)
4+ (mold 3:1 local-msg
5+ (union 4:3 (const 4:3 %left) (const 5:3 %right)))
6+ (mold 6:1 other-msg
7+ (union 7:3 (const 7:3 %left) (const 8:3 %right)))
8+ (mold 9:1 choice
9+ (generic 9:11 A
10+ (union 10:3
11+ (cell 10:3
12+ (const 10:4 %some)
13+ (face 10:10 value (tvar 10:16 A)))
14+ (const 11:3 %none))))
15+ (value 12:1 local-id
16+ (gate 12:13 (bind 12:16 x) (wing 12:18 x)))
17+ (value 13:1 select-first
18+ (gate 13:17
19+ (cell 13:20
20+ (face 13:21 a (tvar 13:23 A))
21+ (face 13:25 b (tvar 13:27 A)))
22+ (wing 13:30 a)))
23+ (value 14:1 use-local
24+ (gate 14:14
25+ (face 14:17 x (ref 14:19 local-msg))
26+ (group 14:29
27+ (call 14:30 (wing 14:30 local-id) (wing 14:39 x)))))
28+ (value 15:1 use-other
29+ (gate 15:14
30+ (face 15:17 x (ref 15:19 other-msg))
31+ (group 15:29
32+ (call 15:30 (wing 15:30 local-id) (wing 15:39 x)))))
33+ (value 16:1 use-import
34+ (gate 16:15
35+ (face 16:18 x (ref 16:20 tag.one))
36+ (group 16:28
37+ (call 16:29 (wing 16:29 local-id) (wing 16:38 x)))))
38+ (value 17:1 use-different
39+ (gate 17:18
40+ (cell 17:21
41+ (face 17:22 a (ref 17:24 local-msg))
42+ (face 17:34 b (ref 17:36 other-msg)))
43+ (group 17:47
44+ (call 17:48 (wing 17:48 select-first) (wing 17:61 a) (wing 17:63 b)))))
45+ (value 18:1 use-import-origins
46+ (gate 18:23
47+ (cell 18:26
48+ (face 18:27 a (ref 18:29 tag.one))
49+ (face 18:37 b (ref 18:39 tag.two)))
50+ (group 18:48
51+ (call 18:49 (wing 18:49 select-first) (wing 18:62 a) (wing 18:64 b)))))
52+ (value 19:1 generic
53+ (gate 19:12
54+ (face 19:15 x
55+ (apply 19:17 choice (tvar 19:25 A)))
56+ (group 19:28
57+ (call 19:29 (wing 19:29 local-id) (wing 19:38 x)))))
58+ (value 20:1 as-text
59+ (gate 20:12
60+ (face 20:15 x
61+ (apply 20:17 choice (aura 20:25 @t)))
62+ (group 20:29
63+ (call 20:30 (wing 20:30 generic) (wing 20:38 x)))))
64+ (value 21:1 as-ship
65+ (gate 21:12
66+ (face 21:15 x
67+ (apply 21:17 choice (aura 21:25 @p)))
68+ (group 21:29
69+ (call 21:30 (wing 21:30 generic) (wing 21:38 x)))))
70+ (value 22:1 repeated
71+ (gate 22:13
72+ (cell 22:16
73+ (face 22:17 a
74+ (apply 22:19 choice (tvar 22:27 A)))
75+ (face 22:30 b
76+ (apply 22:32 choice (tvar 22:40 A))))
77+ (group 22:44
78+ (call 22:45 (wing 22:45 select-first) (wing 22:58 a) (wing 22:60 b)))))
79+ (value 23:1 mismatch
80+ (gate 23:13
81+ (cell 23:16
82+ (face 23:17 a
83+ (apply 23:19 choice (aura 23:27 @t)))
84+ (face 23:31 b
85+ (apply 23:33 choice (aura 23:41 @p))))
86+ (group 23:46
87+ (call 23:47 (wing 23:47 select-first) (wing 23:60 a) (wing 23:62 b)))))
88+ (value 24:1 face-result
89+ (gate 24:16
90+ (face 24:19 x (ref 24:21 local-msg))
91+ (group 24:31
92+ (call 24:32
93+ (wing 24:32 local-id)
94+ (tuple 24:41
95+ (face 24:42 field (wing 24:48 x))
96+ (face 24:50 flag (lit 24:55 %.y)))))))
97+ (value 25:1 explicit
98+ (gate 25:13
99+ (cell 25:16
100+ (face 25:17 x (tvar 25:19 A))
101+ (face 25:21 y (ref 25:23 local-msg)))
102+ (group 25:34
103+ (call 25:35 (wing 25:35 select-first) (wing 25:48 x) (wing 25:50 y)))))
104+ (value 26:1 pending
105+ (gate 26:12
106+ (face 26:15 x (ref 26:17 local-msg))
107+ (body 27:3
108+ (trace 27:3
109+ (lit 27:6 %dangling)
110+ (body 28:5
111+ (group 28:5
112+ (call 28:6 (wing 28:6 local-id) (wing 28:15 x))))))))
113+ (value 29:1 unresolved
114+ (group 29:15
115+ (call 29:16 (wing 29:16 local-id) (lit 29:25 %dangling))))
116+ (value 30:1 same-choice
117+ (gate 30:16
118+ (cell 30:19
119+ (face 30:20 a
120+ (apply 30:22 choice (tvar 30:30 A)))
121+ (face 30:33 b
122+ (apply 30:35 choice (tvar 30:43 A))))
123+ (group 30:47
124+ (call 30:48 (wing 30:48 select-first) (wing 30:61 a) (wing 30:63 b)))))
125+ (value 31:1 distinct-choice
126+ (gate 31:20
127+ (cell 31:23
128+ (face 31:24 a
129+ (apply 31:26 choice (tvar 31:34 A)))
130+ (face 31:37 b
131+ (apply 31:39 choice (tvar 31:47 B))))
132+ (group 31:51
133+ (call 31:52 (wing 31:52 select-first) (wing 31:65 a) (wing 31:67 b)))))
134+ (value 32:1 self-apply
135+ (gate 32:15
136+ (bind 32:18 x)
137+ (group 32:20
138+ (call 32:21 (wing 32:21 x) (wing 32:23 x)))))
139+ (value 33:1 faced-choice
140+ (gate 33:17
141+ (face 33:20 x
142+ (apply 33:22 choice (tvar 33:30 A)))
143+ (cast 33:33
144+ (cell 33:36
145+ (face 33:37 item
146+ (apply 33:42 choice (tvar 33:50 A)))
147+ (face 33:53 flag (flag 33:58)))
148+ (tuple 33:61
149+ (face 33:62 item
150+ (group 33:67
151+ (call 33:68 (wing 33:68 local-id) (wing 33:77 x))))
152+ (face 33:80 flag (lit 33:85 %.y)))))))
tests/golden/types-union-polymorphic-identity/types.txtnew file+36
@@ -0,0 +1,36 @@
1+partial inference; module not checked
2++$ local-msg: cases proven disjoint; mold not checked
3++$ other-msg: cases proven disjoint; mold not checked
4++$ choice: cases proven disjoint; mold not checked
5+++ local-id: $-(A A)
6+++ select-first: $-([a=A b=A] A)
7+++ use-local: $-(local-msg local-msg)
8+++ use-other: $-(other-msg other-msg)
9+++ use-import: $-(tag.one tag.one)
10+++ use-different: call constraint is not supported by partial inference
11+++ use-import-origins: call constraint is not supported by partial inference
12+++ generic: $-((choice A) (choice A))
13+++ as-text: $-((choice @t) (choice @t))
14+++ as-ship: $-((choice @p) (choice @p))
15+++ repeated: $-([a=(choice A) b=(choice A)] (choice A))
16+++ mismatch: call constraint is not supported by partial inference
17+++ face-result: $-(local-msg [field=local-msg flag=?])
18+++ explicit: call constraint is not supported by partial inference
19+++ pending: tag needs context in partial inference
20+++ unresolved: tag needs context in partial inference
21+++ same-choice: $-([a=(choice A) b=(choice A)] (choice A))
22+++ distinct-choice: distinct type variables `A` and `B` must not be forced equal; use the same capital for a shared type
23+/tests/golden/types-union-polymorphic-identity/source.jibb:31:34: first type variable
24+++ distinct-choice |= [a=(choice A) b=(choice B)] (select-first a b)
25+ ^
26+/tests/golden/types-union-polymorphic-identity/source.jibb:31:47: second type variable
27+++ distinct-choice |= [a=(choice A) b=(choice B)] (select-first a b)
28+ ^
29+++ self-apply: call's sample and argument types do not unify
30+/tests/golden/types-union-polymorphic-identity/source.jibb:32:21: called gate
31+++ self-apply |= x (x x)
32+ ^
33+/tests/golden/types-union-polymorphic-identity/source.jibb:32:23: argument
34+++ self-apply |= x (x x)
35+ ^
36+++ faced-choice: $-((choice A) [item=(choice A) flag=?])
tests/lib/jibb.hoon+110−101
@@ -2007,89 +2007,96 @@
20072007/* tok-555 %txt /tests/golden/types-union-phantom-generic/tokens/txt
20082008/* tre-555 %txt /tests/golden/types-union-phantom-generic/tree/txt
20092009/* typ-555 %txt /tests/golden/types-union-phantom-generic/types/txt
2010−/* src-556 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
2011−/* tok-556 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
2012−/* tre-556 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
2013−/* mod-556-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
2014−/* typ-556 %txt /tests/golden/types-union-print-cross-namespace/types/txt
2015−/* mtre-556 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
2016−/* src-557 %jibb /tests/golden/types-union-print-distinct/source/jibb
2017−/* tok-557 %txt /tests/golden/types-union-print-distinct/tokens/txt
2018−/* tre-557 %txt /tests/golden/types-union-print-distinct/tree/txt
2019−/* mod-557-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
2020−/* mod-557-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
2021−/* mod-557-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
2022−/* typ-557 %txt /tests/golden/types-union-print-distinct/types/txt
2023−/* mtre-557 %txt /tests/golden/types-union-print-distinct/module-trees/txt
2024−/* src-558 %jibb /tests/golden/types-union-print-escape/source/jibb
2025−/* tok-558 %txt /tests/golden/types-union-print-escape/tokens/txt
2026−/* tre-558 %txt /tests/golden/types-union-print-escape/tree/txt
2027−/* typ-558 %txt /tests/golden/types-union-print-escape/types/txt
2028−/* src-559 %jibb /tests/golden/types-union-print-local/source/jibb
2029−/* tok-559 %txt /tests/golden/types-union-print-local/tokens/txt
2030−/* tre-559 %txt /tests/golden/types-union-print-local/tree/txt
2031−/* typ-559 %txt /tests/golden/types-union-print-local/types/txt
2032−/* src-560 %jibb /tests/golden/types-union-print-nested/source/jibb
2033−/* tok-560 %txt /tests/golden/types-union-print-nested/tokens/txt
2034−/* tre-560 %txt /tests/golden/types-union-print-nested/tree/txt
2035−/* typ-560 %txt /tests/golden/types-union-print-nested/types/txt
2036−/* src-561 %jibb /tests/golden/types-union-print-same-origin/source/jibb
2037−/* tok-561 %txt /tests/golden/types-union-print-same-origin/tokens/txt
2038−/* tre-561 %txt /tests/golden/types-union-print-same-origin/tree/txt
2039−/* mod-561-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
2040−/* typ-561 %txt /tests/golden/types-union-print-same-origin/types/txt
2041−/* mtre-561 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
2042−/* src-562 %jibb /tests/golden/types-union-print-transitive/source/jibb
2043−/* tok-562 %txt /tests/golden/types-union-print-transitive/tokens/txt
2044−/* tre-562 %txt /tests/golden/types-union-print-transitive/tree/txt
2045−/* mod-562-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
2046−/* mod-562-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
2047−/* typ-562 %txt /tests/golden/types-union-print-transitive/types/txt
2048−/* mtre-562 %txt /tests/golden/types-union-print-transitive/module-trees/txt
2049−/* src-563 %jibb /tests/golden/types-union-singleton/source/jibb
2050−/* tok-563 %txt /tests/golden/types-union-singleton/tokens/txt
2051−/* tre-563 %txt /tests/golden/types-union-singleton/tree/txt
2052−/* typ-563 %txt /tests/golden/types-union-singleton/types/txt
2053−/* src-564 %jibb /tests/golden/types-union-tag-atoms/source/jibb
2054−/* tok-564 %txt /tests/golden/types-union-tag-atoms/tokens/txt
2055−/* tre-564 %txt /tests/golden/types-union-tag-atoms/tree/txt
2056−/* typ-564 %txt /tests/golden/types-union-tag-atoms/types/txt
2057−/* src-565 %jibb /tests/golden/types-union-tags/source/jibb
2058−/* tok-565 %txt /tests/golden/types-union-tags/tokens/txt
2059−/* tre-565 %txt /tests/golden/types-union-tags/tree/txt
2060−/* typ-565 %txt /tests/golden/types-union-tags/types/txt
2061−/* src-566 %jibb /tests/golden/types-union-unresolved/source/jibb
2062−/* tok-566 %txt /tests/golden/types-union-unresolved/tokens/txt
2063−/* tre-566 %txt /tests/golden/types-union-unresolved/tree/txt
2064−/* typ-566 %txt /tests/golden/types-union-unresolved/types/txt
2065−/* src-567 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
2066−/* tok-567 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
2067−/* tre-567 %txt /tests/golden/types-union-unresolved-flow/tree/txt
2068−/* typ-567 %txt /tests/golden/types-union-unresolved-flow/types/txt
2069−/* src-568 %jibb /tests/golden/types-unit-construction/source/jibb
2070−/* tok-568 %txt /tests/golden/types-unit-construction/tokens/txt
2071−/* tre-568 %txt /tests/golden/types-unit-construction/tree/txt
2072−/* typ-568 %txt /tests/golden/types-unit-construction/types/txt
2073−/* src-569 %jibb /tests/golden/types-unit-context/source/jibb
2074−/* tok-569 %txt /tests/golden/types-unit-context/tokens/txt
2075−/* tre-569 %txt /tests/golden/types-unit-context/tree/txt
2076−/* typ-569 %txt /tests/golden/types-unit-context/types/txt
2077−/* src-570 %jibb /tests/golden/types-unit-patterns/source/jibb
2078−/* tok-570 %txt /tests/golden/types-unit-patterns/tokens/txt
2079−/* tre-570 %txt /tests/golden/types-unit-patterns/tree/txt
2080−/* typ-570 %txt /tests/golden/types-unit-patterns/types/txt
2081−/* src-571 %jibb /tests/golden/types-value-cycle-shadow/source/jibb
2082−/* tok-571 %txt /tests/golden/types-value-cycle-shadow/tokens/txt
2083−/* tre-571 %txt /tests/golden/types-value-cycle-shadow/tree/txt
2084−/* typ-571 %txt /tests/golden/types-value-cycle-shadow/types/txt
2085−/* src-572 %jibb /tests/golden/types-value-cycle-unsupported/source/jibb
2086−/* tok-572 %txt /tests/golden/types-value-cycle-unsupported/tokens/txt
2087−/* tre-572 %txt /tests/golden/types-value-cycle-unsupported/tree/txt
2088−/* typ-572 %txt /tests/golden/types-value-cycle-unsupported/types/txt
2089−/* src-573 %jibb /tests/golden/types-value-cycles/source/jibb
2090−/* tok-573 %txt /tests/golden/types-value-cycles/tokens/txt
2091−/* tre-573 %txt /tests/golden/types-value-cycles/tree/txt
2092−/* typ-573 %txt /tests/golden/types-value-cycles/types/txt
2010+/* src-556 %jibb /tests/golden/types-union-polymorphic-identity/source/jibb
2011+/* tok-556 %txt /tests/golden/types-union-polymorphic-identity/tokens/txt
2012+/* tre-556 %txt /tests/golden/types-union-polymorphic-identity/tree/txt
2013+/* mod-556-1 %jibb /tests/golden/types-union-polymorphic-identity/modules/ui/one/jibb
2014+/* mod-556-2 %jibb /tests/golden/types-union-polymorphic-identity/modules/ui/two/jibb
2015+/* typ-556 %txt /tests/golden/types-union-polymorphic-identity/types/txt
2016+/* mtre-556 %txt /tests/golden/types-union-polymorphic-identity/module-trees/txt
2017+/* src-557 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
2018+/* tok-557 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
2019+/* tre-557 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
2020+/* mod-557-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
2021+/* typ-557 %txt /tests/golden/types-union-print-cross-namespace/types/txt
2022+/* mtre-557 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
2023+/* src-558 %jibb /tests/golden/types-union-print-distinct/source/jibb
2024+/* tok-558 %txt /tests/golden/types-union-print-distinct/tokens/txt
2025+/* tre-558 %txt /tests/golden/types-union-print-distinct/tree/txt
2026+/* mod-558-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
2027+/* mod-558-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
2028+/* mod-558-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
2029+/* typ-558 %txt /tests/golden/types-union-print-distinct/types/txt
2030+/* mtre-558 %txt /tests/golden/types-union-print-distinct/module-trees/txt
2031+/* src-559 %jibb /tests/golden/types-union-print-escape/source/jibb
2032+/* tok-559 %txt /tests/golden/types-union-print-escape/tokens/txt
2033+/* tre-559 %txt /tests/golden/types-union-print-escape/tree/txt
2034+/* typ-559 %txt /tests/golden/types-union-print-escape/types/txt
2035+/* src-560 %jibb /tests/golden/types-union-print-local/source/jibb
2036+/* tok-560 %txt /tests/golden/types-union-print-local/tokens/txt
2037+/* tre-560 %txt /tests/golden/types-union-print-local/tree/txt
2038+/* typ-560 %txt /tests/golden/types-union-print-local/types/txt
2039+/* src-561 %jibb /tests/golden/types-union-print-nested/source/jibb
2040+/* tok-561 %txt /tests/golden/types-union-print-nested/tokens/txt
2041+/* tre-561 %txt /tests/golden/types-union-print-nested/tree/txt
2042+/* typ-561 %txt /tests/golden/types-union-print-nested/types/txt
2043+/* src-562 %jibb /tests/golden/types-union-print-same-origin/source/jibb
2044+/* tok-562 %txt /tests/golden/types-union-print-same-origin/tokens/txt
2045+/* tre-562 %txt /tests/golden/types-union-print-same-origin/tree/txt
2046+/* mod-562-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
2047+/* typ-562 %txt /tests/golden/types-union-print-same-origin/types/txt
2048+/* mtre-562 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
2049+/* src-563 %jibb /tests/golden/types-union-print-transitive/source/jibb
2050+/* tok-563 %txt /tests/golden/types-union-print-transitive/tokens/txt
2051+/* tre-563 %txt /tests/golden/types-union-print-transitive/tree/txt
2052+/* mod-563-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
2053+/* mod-563-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
2054+/* typ-563 %txt /tests/golden/types-union-print-transitive/types/txt
2055+/* mtre-563 %txt /tests/golden/types-union-print-transitive/module-trees/txt
2056+/* src-564 %jibb /tests/golden/types-union-singleton/source/jibb
2057+/* tok-564 %txt /tests/golden/types-union-singleton/tokens/txt
2058+/* tre-564 %txt /tests/golden/types-union-singleton/tree/txt
2059+/* typ-564 %txt /tests/golden/types-union-singleton/types/txt
2060+/* src-565 %jibb /tests/golden/types-union-tag-atoms/source/jibb
2061+/* tok-565 %txt /tests/golden/types-union-tag-atoms/tokens/txt
2062+/* tre-565 %txt /tests/golden/types-union-tag-atoms/tree/txt
2063+/* typ-565 %txt /tests/golden/types-union-tag-atoms/types/txt
2064+/* src-566 %jibb /tests/golden/types-union-tags/source/jibb
2065+/* tok-566 %txt /tests/golden/types-union-tags/tokens/txt
2066+/* tre-566 %txt /tests/golden/types-union-tags/tree/txt
2067+/* typ-566 %txt /tests/golden/types-union-tags/types/txt
2068+/* src-567 %jibb /tests/golden/types-union-unresolved/source/jibb
2069+/* tok-567 %txt /tests/golden/types-union-unresolved/tokens/txt
2070+/* tre-567 %txt /tests/golden/types-union-unresolved/tree/txt
2071+/* typ-567 %txt /tests/golden/types-union-unresolved/types/txt
2072+/* src-568 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
2073+/* tok-568 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
2074+/* tre-568 %txt /tests/golden/types-union-unresolved-flow/tree/txt
2075+/* typ-568 %txt /tests/golden/types-union-unresolved-flow/types/txt
2076+/* src-569 %jibb /tests/golden/types-unit-construction/source/jibb
2077+/* tok-569 %txt /tests/golden/types-unit-construction/tokens/txt
2078+/* tre-569 %txt /tests/golden/types-unit-construction/tree/txt
2079+/* typ-569 %txt /tests/golden/types-unit-construction/types/txt
2080+/* src-570 %jibb /tests/golden/types-unit-context/source/jibb
2081+/* tok-570 %txt /tests/golden/types-unit-context/tokens/txt
2082+/* tre-570 %txt /tests/golden/types-unit-context/tree/txt
2083+/* typ-570 %txt /tests/golden/types-unit-context/types/txt
2084+/* src-571 %jibb /tests/golden/types-unit-patterns/source/jibb
2085+/* tok-571 %txt /tests/golden/types-unit-patterns/tokens/txt
2086+/* tre-571 %txt /tests/golden/types-unit-patterns/tree/txt
2087+/* typ-571 %txt /tests/golden/types-unit-patterns/types/txt
2088+/* src-572 %jibb /tests/golden/types-value-cycle-shadow/source/jibb
2089+/* tok-572 %txt /tests/golden/types-value-cycle-shadow/tokens/txt
2090+/* tre-572 %txt /tests/golden/types-value-cycle-shadow/tree/txt
2091+/* typ-572 %txt /tests/golden/types-value-cycle-shadow/types/txt
2092+/* src-573 %jibb /tests/golden/types-value-cycle-unsupported/source/jibb
2093+/* tok-573 %txt /tests/golden/types-value-cycle-unsupported/tokens/txt
2094+/* tre-573 %txt /tests/golden/types-value-cycle-unsupported/tree/txt
2095+/* typ-573 %txt /tests/golden/types-value-cycle-unsupported/types/txt
2096+/* src-574 %jibb /tests/golden/types-value-cycles/source/jibb
2097+/* tok-574 %txt /tests/golden/types-value-cycles/tokens/txt
2098+/* tre-574 %txt /tests/golden/types-value-cycles/tree/txt
2099+/* typ-574 %txt /tests/golden/types-value-cycles/types/txt
20932100=/ prepared-prelude (prepare-prelude-with-internal:jibb prelude-source internal-source)
20942101|%
20952102:: one arm per case
@@ -3204,42 +3211,44 @@
32043211 (weld (weld (check ~.types-union-patterns-import src-554 `tok-554 `tre-554) (check-module-types ~.types-union-patterns-import ~[%tests %golden ~.types-union-patterns-import %source %jibb] src-554 `typ-554 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-554-1]])) (check-module-trees ~.types-union-patterns-import `mtre-554 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-554-1]]))
32053212++ test-types-union-phantom-generic
32063213 (weld (check ~.types-union-phantom-generic src-555 `tok-555 `tre-555) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-555 `typ-555))
3214+++ test-types-union-polymorphic-identity
3215+ (weld (weld (check ~.types-union-polymorphic-identity src-556 `tok-556 `tre-556) (check-module-types ~.types-union-polymorphic-identity ~[%tests %golden ~.types-union-polymorphic-identity %source %jibb] src-556 `typ-556 ~ ~ ~[['/ui/one.jibb' ~[~.ui ~.one ~.jibb] mod-556-1] ['/ui/two.jibb' ~[~.ui ~.two ~.jibb] mod-556-2]])) (check-module-trees ~.types-union-polymorphic-identity `mtre-556 ~[['/ui/one.jibb' ~[~.ui ~.one ~.jibb] mod-556-1] ['/ui/two.jibb' ~[~.ui ~.two ~.jibb] mod-556-2]]))
32073216++ test-types-union-print-cross-namespace
3208− (weld (weld (check ~.types-union-print-cross-namespace src-556 `tok-556 `tre-556) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-556 `typ-556 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-556-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-556 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-556-1]]))
3217+ (weld (weld (check ~.types-union-print-cross-namespace src-557 `tok-557 `tre-557) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-557 `typ-557 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-557-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-557 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-557-1]]))
32093218++ test-types-union-print-distinct
3210− (weld (weld (check ~.types-union-print-distinct src-557 `tok-557 `tre-557) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-557 `typ-557 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-557-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-557-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-557-3]])) (check-module-trees ~.types-union-print-distinct `mtre-557 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-557-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-557-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-557-3]]))
3219+ (weld (weld (check ~.types-union-print-distinct src-558 `tok-558 `tre-558) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-558 `typ-558 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-558-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-558-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-558-3]])) (check-module-trees ~.types-union-print-distinct `mtre-558 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-558-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-558-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-558-3]]))
32113220++ test-types-union-print-escape
3212− (weld (check ~.types-union-print-escape src-558 `tok-558 `tre-558) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-558 `typ-558))
3221+ (weld (check ~.types-union-print-escape src-559 `tok-559 `tre-559) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-559 `typ-559))
32133222++ test-types-union-print-local
3214− (weld (check ~.types-union-print-local src-559 `tok-559 `tre-559) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-559 `typ-559))
3223+ (weld (check ~.types-union-print-local src-560 `tok-560 `tre-560) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-560 `typ-560))
32153224++ test-types-union-print-nested
3216− (weld (check ~.types-union-print-nested src-560 `tok-560 `tre-560) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-560 `typ-560))
3225+ (weld (check ~.types-union-print-nested src-561 `tok-561 `tre-561) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-561 `typ-561))
32173226++ test-types-union-print-same-origin
3218− (weld (weld (check ~.types-union-print-same-origin src-561 `tok-561 `tre-561) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-561 `typ-561 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-561-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-561 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-561-1]]))
3227+ (weld (weld (check ~.types-union-print-same-origin src-562 `tok-562 `tre-562) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-562 `typ-562 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-562-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-562 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-562-1]]))
32193228++ test-types-union-print-transitive
3220− (weld (weld (check ~.types-union-print-transitive src-562 `tok-562 `tre-562) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-562 `typ-562 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-562-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-562-2]])) (check-module-trees ~.types-union-print-transitive `mtre-562 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-562-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-562-2]]))
3229+ (weld (weld (check ~.types-union-print-transitive src-563 `tok-563 `tre-563) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-563 `typ-563 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-563-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-563-2]])) (check-module-trees ~.types-union-print-transitive `mtre-563 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-563-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-563-2]]))
32213230++ test-types-union-singleton
3222− (weld (check ~.types-union-singleton src-563 `tok-563 `tre-563) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-563 `typ-563))
3231+ (weld (check ~.types-union-singleton src-564 `tok-564 `tre-564) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-564 `typ-564))
32233232++ test-types-union-tag-atoms
3224− (weld (check ~.types-union-tag-atoms src-564 `tok-564 `tre-564) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-564 `typ-564))
3233+ (weld (check ~.types-union-tag-atoms src-565 `tok-565 `tre-565) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-565 `typ-565))
32253234++ test-types-union-tags
3226− (weld (check ~.types-union-tags src-565 `tok-565 `tre-565) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-565 `typ-565))
3235+ (weld (check ~.types-union-tags src-566 `tok-566 `tre-566) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-566 `typ-566))
32273236++ test-types-union-unresolved
3228− (weld (check ~.types-union-unresolved src-566 `tok-566 `tre-566) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-566 `typ-566))
3237+ (weld (check ~.types-union-unresolved src-567 `tok-567 `tre-567) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-567 `typ-567))
32293238++ test-types-union-unresolved-flow
3230− (weld (check ~.types-union-unresolved-flow src-567 `tok-567 `tre-567) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-567 `typ-567))
3239+ (weld (check ~.types-union-unresolved-flow src-568 `tok-568 `tre-568) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-568 `typ-568))
32313240++ test-types-unit-construction
3232− (weld (check ~.types-unit-construction src-568 `tok-568 `tre-568) (check-module-types ~.types-unit-construction ~[%tests %golden ~.types-unit-construction %source %jibb] src-568 `typ-568 ~ ~ ~))
3241+ (weld (check ~.types-unit-construction src-569 `tok-569 `tre-569) (check-module-types ~.types-unit-construction ~[%tests %golden ~.types-unit-construction %source %jibb] src-569 `typ-569 ~ ~ ~))
32333242++ test-types-unit-context
3234− (weld (check ~.types-unit-context src-569 `tok-569 `tre-569) (check-module-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-569 `typ-569 ~ ~ ~))
3243+ (weld (check ~.types-unit-context src-570 `tok-570 `tre-570) (check-module-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-570 `typ-570 ~ ~ ~))
32353244++ test-types-unit-patterns
3236− (weld (check ~.types-unit-patterns src-570 `tok-570 `tre-570) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-570 `typ-570))
3245+ (weld (check ~.types-unit-patterns src-571 `tok-571 `tre-571) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-571 `typ-571))
32373246++ test-types-value-cycle-shadow
3238− (weld (check ~.types-value-cycle-shadow src-571 `tok-571 `tre-571) (check-module-types ~.types-value-cycle-shadow ~[%tests %golden ~.types-value-cycle-shadow %source %jibb] src-571 `typ-571 ~ ~ ~))
3247+ (weld (check ~.types-value-cycle-shadow src-572 `tok-572 `tre-572) (check-module-types ~.types-value-cycle-shadow ~[%tests %golden ~.types-value-cycle-shadow %source %jibb] src-572 `typ-572 ~ ~ ~))
32393248++ test-types-value-cycle-unsupported
3240− (weld (check ~.types-value-cycle-unsupported src-572 `tok-572 `tre-572) (check-module-types ~.types-value-cycle-unsupported ~[%tests %golden ~.types-value-cycle-unsupported %source %jibb] src-572 `typ-572 ~ ~ ~))
3249+ (weld (check ~.types-value-cycle-unsupported src-573 `tok-573 `tre-573) (check-module-types ~.types-value-cycle-unsupported ~[%tests %golden ~.types-value-cycle-unsupported %source %jibb] src-573 `typ-573 ~ ~ ~))
32413250++ test-types-value-cycles
3242− (weld (check ~.types-value-cycles src-573 `tok-573 `tre-573) (check-module-types ~.types-value-cycles ~[%tests %golden ~.types-value-cycles %source %jibb] src-573 `typ-573 ~ ~ ~))
3251+ (weld (check ~.types-value-cycles src-574 `tok-574 `tre-574) (check-module-types ~.types-value-cycles ~[%tests %golden ~.types-value-cycles %source %jibb] src-574 `typ-574 ~ ~ ~))
32433252::
32443253:: +check: run golden:jibb on a case and compare both outputs
32453254::