on master help sign in
Preserve named samples in recursive gates
commit918acbdb43b6104a6a79b731d0c178f6bdd70ea4 authoriko <mail@iko.soy> dateFri 30 Oct 2026, 22:36 (10 hours ago) parentc7082e0
12 files changed+787−151
docs/compiler.md+1−1 docs/status.md+7−6 jibb-dev/lib/jibb.hoon+23−7 tests/golden/types-list-branch/types.txt+7−1 tests/golden/types-recursive-branch/types.txt+14−2 tests/golden/types-recursive-gate/types.txt+7−1 tests/golden/types-recursive-sample/about.txt+4 tests/golden/types-recursive-sample/source.jibb+40 tests/golden/types-recursive-sample/tokens.txt+344 tests/golden/types-recursive-sample/tree.txt+161 tests/golden/types-recursive-sample/types.txt+40 tests/lib/jibb.hoon+139−133
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 two-binder cell pattern, a complete two-arm loobean branch, a complete two-arm unit-shaped branch, closed local mold aliases and acyclic forward value references. A supported single syntactic top-level gate can refer to itself through one monomorphic placeholder; the completed body must unify with it before the gate is generalized. 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. Mutual groups, local recursive gates, polymorphic recursion and value cycles remain unsupported. Acyclic local value definitions can refer forward and generalize variables that are free of their enclosing environment; captured variables and explicit capitals remain shared. 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 remains unsupported, as do recursive local groups and recursive molds. 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. The reporting path repeats inference of a recursive gate rather than instantiating its generalized interface inside its own body. 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 two-binder cell pattern, 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. Mutual groups, local recursive gates, polymorphic recursion and value cycles remain unsupported. Acyclic local value definitions can refer forward and generalize variables that are free of their enclosing environment; captured variables and explicit capitals remain shared. 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 remains unsupported, as do recursive local groups and recursive molds. 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. The reporting path repeats inference of a recursive gate rather than instantiating its generalized interface inside its own body. 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
6161For supported closed unions, the type printer keeps the union’s origin separate from its displayed name. It prints an in-scope name such as `msg` or `msg.lib`, including in records and gates; an accessible imported nongeneric alias may name a transitive union. A nongeneric body-local union that escapes its scope, or an origin without an accessible name, prints its cases separated by spaces, parenthesized when nested. That case-list form is print-only. A supported generic union prints its name and all arguments, including unused arguments; when its name is unavailable, the partial printer reports that limitation instead of dropping its arguments. Two faces for the same imported origin remain compatible; compatibility between distinct union origins, including in gate types, remains unsupported. Some comparisons of generic union arguments also remain unsupported rather than deciding equality or mismatch. The Hoon bridge also translates some imported unnamed unions into this representation; unsupported cases remain errors.
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 selected Hoon atoms, term singletons, 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 prelude collection operations are not yet connected; malformed names and arities fail closed. Selected self-recursive `/sur` molds cross as opaque module-and-name identities; aliases, foreign references, recursive marks, unfolding and construction remain unsupported. The reader handles mark samples, recursive molds whose origins can be verified through Ford imports, nested collections, direct ordered maps, 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. 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. 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, and detects missing sources and cycles. It does not yet check API or kind semantics, and 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 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. 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. A recursive gate uses one monomorphic self reference while its body is inferred, then generalizes after the body is checked; subsequent uses instantiate it independently. 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. Mutual groups, local recursive gates, polymorphic recursion and value cycles remain unsupported. Reporting repeats inference for a recursive gate, so its performance cost remains unmeasured. 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. 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. Uncontextualized list construction, 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 local groups and 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 selected Hoon atoms, term singletons, 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 prelude collection operations are not yet connected; malformed names and arities fail closed. Selected self-recursive `/sur` molds cross as opaque module-and-name identities; aliases, foreign references, recursive marks, unfolding and construction remain unsupported. The reader handles mark samples, recursive molds whose origins can be verified through Ford imports, nested collections, direct ordered maps, 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. 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. 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, and detects missing sources and cycles. It does not yet check API or kind semantics, and 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 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. 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. Mutual groups, local recursive gates, polymorphic recursion and value cycles remain unsupported. Reporting repeats inference for a recursive gate, so its performance cost remains unmeasured. 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. 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. Uncontextualized list construction, 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 local groups and 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` and `need`. Unsupported entries such as most list helpers remain reserved but unavailable. 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−- 510 golden cases: 294 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 510-case corpus passed under `urbit eval` in 57.8 s. The fake ship passed all 515 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 28.2 s for sync and 33.9 s for tests. The importer golden compares 141 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+- 511 golden cases: 295 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 511-case corpus passed under `urbit eval` in 57.7 s. The fake ship passed all 516 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 28.8 s for sync and 33.7 s for tests. The importer golden compares 141 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) and `tools/testdata/ship-selftest` test the tools themselves.
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).
@@ -86,14 +86,15 @@ Besides the plan's list:
8686| 7e69436 | 2026-10-30 | Infer selected self-recursive gates |
8787| 9ab52e8 | 2026-10-30 | Infer recursive branches with closed base types |
8888| d782b45 | 2026-10-30 | Propagate list context and apply settled type decisions |
89−| This change | 2026-10-30 | Infer multi-argument calls |
89+| c7082e0 | 2026-10-30 | Infer multi-argument calls |
90+| This change | 2026-10-30 | Infer recursive gates from their samples first |
9091
9192## Checking it
9293
9394On a machine set up as [development.md](development.md) says:
9495
9596```
96−tools/golden # 510 cases under urbit eval
97+tools/golden # 511 cases under urbit eval
9798tools/importer-test # the Hoon importer fixture projection
9899tools/type-import-test # the importer/checker bridge fixture
99100tools/type-mark-test # the mark/checker bridge fixture
@@ -103,7 +104,7 @@ tools/testdata/selftest # the tools themselves
103104tools/doc-blocks docs/spec # the doc's examples are golden cases
104105tools/ship start
105106tools/ship gen-tests --check # tests/lib/jibb.hoon is up to date
106−tools/ship test # the same 510 cases as -test arms on the ship
107+tools/ship test # the same 511 cases as -test arms on the ship
107108tools/testdata/ship-selftest
108109tools/ship check-commit # |commit stores .jibb files
109110tools/clay-fixtures # example /sur files and marks build through Clay
jibb-dev/lib/jibb.hoon+23−7
@@ -6954,6 +6954,7 @@
69546954 |
69556955::
69566956:: A top-level gate may refer to itself through one monomorphic placeholder.
6957+:: Its declared sample is inferred first and preserves its field faces.
69576958:: Unify the completed body with that placeholder before generalization;
69586959:: reporting repeats the same check instead of instantiating the gate's
69596960:: generalized interface inside its own body. Mutual groups stay unsupported.
@@ -7027,16 +7028,31 @@
70277028 ?. ?=(%value -.d) [%| ["recursive definition is not a gate" ~]]
70287029 ?. |(?=(%gate -.val.d) ?=(%gate-wide -.val.d))
70297030 [%| ["recursive definition is not a gate" ~]]
7030− =/ id=@ud next.state
70317031 =/ result=(unit itype) (recursive-branch-seed d env state)
7032− =/ seed=itype ?~(result [%var id] [%fn [%var +(id)] u.result])
7033− =/ next=@ud ?~(result +(id) +(+(id)))
7034− =/ seeded=ienv [[name.d [seed ~]] env]
7035− =/ out=iresult (infer-fragment val.d seeded state(next next))
7032+ =/ gate=expr val.d
7033+ =/ sam=isample-result
7034+ ?- -.gate
7035+ %gate (infer-sample sample.gate env state)
7036+ %gate-wide (infer-sample sample.gate env state)
7037+ * !!
7038+ ==
7039+ ?: ?=(%| -.sam) [%| [p.sam ~]]
7040+ =/ id=@ud next.state.p.sam
7041+ =/ product=itype ?~(result [%var id] u.result)
7042+ =/ st=istate state.p.sam(next +(id))
7043+ =/ seed=itype [%fn typ.p.sam product]
7044+ =/ seeded=ienv [[name.d [seed ~]] env.p.sam]
7045+ =/ body=expr
7046+ ?- -.gate
7047+ %gate body.gate
7048+ %gate-wide body.gate
7049+ * !!
7050+ ==
7051+ =/ out=iresult (infer-fragment body seeded st)
70367052 ?: ?=(%| -.out) out
7037− =/ uni=(unit isub) (itype-unify seed typ.p.out sub.state.p.out)
7053+ =/ uni=(unit isub) (itype-unify product typ.p.out sub.state.p.out)
70387054 ?~ uni [%| ["recursive gate constraint is not supported by partial inference" ~]]
7039− [%& typ.p.out state.p.out(sub u.uni)]
7055+ [%& [%fn typ.p.sam typ.p.out] state.p.out(sub u.uni)]
70407056::
70417057++ add-supported-defs
70427058 |= [ds=(list def) env=ienv molds=imolds globals=(list term) externals=iexternals surs=(list term) mark-externals=imark-externals marks=(list term) jimports=ijimports reserved-molds=(list term) at=path prelude=(unit ifile)]
tests/golden/types-list-branch/types.txt+7−1
@@ -32,4 +32,10 @@ partial inference; module not checked
3232 %.y [~zod ~]
3333 ^
3434++ escape: name is not available to partial inference
35−++ bad-recursive: recursive gate constraint is not supported by partial inference
35+++ bad-recursive: call's sample and argument types do not unify
36+/tests/golden/types-list-branch/source.jibb:81:26: called gate has type $-((list @t) A)
37+ [item rest] [item (bad-recursive ~zod)]
38+ ^
39+/tests/golden/types-list-branch/source.jibb:81:40: argument has type @p
40+ [item rest] [item (bad-recursive ~zod)]
41+ ^
tests/golden/types-recursive-branch/types.txt+14−2
@@ -13,7 +13,13 @@ partial inference; module not checked
1313++ pending-null: branch widening is not supported by partial inference
1414++ dependent: $-(? @t)
1515++ nonself: $-(? @t)
16−++ polymorphic: recursive gate constraint is not supported by partial inference
16+++ polymorphic: call's sample and argument types do not unify
17+/tests/golden/types-recursive-branch/source.jibb:61:10: called gate has type $-(A @t)
18+ %.n (polymorphic [x x])
19+ ^
20+/tests/golden/types-recursive-branch/source.jibb:61:22: argument has type [A A]
21+ %.n (polymorphic [x x])
22+ ^
1723++ no-base: $-(? A)
1824++ malformed: branch does not cover both loobeans
1925++ mixed: branch arms have incompatible types
@@ -24,7 +30,13 @@ partial inference; module not checked
2430 %.n (mixed b)
2531 ^
2632++ sample-base: $-(? ?)
27−++ sample-mismatch: recursive gate constraint is not supported by partial inference
33+++ sample-mismatch: call's sample and argument types do not unify
34+/tests/golden/types-recursive-branch/source.jibb:80:10: called gate has type $-(? @t)
35+ %.n (sample-mismatch "wrong")
36+ ^
37+/tests/golden/types-recursive-branch/source.jibb:80:26: argument has type @t
38+ %.n (sample-mismatch "wrong")
39+ ^
2840++ self-subject: loobean branch subject does not unify with ?
2941++ aura-base: $-(? @u)
3042++ aura-conflict: branch arms have incompatible types
tests/golden/types-recursive-gate/types.txt+7−1
@@ -3,7 +3,13 @@ partial inference; module not checked
33++ recur: $-(A A)
44++ cord-result: @t
55++ ship-result: @p
6−++ poly: recursive gate constraint is not supported by partial inference
6+++ poly: call's sample and argument types do not unify
7+/tests/golden/types-recursive-gate/source.jibb:11:17: called gate has type $-(A B)
8+++ poly |= x=A (poly [x x])
9+ ^
10+/tests/golden/types-recursive-gate/source.jibb:11:22: argument has type [A A]
11+++ poly |= x=A (poly [x x])
12+ ^
713++ occurs: call's sample and argument types do not unify
814/tests/golden/types-recursive-gate/source.jibb:12:17: called gate
915++ occurs |= x (x x)
tests/golden/types-recursive-sample/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Modules: "Gates may call themselves and their siblings"; Modules: no name may shadow one already in scope.
2+tests: Named recursive samples retain their fields and monomorphic self type; scope violations, incompatible arguments, unresolved literals, explicit-capital constraints and recursive occurs checks are reported or fail closed.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/types-recursive-sample/source.jibbnew file+40
@@ -0,0 +1,40 @@
1+++ recurse |= [first=@t second=@p]
2+ ?- %.y
3+ %.y [first second]
4+ %.n (recurse first second)
5+++ wrong-arg |= [first=@t second=@p] (wrong-arg first first)
6+++ wrong-face |= [first=@t second=@p] (wrong-face [other=first second=second])
7+++ shadow |= [shadow=@t second=@p] (shadow shadow second)
8+++ capture |= [first=A second=B]
9+ ++ inner |= flag=? first
10+ ?- %.y
11+ %.y (inner %.y)
12+ %.n (capture first second)
13+++ alias-use |= [first=A second=A]
14+ ++ alias alias-use
15+ ~& (alias "hi" "hi")
16+ (alias ~zod ~zod)
17+++ self-apply |= [first=A second=B] (self-apply self-apply second)
18+++ forced |= [first=A second=B]
19+ ~& ^- @t first
20+ (forced first second)
21+++ pending |= [first=A second=B]
22+ ~& %unknown
23+ (pending first second)
24+++ pending-null |= [first=A second=B]
25+ ~& ~
26+ (pending-null first second)
27+++ early-base |= [first=@t second=@p]
28+ ?- %.y
29+ %.y "ok"
30+ %.n (early-base first second)
31+++ late-base |= [first=@t second=@p]
32+ ?- %.y
33+ %.n (late-base first second)
34+ %.y "ok"
35+++ generic |= [first=A second=B]
36+ ?- %.y
37+ %.y [first second]
38+ %.n (generic first second)
39+++ generic-one (generic "hi" ~zod)
40+++ generic-two (generic ~zod "hi")
tests/golden/types-recursive-sample/tokens.txtnew file+344
@@ -0,0 +1,344 @@
1+1:1 glyph ++
2+1:4 name recurse
3+1:12 glyph |=
4+1:15 glyph [
5+1:16 tight name first
6+1:21 tight glyph =
7+1:22 tight aura @t
8+1:25 name second
9+1:31 tight glyph =
10+1:32 tight aura @p
11+1:34 tight glyph ]
12+2:3 INDENT
13+2:3 glyph ?-
14+2:6 lit %.y
15+3:5 INDENT
16+3:5 lit %.y
17+3:9 glyph [
18+3:10 tight name first
19+3:16 name second
20+3:22 tight glyph ]
21+4:5 NEWLINE
22+4:5 lit %.n
23+4:9 glyph (
24+4:10 tight name recurse
25+4:18 name first
26+4:24 name second
27+4:30 tight glyph )
28+5:1 DEDENT
29+5:1 DEDENT
30+5:1 NEWLINE
31+5:1 glyph ++
32+5:4 name wrong-arg
33+5:14 glyph |=
34+5:17 glyph [
35+5:18 tight name first
36+5:23 tight glyph =
37+5:24 tight aura @t
38+5:27 name second
39+5:33 tight glyph =
40+5:34 tight aura @p
41+5:36 tight glyph ]
42+5:38 glyph (
43+5:39 tight name wrong-arg
44+5:49 name first
45+5:55 name first
46+5:60 tight glyph )
47+6:1 NEWLINE
48+6:1 glyph ++
49+6:4 name wrong-face
50+6:15 glyph |=
51+6:18 glyph [
52+6:19 tight name first
53+6:24 tight glyph =
54+6:25 tight aura @t
55+6:28 name second
56+6:34 tight glyph =
57+6:35 tight aura @p
58+6:37 tight glyph ]
59+6:39 glyph (
60+6:40 tight name wrong-face
61+6:51 glyph [
62+6:52 tight name other
63+6:57 tight glyph =
64+6:58 tight name first
65+6:64 name second
66+6:70 tight glyph =
67+6:71 tight name second
68+6:77 tight glyph ]
69+6:78 tight glyph )
70+7:1 NEWLINE
71+7:1 glyph ++
72+7:4 name shadow
73+7:11 glyph |=
74+7:14 glyph [
75+7:15 tight name shadow
76+7:21 tight glyph =
77+7:22 tight aura @t
78+7:25 name second
79+7:31 tight glyph =
80+7:32 tight aura @p
81+7:34 tight glyph ]
82+7:36 glyph (
83+7:37 tight name shadow
84+7:44 name shadow
85+7:51 name second
86+7:57 tight glyph )
87+8:1 NEWLINE
88+8:1 glyph ++
89+8:4 name capture
90+8:12 glyph |=
91+8:15 glyph [
92+8:16 tight name first
93+8:21 tight glyph =
94+8:22 tight tvar A
95+8:24 name second
96+8:30 tight glyph =
97+8:31 tight tvar B
98+8:32 tight glyph ]
99+9:3 INDENT
100+9:3 glyph ++
101+9:6 name inner
102+9:12 glyph |=
103+9:15 name flag
104+9:19 tight glyph =
105+9:20 tight glyph ?
106+9:22 name first
107+10:3 NEWLINE
108+10:3 glyph ?-
109+10:6 lit %.y
110+11:5 INDENT
111+11:5 lit %.y
112+11:9 glyph (
113+11:10 tight name inner
114+11:16 lit %.y
115+11:19 tight glyph )
116+12:5 NEWLINE
117+12:5 lit %.n
118+12:9 glyph (
119+12:10 tight name capture
120+12:18 name first
121+12:24 name second
122+12:30 tight glyph )
123+13:1 DEDENT
124+13:1 DEDENT
125+13:1 NEWLINE
126+13:1 glyph ++
127+13:4 name alias-use
128+13:14 glyph |=
129+13:17 glyph [
130+13:18 tight name first
131+13:23 tight glyph =
132+13:24 tight tvar A
133+13:26 name second
134+13:32 tight glyph =
135+13:33 tight tvar A
136+13:34 tight glyph ]
137+14:3 INDENT
138+14:3 glyph ++
139+14:6 name alias
140+14:12 name alias-use
141+15:3 NEWLINE
142+15:3 glyph ~&
143+15:6 glyph (
144+15:7 tight name alias
145+15:13 str "hi"
146+15:18 str "hi"
147+15:22 tight glyph )
148+16:5 INDENT
149+16:5 glyph (
150+16:6 tight name alias
151+16:12 lit ~zod
152+16:17 lit ~zod
153+16:21 tight glyph )
154+17:1 DEDENT
155+17:1 DEDENT
156+17:1 NEWLINE
157+17:1 glyph ++
158+17:4 name self-apply
159+17:15 glyph |=
160+17:18 glyph [
161+17:19 tight name first
162+17:24 tight glyph =
163+17:25 tight tvar A
164+17:27 name second
165+17:33 tight glyph =
166+17:34 tight tvar B
167+17:35 tight glyph ]
168+17:37 glyph (
169+17:38 tight name self-apply
170+17:49 name self-apply
171+17:60 name second
172+17:66 tight glyph )
173+18:1 NEWLINE
174+18:1 glyph ++
175+18:4 name forced
176+18:11 glyph |=
177+18:14 glyph [
178+18:15 tight name first
179+18:20 tight glyph =
180+18:21 tight tvar A
181+18:23 name second
182+18:29 tight glyph =
183+18:30 tight tvar B
184+18:31 tight glyph ]
185+19:3 INDENT
186+19:3 glyph ~&
187+19:6 glyph ^-
188+19:9 aura @t
189+19:12 name first
190+20:5 INDENT
191+20:5 glyph (
192+20:6 tight name forced
193+20:13 name first
194+20:19 name second
195+20:25 tight glyph )
196+21:1 DEDENT
197+21:1 DEDENT
198+21:1 NEWLINE
199+21:1 glyph ++
200+21:4 name pending
201+21:12 glyph |=
202+21:15 glyph [
203+21:16 tight name first
204+21:21 tight glyph =
205+21:22 tight tvar A
206+21:24 name second
207+21:30 tight glyph =
208+21:31 tight tvar B
209+21:32 tight glyph ]
210+22:3 INDENT
211+22:3 glyph ~&
212+22:6 lit %unknown
213+23:5 INDENT
214+23:5 glyph (
215+23:6 tight name pending
216+23:14 name first
217+23:20 name second
218+23:26 tight glyph )
219+24:1 DEDENT
220+24:1 DEDENT
221+24:1 NEWLINE
222+24:1 glyph ++
223+24:4 name pending-null
224+24:17 glyph |=
225+24:20 glyph [
226+24:21 tight name first
227+24:26 tight glyph =
228+24:27 tight tvar A
229+24:29 name second
230+24:35 tight glyph =
231+24:36 tight tvar B
232+24:37 tight glyph ]
233+25:3 INDENT
234+25:3 glyph ~&
235+25:6 lit ~
236+26:5 INDENT
237+26:5 glyph (
238+26:6 tight name pending-null
239+26:19 name first
240+26:25 name second
241+26:31 tight glyph )
242+27:1 DEDENT
243+27:1 DEDENT
244+27:1 NEWLINE
245+27:1 glyph ++
246+27:4 name early-base
247+27:15 glyph |=
248+27:18 glyph [
249+27:19 tight name first
250+27:24 tight glyph =
251+27:25 tight aura @t
252+27:28 name second
253+27:34 tight glyph =
254+27:35 tight aura @p
255+27:37 tight glyph ]
256+28:3 INDENT
257+28:3 glyph ?-
258+28:6 lit %.y
259+29:5 INDENT
260+29:5 lit %.y
261+29:9 str "ok"
262+30:5 NEWLINE
263+30:5 lit %.n
264+30:9 glyph (
265+30:10 tight name early-base
266+30:21 name first
267+30:27 name second
268+30:33 tight glyph )
269+31:1 DEDENT
270+31:1 DEDENT
271+31:1 NEWLINE
272+31:1 glyph ++
273+31:4 name late-base
274+31:14 glyph |=
275+31:17 glyph [
276+31:18 tight name first
277+31:23 tight glyph =
278+31:24 tight aura @t
279+31:27 name second
280+31:33 tight glyph =
281+31:34 tight aura @p
282+31:36 tight glyph ]
283+32:3 INDENT
284+32:3 glyph ?-
285+32:6 lit %.y
286+33:5 INDENT
287+33:5 lit %.n
288+33:9 glyph (
289+33:10 tight name late-base
290+33:20 name first
291+33:26 name second
292+33:32 tight glyph )
293+34:5 NEWLINE
294+34:5 lit %.y
295+34:9 str "ok"
296+35:1 DEDENT
297+35:1 DEDENT
298+35:1 NEWLINE
299+35:1 glyph ++
300+35:4 name generic
301+35:12 glyph |=
302+35:15 glyph [
303+35:16 tight name first
304+35:21 tight glyph =
305+35:22 tight tvar A
306+35:24 name second
307+35:30 tight glyph =
308+35:31 tight tvar B
309+35:32 tight glyph ]
310+36:3 INDENT
311+36:3 glyph ?-
312+36:6 lit %.y
313+37:5 INDENT
314+37:5 lit %.y
315+37:9 glyph [
316+37:10 tight name first
317+37:16 name second
318+37:22 tight glyph ]
319+38:5 NEWLINE
320+38:5 lit %.n
321+38:9 glyph (
322+38:10 tight name generic
323+38:18 name first
324+38:24 name second
325+38:30 tight glyph )
326+39:1 DEDENT
327+39:1 DEDENT
328+39:1 NEWLINE
329+39:1 glyph ++
330+39:4 name generic-one
331+39:16 glyph (
332+39:17 tight name generic
333+39:25 str "hi"
334+39:30 lit ~zod
335+39:34 tight glyph )
336+40:1 NEWLINE
337+40:1 glyph ++
338+40:4 name generic-two
339+40:16 glyph (
340+40:17 tight name generic
341+40:25 lit ~zod
342+40:30 str "hi"
343+40:34 tight glyph )
344+40:35 NEWLINE
tests/golden/types-recursive-sample/tree.txtnew file+161
@@ -0,0 +1,161 @@
1+(module
2+ (value 1:1 recurse
3+ (gate 1:12
4+ (cell 1:15
5+ (face 1:16 first (aura 1:22 @t))
6+ (face 1:25 second (aura 1:32 @p)))
7+ (body 2:3
8+ (branch 2:3
9+ (lit 2:6 %.y)
10+ (arm 3:5
11+ (lit 3:5 %.y)
12+ (tuple 3:9 (wing 3:10 first) (wing 3:16 second)))
13+ (arm 4:5
14+ (lit 4:5 %.n)
15+ (group 4:9
16+ (call 4:10 (wing 4:10 recurse) (wing 4:18 first) (wing 4:24 second))))))))
17+ (value 5:1 wrong-arg
18+ (gate 5:14
19+ (cell 5:17
20+ (face 5:18 first (aura 5:24 @t))
21+ (face 5:27 second (aura 5:34 @p)))
22+ (group 5:38
23+ (call 5:39 (wing 5:39 wrong-arg) (wing 5:49 first) (wing 5:55 first)))))
24+ (value 6:1 wrong-face
25+ (gate 6:15
26+ (cell 6:18
27+ (face 6:19 first (aura 6:25 @t))
28+ (face 6:28 second (aura 6:35 @p)))
29+ (group 6:39
30+ (call 6:40
31+ (wing 6:40 wrong-face)
32+ (tuple 6:51
33+ (face 6:52 other (wing 6:58 first))
34+ (face 6:64 second (wing 6:71 second)))))))
35+ (value 7:1 shadow
36+ (gate 7:11
37+ (cell 7:14
38+ (face 7:15 shadow (aura 7:22 @t))
39+ (face 7:25 second (aura 7:32 @p)))
40+ (group 7:36
41+ (call 7:37 (wing 7:37 shadow) (wing 7:44 shadow) (wing 7:51 second)))))
42+ (value 8:1 capture
43+ (gate 8:12
44+ (cell 8:15
45+ (face 8:16 first (tvar 8:22 A))
46+ (face 8:24 second (tvar 8:31 B)))
47+ (body 9:3
48+ (value 9:3 inner
49+ (gate 9:12
50+ (face 9:15 flag (flag 9:20))
51+ (wing 9:22 first)))
52+ (branch 10:3
53+ (lit 10:6 %.y)
54+ (arm 11:5
55+ (lit 11:5 %.y)
56+ (group 11:9
57+ (call 11:10 (wing 11:10 inner) (lit 11:16 %.y))))
58+ (arm 12:5
59+ (lit 12:5 %.n)
60+ (group 12:9
61+ (call 12:10 (wing 12:10 capture) (wing 12:18 first) (wing 12:24 second))))))))
62+ (value 13:1 alias-use
63+ (gate 13:14
64+ (cell 13:17
65+ (face 13:18 first (tvar 13:24 A))
66+ (face 13:26 second (tvar 13:33 A)))
67+ (body 14:3
68+ (value 14:3 alias (wing 14:12 alias-use))
69+ (trace 15:3
70+ (group 15:6
71+ (call 15:7 (wing 15:7 alias) (str 15:13 "hi") (str 15:18 "hi")))
72+ (body 16:5
73+ (group 16:5
74+ (call 16:6 (wing 16:6 alias) (lit 16:12 ~zod) (lit 16:17 ~zod))))))))
75+ (value 17:1 self-apply
76+ (gate 17:15
77+ (cell 17:18
78+ (face 17:19 first (tvar 17:25 A))
79+ (face 17:27 second (tvar 17:34 B)))
80+ (group 17:37
81+ (call 17:38 (wing 17:38 self-apply) (wing 17:49 self-apply) (wing 17:60 second)))))
82+ (value 18:1 forced
83+ (gate 18:11
84+ (cell 18:14
85+ (face 18:15 first (tvar 18:21 A))
86+ (face 18:23 second (tvar 18:30 B)))
87+ (body 19:3
88+ (trace 19:3
89+ (cast 19:6 (aura 19:9 @t) (wing 19:12 first))
90+ (body 20:5
91+ (group 20:5
92+ (call 20:6 (wing 20:6 forced) (wing 20:13 first) (wing 20:19 second))))))))
93+ (value 21:1 pending
94+ (gate 21:12
95+ (cell 21:15
96+ (face 21:16 first (tvar 21:22 A))
97+ (face 21:24 second (tvar 21:31 B)))
98+ (body 22:3
99+ (trace 22:3
100+ (lit 22:6 %unknown)
101+ (body 23:5
102+ (group 23:5
103+ (call 23:6 (wing 23:6 pending) (wing 23:14 first) (wing 23:20 second))))))))
104+ (value 24:1 pending-null
105+ (gate 24:17
106+ (cell 24:20
107+ (face 24:21 first (tvar 24:27 A))
108+ (face 24:29 second (tvar 24:36 B)))
109+ (body 25:3
110+ (trace 25:3
111+ (lit 25:6 ~)
112+ (body 26:5
113+ (group 26:5
114+ (call 26:6 (wing 26:6 pending-null) (wing 26:19 first) (wing 26:25 second))))))))
115+ (value 27:1 early-base
116+ (gate 27:15
117+ (cell 27:18
118+ (face 27:19 first (aura 27:25 @t))
119+ (face 27:28 second (aura 27:35 @p)))
120+ (body 28:3
121+ (branch 28:3
122+ (lit 28:6 %.y)
123+ (arm 29:5 (lit 29:5 %.y) (str 29:9 "ok"))
124+ (arm 30:5
125+ (lit 30:5 %.n)
126+ (group 30:9
127+ (call 30:10 (wing 30:10 early-base) (wing 30:21 first) (wing 30:27 second))))))))
128+ (value 31:1 late-base
129+ (gate 31:14
130+ (cell 31:17
131+ (face 31:18 first (aura 31:24 @t))
132+ (face 31:27 second (aura 31:34 @p)))
133+ (body 32:3
134+ (branch 32:3
135+ (lit 32:6 %.y)
136+ (arm 33:5
137+ (lit 33:5 %.n)
138+ (group 33:9
139+ (call 33:10 (wing 33:10 late-base) (wing 33:20 first) (wing 33:26 second))))
140+ (arm 34:5 (lit 34:5 %.y) (str 34:9 "ok"))))))
141+ (value 35:1 generic
142+ (gate 35:12
143+ (cell 35:15
144+ (face 35:16 first (tvar 35:22 A))
145+ (face 35:24 second (tvar 35:31 B)))
146+ (body 36:3
147+ (branch 36:3
148+ (lit 36:6 %.y)
149+ (arm 37:5
150+ (lit 37:5 %.y)
151+ (tuple 37:9 (wing 37:10 first) (wing 37:16 second)))
152+ (arm 38:5
153+ (lit 38:5 %.n)
154+ (group 38:9
155+ (call 38:10 (wing 38:10 generic) (wing 38:18 first) (wing 38:24 second))))))))
156+ (value 39:1 generic-one
157+ (group 39:16
158+ (call 39:17 (wing 39:17 generic) (str 39:25 "hi") (lit 39:30 ~zod))))
159+ (value 40:1 generic-two
160+ (group 40:16
161+ (call 40:17 (wing 40:17 generic) (lit 40:25 ~zod) (str 40:30 "hi")))))
tests/golden/types-recursive-sample/types.txtnew file+40
@@ -0,0 +1,40 @@
1+partial inference; module not checked
2+++ recurse: $-([first=@t second=@p] [@t @p])
3+++ wrong-arg: call's sample and argument types do not unify
4+/tests/golden/types-recursive-sample/source.jibb:5:39: called gate has type $-([first=@t second=@p] A)
5+++ wrong-arg |= [first=@t second=@p] (wrong-arg first first)
6+ ^
7+/tests/golden/types-recursive-sample/source.jibb:5:55: argument has type @t
8+++ wrong-arg |= [first=@t second=@p] (wrong-arg first first)
9+ ^
10+++ wrong-face: call's sample and argument types do not unify
11+/tests/golden/types-recursive-sample/source.jibb:6:40: called gate has type $-([first=@t second=@p] A)
12+++ wrong-face |= [first=@t second=@p] (wrong-face [other=first second=second])
13+ ^
14+/tests/golden/types-recursive-sample/source.jibb:6:51: argument has type [other=@t second=@p]
15+++ wrong-face |= [first=@t second=@p] (wrong-face [other=first second=second])
16+ ^
17+++ shadow: sample shadows a name
18+++ capture: $-([first=A second=B] A)
19+++ alias-use: call's sample and argument types do not unify
20+/tests/golden/types-recursive-sample/source.jibb:16:6: called gate has type $-([first=@t second=@t] A)
21+ (alias ~zod ~zod)
22+ ^
23+/tests/golden/types-recursive-sample/source.jibb:16:12: argument has type @p
24+ (alias ~zod ~zod)
25+ ^
26+++ self-apply: call's sample and argument types do not unify
27+/tests/golden/types-recursive-sample/source.jibb:17:38: called gate has type $-([first=A second=B] C)
28+++ self-apply |= [first=A second=B] (self-apply self-apply second)
29+ ^
30+/tests/golden/types-recursive-sample/source.jibb:17:49: argument has type $-([first=A second=B] C)
31+++ self-apply |= [first=A second=B] (self-apply self-apply second)
32+ ^
33+++ forced: call constraint is not supported by partial inference
34+++ pending: tag needs context in partial inference
35+++ pending-null: `~` needs context in partial inference
36+++ early-base: $-([first=@t second=@p] @t)
37+++ late-base: $-([first=@t second=@p] @t)
38+++ generic: $-([first=A second=B] [A B])
39+++ generic-one: [@t @p]
40+++ generic-two: [@p @t]
tests/lib/jibb.hoon+139−133
@@ -1694,115 +1694,119 @@
16941694/* tok-486 %txt /tests/golden/types-recursive-gate/tokens/txt
16951695/* tre-486 %txt /tests/golden/types-recursive-gate/tree/txt
16961696/* typ-486 %txt /tests/golden/types-recursive-gate/types/txt
1697−/* src-487 %jibb /tests/golden/types-union-alias/source/jibb
1698−/* tok-487 %txt /tests/golden/types-union-alias/tokens/txt
1699−/* tre-487 %txt /tests/golden/types-union-alias/tree/txt
1700−/* typ-487 %txt /tests/golden/types-union-alias/types/txt
1701−/* src-488 %jibb /tests/golden/types-union-branch-context/source/jibb
1702−/* tok-488 %txt /tests/golden/types-union-branch-context/tokens/txt
1703−/* tre-488 %txt /tests/golden/types-union-branch-context/tree/txt
1704−/* typ-488 %txt /tests/golden/types-union-branch-context/types/txt
1705−/* src-489 %jibb /tests/golden/types-union-branch-pending/source/jibb
1706−/* tok-489 %txt /tests/golden/types-union-branch-pending/tokens/txt
1707−/* tre-489 %txt /tests/golden/types-union-branch-pending/tree/txt
1708−/* typ-489 %txt /tests/golden/types-union-branch-pending/types/txt
1709−/* src-490 %jibb /tests/golden/types-union-constructor-shape/source/jibb
1710−/* tok-490 %txt /tests/golden/types-union-constructor-shape/tokens/txt
1711−/* tre-490 %txt /tests/golden/types-union-constructor-shape/tree/txt
1712−/* typ-490 %txt /tests/golden/types-union-constructor-shape/types/txt
1713−/* src-491 %jibb /tests/golden/types-union-context-flow/source/jibb
1714−/* tok-491 %txt /tests/golden/types-union-context-flow/tokens/txt
1715−/* tre-491 %txt /tests/golden/types-union-context-flow/tree/txt
1716−/* typ-491 %txt /tests/golden/types-union-context-flow/types/txt
1717−/* src-492 %jibb /tests/golden/types-union-import/source/jibb
1718−/* tok-492 %txt /tests/golden/types-union-import/tokens/txt
1719−/* tre-492 %txt /tests/golden/types-union-import/tree/txt
1720−/* mod-492-1 %jibb /tests/golden/types-union-import/modules/ui/lib/jibb
1721−/* typ-492 %txt /tests/golden/types-union-import/types/txt
1722−/* mtre-492 %txt /tests/golden/types-union-import/module-trees/txt
1723−/* src-493 %jibb /tests/golden/types-union-local-pending/source/jibb
1724−/* tok-493 %txt /tests/golden/types-union-local-pending/tokens/txt
1725−/* tre-493 %txt /tests/golden/types-union-local-pending/tree/txt
1726−/* typ-493 %txt /tests/golden/types-union-local-pending/types/txt
1727−/* src-494 %jibb /tests/golden/types-union-overlap/source/jibb
1728−/* tok-494 %txt /tests/golden/types-union-overlap/tokens/txt
1729−/* tre-494 %txt /tests/golden/types-union-overlap/tree/txt
1730−/* typ-494 %txt /tests/golden/types-union-overlap/types/txt
1731−/* src-495 %jibb /tests/golden/types-union-overlap-nested/source/jibb
1732−/* tok-495 %txt /tests/golden/types-union-overlap-nested/tokens/txt
1733−/* tre-495 %txt /tests/golden/types-union-overlap-nested/tree/txt
1734−/* typ-495 %txt /tests/golden/types-union-overlap-nested/types/txt
1735−/* src-496 %jibb /tests/golden/types-union-phantom-generic/source/jibb
1736−/* tok-496 %txt /tests/golden/types-union-phantom-generic/tokens/txt
1737−/* tre-496 %txt /tests/golden/types-union-phantom-generic/tree/txt
1738−/* typ-496 %txt /tests/golden/types-union-phantom-generic/types/txt
1739−/* src-497 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
1740−/* tok-497 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
1741−/* tre-497 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
1742−/* mod-497-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
1743−/* typ-497 %txt /tests/golden/types-union-print-cross-namespace/types/txt
1744−/* mtre-497 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
1745−/* src-498 %jibb /tests/golden/types-union-print-distinct/source/jibb
1746−/* tok-498 %txt /tests/golden/types-union-print-distinct/tokens/txt
1747−/* tre-498 %txt /tests/golden/types-union-print-distinct/tree/txt
1748−/* mod-498-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
1749−/* mod-498-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
1750−/* mod-498-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
1751−/* typ-498 %txt /tests/golden/types-union-print-distinct/types/txt
1752−/* mtre-498 %txt /tests/golden/types-union-print-distinct/module-trees/txt
1753−/* src-499 %jibb /tests/golden/types-union-print-escape/source/jibb
1754−/* tok-499 %txt /tests/golden/types-union-print-escape/tokens/txt
1755−/* tre-499 %txt /tests/golden/types-union-print-escape/tree/txt
1756−/* typ-499 %txt /tests/golden/types-union-print-escape/types/txt
1757−/* src-500 %jibb /tests/golden/types-union-print-local/source/jibb
1758−/* tok-500 %txt /tests/golden/types-union-print-local/tokens/txt
1759−/* tre-500 %txt /tests/golden/types-union-print-local/tree/txt
1760−/* typ-500 %txt /tests/golden/types-union-print-local/types/txt
1761−/* src-501 %jibb /tests/golden/types-union-print-nested/source/jibb
1762−/* tok-501 %txt /tests/golden/types-union-print-nested/tokens/txt
1763−/* tre-501 %txt /tests/golden/types-union-print-nested/tree/txt
1764−/* typ-501 %txt /tests/golden/types-union-print-nested/types/txt
1765−/* src-502 %jibb /tests/golden/types-union-print-same-origin/source/jibb
1766−/* tok-502 %txt /tests/golden/types-union-print-same-origin/tokens/txt
1767−/* tre-502 %txt /tests/golden/types-union-print-same-origin/tree/txt
1768−/* mod-502-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
1769−/* typ-502 %txt /tests/golden/types-union-print-same-origin/types/txt
1770−/* mtre-502 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
1771−/* src-503 %jibb /tests/golden/types-union-print-transitive/source/jibb
1772−/* tok-503 %txt /tests/golden/types-union-print-transitive/tokens/txt
1773−/* tre-503 %txt /tests/golden/types-union-print-transitive/tree/txt
1774−/* mod-503-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
1775−/* mod-503-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
1776−/* typ-503 %txt /tests/golden/types-union-print-transitive/types/txt
1777−/* mtre-503 %txt /tests/golden/types-union-print-transitive/module-trees/txt
1778−/* src-504 %jibb /tests/golden/types-union-singleton/source/jibb
1779−/* tok-504 %txt /tests/golden/types-union-singleton/tokens/txt
1780−/* tre-504 %txt /tests/golden/types-union-singleton/tree/txt
1781−/* typ-504 %txt /tests/golden/types-union-singleton/types/txt
1782−/* src-505 %jibb /tests/golden/types-union-tag-atoms/source/jibb
1783−/* tok-505 %txt /tests/golden/types-union-tag-atoms/tokens/txt
1784−/* tre-505 %txt /tests/golden/types-union-tag-atoms/tree/txt
1785−/* typ-505 %txt /tests/golden/types-union-tag-atoms/types/txt
1786−/* src-506 %jibb /tests/golden/types-union-tags/source/jibb
1787−/* tok-506 %txt /tests/golden/types-union-tags/tokens/txt
1788−/* tre-506 %txt /tests/golden/types-union-tags/tree/txt
1789−/* typ-506 %txt /tests/golden/types-union-tags/types/txt
1790−/* src-507 %jibb /tests/golden/types-union-unresolved/source/jibb
1791−/* tok-507 %txt /tests/golden/types-union-unresolved/tokens/txt
1792−/* tre-507 %txt /tests/golden/types-union-unresolved/tree/txt
1793−/* typ-507 %txt /tests/golden/types-union-unresolved/types/txt
1794−/* src-508 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
1795−/* tok-508 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
1796−/* tre-508 %txt /tests/golden/types-union-unresolved-flow/tree/txt
1797−/* typ-508 %txt /tests/golden/types-union-unresolved-flow/types/txt
1798−/* src-509 %jibb /tests/golden/types-unit-context/source/jibb
1799−/* tok-509 %txt /tests/golden/types-unit-context/tokens/txt
1800−/* tre-509 %txt /tests/golden/types-unit-context/tree/txt
1801−/* typ-509 %txt /tests/golden/types-unit-context/types/txt
1802−/* src-510 %jibb /tests/golden/types-unit-patterns/source/jibb
1803−/* tok-510 %txt /tests/golden/types-unit-patterns/tokens/txt
1804−/* tre-510 %txt /tests/golden/types-unit-patterns/tree/txt
1805−/* typ-510 %txt /tests/golden/types-unit-patterns/types/txt
1697+/* src-487 %jibb /tests/golden/types-recursive-sample/source/jibb
1698+/* tok-487 %txt /tests/golden/types-recursive-sample/tokens/txt
1699+/* tre-487 %txt /tests/golden/types-recursive-sample/tree/txt
1700+/* typ-487 %txt /tests/golden/types-recursive-sample/types/txt
1701+/* src-488 %jibb /tests/golden/types-union-alias/source/jibb
1702+/* tok-488 %txt /tests/golden/types-union-alias/tokens/txt
1703+/* tre-488 %txt /tests/golden/types-union-alias/tree/txt
1704+/* typ-488 %txt /tests/golden/types-union-alias/types/txt
1705+/* src-489 %jibb /tests/golden/types-union-branch-context/source/jibb
1706+/* tok-489 %txt /tests/golden/types-union-branch-context/tokens/txt
1707+/* tre-489 %txt /tests/golden/types-union-branch-context/tree/txt
1708+/* typ-489 %txt /tests/golden/types-union-branch-context/types/txt
1709+/* src-490 %jibb /tests/golden/types-union-branch-pending/source/jibb
1710+/* tok-490 %txt /tests/golden/types-union-branch-pending/tokens/txt
1711+/* tre-490 %txt /tests/golden/types-union-branch-pending/tree/txt
1712+/* typ-490 %txt /tests/golden/types-union-branch-pending/types/txt
1713+/* src-491 %jibb /tests/golden/types-union-constructor-shape/source/jibb
1714+/* tok-491 %txt /tests/golden/types-union-constructor-shape/tokens/txt
1715+/* tre-491 %txt /tests/golden/types-union-constructor-shape/tree/txt
1716+/* typ-491 %txt /tests/golden/types-union-constructor-shape/types/txt
1717+/* src-492 %jibb /tests/golden/types-union-context-flow/source/jibb
1718+/* tok-492 %txt /tests/golden/types-union-context-flow/tokens/txt
1719+/* tre-492 %txt /tests/golden/types-union-context-flow/tree/txt
1720+/* typ-492 %txt /tests/golden/types-union-context-flow/types/txt
1721+/* src-493 %jibb /tests/golden/types-union-import/source/jibb
1722+/* tok-493 %txt /tests/golden/types-union-import/tokens/txt
1723+/* tre-493 %txt /tests/golden/types-union-import/tree/txt
1724+/* mod-493-1 %jibb /tests/golden/types-union-import/modules/ui/lib/jibb
1725+/* typ-493 %txt /tests/golden/types-union-import/types/txt
1726+/* mtre-493 %txt /tests/golden/types-union-import/module-trees/txt
1727+/* src-494 %jibb /tests/golden/types-union-local-pending/source/jibb
1728+/* tok-494 %txt /tests/golden/types-union-local-pending/tokens/txt
1729+/* tre-494 %txt /tests/golden/types-union-local-pending/tree/txt
1730+/* typ-494 %txt /tests/golden/types-union-local-pending/types/txt
1731+/* src-495 %jibb /tests/golden/types-union-overlap/source/jibb
1732+/* tok-495 %txt /tests/golden/types-union-overlap/tokens/txt
1733+/* tre-495 %txt /tests/golden/types-union-overlap/tree/txt
1734+/* typ-495 %txt /tests/golden/types-union-overlap/types/txt
1735+/* src-496 %jibb /tests/golden/types-union-overlap-nested/source/jibb
1736+/* tok-496 %txt /tests/golden/types-union-overlap-nested/tokens/txt
1737+/* tre-496 %txt /tests/golden/types-union-overlap-nested/tree/txt
1738+/* typ-496 %txt /tests/golden/types-union-overlap-nested/types/txt
1739+/* src-497 %jibb /tests/golden/types-union-phantom-generic/source/jibb
1740+/* tok-497 %txt /tests/golden/types-union-phantom-generic/tokens/txt
1741+/* tre-497 %txt /tests/golden/types-union-phantom-generic/tree/txt
1742+/* typ-497 %txt /tests/golden/types-union-phantom-generic/types/txt
1743+/* src-498 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
1744+/* tok-498 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
1745+/* tre-498 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
1746+/* mod-498-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
1747+/* typ-498 %txt /tests/golden/types-union-print-cross-namespace/types/txt
1748+/* mtre-498 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
1749+/* src-499 %jibb /tests/golden/types-union-print-distinct/source/jibb
1750+/* tok-499 %txt /tests/golden/types-union-print-distinct/tokens/txt
1751+/* tre-499 %txt /tests/golden/types-union-print-distinct/tree/txt
1752+/* mod-499-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
1753+/* mod-499-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
1754+/* mod-499-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
1755+/* typ-499 %txt /tests/golden/types-union-print-distinct/types/txt
1756+/* mtre-499 %txt /tests/golden/types-union-print-distinct/module-trees/txt
1757+/* src-500 %jibb /tests/golden/types-union-print-escape/source/jibb
1758+/* tok-500 %txt /tests/golden/types-union-print-escape/tokens/txt
1759+/* tre-500 %txt /tests/golden/types-union-print-escape/tree/txt
1760+/* typ-500 %txt /tests/golden/types-union-print-escape/types/txt
1761+/* src-501 %jibb /tests/golden/types-union-print-local/source/jibb
1762+/* tok-501 %txt /tests/golden/types-union-print-local/tokens/txt
1763+/* tre-501 %txt /tests/golden/types-union-print-local/tree/txt
1764+/* typ-501 %txt /tests/golden/types-union-print-local/types/txt
1765+/* src-502 %jibb /tests/golden/types-union-print-nested/source/jibb
1766+/* tok-502 %txt /tests/golden/types-union-print-nested/tokens/txt
1767+/* tre-502 %txt /tests/golden/types-union-print-nested/tree/txt
1768+/* typ-502 %txt /tests/golden/types-union-print-nested/types/txt
1769+/* src-503 %jibb /tests/golden/types-union-print-same-origin/source/jibb
1770+/* tok-503 %txt /tests/golden/types-union-print-same-origin/tokens/txt
1771+/* tre-503 %txt /tests/golden/types-union-print-same-origin/tree/txt
1772+/* mod-503-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
1773+/* typ-503 %txt /tests/golden/types-union-print-same-origin/types/txt
1774+/* mtre-503 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
1775+/* src-504 %jibb /tests/golden/types-union-print-transitive/source/jibb
1776+/* tok-504 %txt /tests/golden/types-union-print-transitive/tokens/txt
1777+/* tre-504 %txt /tests/golden/types-union-print-transitive/tree/txt
1778+/* mod-504-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
1779+/* mod-504-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
1780+/* typ-504 %txt /tests/golden/types-union-print-transitive/types/txt
1781+/* mtre-504 %txt /tests/golden/types-union-print-transitive/module-trees/txt
1782+/* src-505 %jibb /tests/golden/types-union-singleton/source/jibb
1783+/* tok-505 %txt /tests/golden/types-union-singleton/tokens/txt
1784+/* tre-505 %txt /tests/golden/types-union-singleton/tree/txt
1785+/* typ-505 %txt /tests/golden/types-union-singleton/types/txt
1786+/* src-506 %jibb /tests/golden/types-union-tag-atoms/source/jibb
1787+/* tok-506 %txt /tests/golden/types-union-tag-atoms/tokens/txt
1788+/* tre-506 %txt /tests/golden/types-union-tag-atoms/tree/txt
1789+/* typ-506 %txt /tests/golden/types-union-tag-atoms/types/txt
1790+/* src-507 %jibb /tests/golden/types-union-tags/source/jibb
1791+/* tok-507 %txt /tests/golden/types-union-tags/tokens/txt
1792+/* tre-507 %txt /tests/golden/types-union-tags/tree/txt
1793+/* typ-507 %txt /tests/golden/types-union-tags/types/txt
1794+/* src-508 %jibb /tests/golden/types-union-unresolved/source/jibb
1795+/* tok-508 %txt /tests/golden/types-union-unresolved/tokens/txt
1796+/* tre-508 %txt /tests/golden/types-union-unresolved/tree/txt
1797+/* typ-508 %txt /tests/golden/types-union-unresolved/types/txt
1798+/* src-509 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
1799+/* tok-509 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
1800+/* tre-509 %txt /tests/golden/types-union-unresolved-flow/tree/txt
1801+/* typ-509 %txt /tests/golden/types-union-unresolved-flow/types/txt
1802+/* src-510 %jibb /tests/golden/types-unit-context/source/jibb
1803+/* tok-510 %txt /tests/golden/types-unit-context/tokens/txt
1804+/* tre-510 %txt /tests/golden/types-unit-context/tree/txt
1805+/* typ-510 %txt /tests/golden/types-unit-context/types/txt
1806+/* src-511 %jibb /tests/golden/types-unit-patterns/source/jibb
1807+/* tok-511 %txt /tests/golden/types-unit-patterns/tokens/txt
1808+/* tre-511 %txt /tests/golden/types-unit-patterns/tree/txt
1809+/* typ-511 %txt /tests/golden/types-unit-patterns/types/txt
18061810=/ prepared-prelude (prepare-prelude:jibb prelude-source)
18071811|%
18081812:: one arm per case
@@ -2779,54 +2783,56 @@
27792783 (weld (check ~.types-recursive-branch src-485 `tok-485 `tre-485) (check-module-types ~.types-recursive-branch ~[%tests %golden ~.types-recursive-branch %source %jibb] src-485 `typ-485 ~ ~ ~))
27802784++ test-types-recursive-gate
27812785 (weld (check ~.types-recursive-gate src-486 `tok-486 `tre-486) (check-types ~.types-recursive-gate ~[%tests %golden ~.types-recursive-gate %source %jibb] src-486 `typ-486))
2786+++ test-types-recursive-sample
2787+ (weld (check ~.types-recursive-sample src-487 `tok-487 `tre-487) (check-types ~.types-recursive-sample ~[%tests %golden ~.types-recursive-sample %source %jibb] src-487 `typ-487))
27822788++ test-types-union-alias
2783− (weld (check ~.types-union-alias src-487 `tok-487 `tre-487) (check-types ~.types-union-alias ~[%tests %golden ~.types-union-alias %source %jibb] src-487 `typ-487))
2789+ (weld (check ~.types-union-alias src-488 `tok-488 `tre-488) (check-types ~.types-union-alias ~[%tests %golden ~.types-union-alias %source %jibb] src-488 `typ-488))
27842790++ test-types-union-branch-context
2785− (weld (check ~.types-union-branch-context src-488 `tok-488 `tre-488) (check-types ~.types-union-branch-context ~[%tests %golden ~.types-union-branch-context %source %jibb] src-488 `typ-488))
2791+ (weld (check ~.types-union-branch-context src-489 `tok-489 `tre-489) (check-types ~.types-union-branch-context ~[%tests %golden ~.types-union-branch-context %source %jibb] src-489 `typ-489))
27862792++ test-types-union-branch-pending
2787− (weld (check ~.types-union-branch-pending src-489 `tok-489 `tre-489) (check-types ~.types-union-branch-pending ~[%tests %golden ~.types-union-branch-pending %source %jibb] src-489 `typ-489))
2793+ (weld (check ~.types-union-branch-pending src-490 `tok-490 `tre-490) (check-types ~.types-union-branch-pending ~[%tests %golden ~.types-union-branch-pending %source %jibb] src-490 `typ-490))
27882794++ test-types-union-constructor-shape
2789− (weld (check ~.types-union-constructor-shape src-490 `tok-490 `tre-490) (check-types ~.types-union-constructor-shape ~[%tests %golden ~.types-union-constructor-shape %source %jibb] src-490 `typ-490))
2795+ (weld (check ~.types-union-constructor-shape src-491 `tok-491 `tre-491) (check-types ~.types-union-constructor-shape ~[%tests %golden ~.types-union-constructor-shape %source %jibb] src-491 `typ-491))
27902796++ test-types-union-context-flow
2791− (weld (check ~.types-union-context-flow src-491 `tok-491 `tre-491) (check-types ~.types-union-context-flow ~[%tests %golden ~.types-union-context-flow %source %jibb] src-491 `typ-491))
2797+ (weld (check ~.types-union-context-flow src-492 `tok-492 `tre-492) (check-types ~.types-union-context-flow ~[%tests %golden ~.types-union-context-flow %source %jibb] src-492 `typ-492))
27922798++ test-types-union-import
2793− (weld (weld (check ~.types-union-import src-492 `tok-492 `tre-492) (check-module-types ~.types-union-import ~[%tests %golden ~.types-union-import %source %jibb] src-492 `typ-492 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-492-1]])) (check-module-trees ~.types-union-import `mtre-492 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-492-1]]))
2799+ (weld (weld (check ~.types-union-import src-493 `tok-493 `tre-493) (check-module-types ~.types-union-import ~[%tests %golden ~.types-union-import %source %jibb] src-493 `typ-493 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-493-1]])) (check-module-trees ~.types-union-import `mtre-493 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-493-1]]))
27942800++ test-types-union-local-pending
2795− (weld (check ~.types-union-local-pending src-493 `tok-493 `tre-493) (check-types ~.types-union-local-pending ~[%tests %golden ~.types-union-local-pending %source %jibb] src-493 `typ-493))
2801+ (weld (check ~.types-union-local-pending src-494 `tok-494 `tre-494) (check-types ~.types-union-local-pending ~[%tests %golden ~.types-union-local-pending %source %jibb] src-494 `typ-494))
27962802++ test-types-union-overlap
2797− (weld (check ~.types-union-overlap src-494 `tok-494 `tre-494) (check-types ~.types-union-overlap ~[%tests %golden ~.types-union-overlap %source %jibb] src-494 `typ-494))
2803+ (weld (check ~.types-union-overlap src-495 `tok-495 `tre-495) (check-types ~.types-union-overlap ~[%tests %golden ~.types-union-overlap %source %jibb] src-495 `typ-495))
27982804++ test-types-union-overlap-nested
2799− (weld (check ~.types-union-overlap-nested src-495 `tok-495 `tre-495) (check-types ~.types-union-overlap-nested ~[%tests %golden ~.types-union-overlap-nested %source %jibb] src-495 `typ-495))
2805+ (weld (check ~.types-union-overlap-nested src-496 `tok-496 `tre-496) (check-types ~.types-union-overlap-nested ~[%tests %golden ~.types-union-overlap-nested %source %jibb] src-496 `typ-496))
28002806++ test-types-union-phantom-generic
2801− (weld (check ~.types-union-phantom-generic src-496 `tok-496 `tre-496) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-496 `typ-496))
2807+ (weld (check ~.types-union-phantom-generic src-497 `tok-497 `tre-497) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-497 `typ-497))
28022808++ test-types-union-print-cross-namespace
2803− (weld (weld (check ~.types-union-print-cross-namespace src-497 `tok-497 `tre-497) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-497 `typ-497 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-497-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-497 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-497-1]]))
2809+ (weld (weld (check ~.types-union-print-cross-namespace src-498 `tok-498 `tre-498) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-498 `typ-498 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-498-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-498 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-498-1]]))
28042810++ test-types-union-print-distinct
2805− (weld (weld (check ~.types-union-print-distinct src-498 `tok-498 `tre-498) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-498 `typ-498 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-498-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-498-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-498-3]])) (check-module-trees ~.types-union-print-distinct `mtre-498 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-498-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-498-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-498-3]]))
2811+ (weld (weld (check ~.types-union-print-distinct src-499 `tok-499 `tre-499) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-499 `typ-499 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-499-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-499-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-499-3]])) (check-module-trees ~.types-union-print-distinct `mtre-499 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-499-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-499-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-499-3]]))
28062812++ test-types-union-print-escape
2807− (weld (check ~.types-union-print-escape src-499 `tok-499 `tre-499) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-499 `typ-499))
2813+ (weld (check ~.types-union-print-escape src-500 `tok-500 `tre-500) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-500 `typ-500))
28082814++ test-types-union-print-local
2809− (weld (check ~.types-union-print-local src-500 `tok-500 `tre-500) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-500 `typ-500))
2815+ (weld (check ~.types-union-print-local src-501 `tok-501 `tre-501) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-501 `typ-501))
28102816++ test-types-union-print-nested
2811− (weld (check ~.types-union-print-nested src-501 `tok-501 `tre-501) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-501 `typ-501))
2817+ (weld (check ~.types-union-print-nested src-502 `tok-502 `tre-502) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-502 `typ-502))
28122818++ test-types-union-print-same-origin
2813− (weld (weld (check ~.types-union-print-same-origin src-502 `tok-502 `tre-502) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-502 `typ-502 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-502-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-502 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-502-1]]))
2819+ (weld (weld (check ~.types-union-print-same-origin src-503 `tok-503 `tre-503) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-503 `typ-503 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-503-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-503 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-503-1]]))
28142820++ test-types-union-print-transitive
2815− (weld (weld (check ~.types-union-print-transitive src-503 `tok-503 `tre-503) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-503 `typ-503 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-503-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-503-2]])) (check-module-trees ~.types-union-print-transitive `mtre-503 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-503-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-503-2]]))
2821+ (weld (weld (check ~.types-union-print-transitive src-504 `tok-504 `tre-504) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-504 `typ-504 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-504-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-504-2]])) (check-module-trees ~.types-union-print-transitive `mtre-504 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-504-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-504-2]]))
28162822++ test-types-union-singleton
2817− (weld (check ~.types-union-singleton src-504 `tok-504 `tre-504) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-504 `typ-504))
2823+ (weld (check ~.types-union-singleton src-505 `tok-505 `tre-505) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-505 `typ-505))
28182824++ test-types-union-tag-atoms
2819− (weld (check ~.types-union-tag-atoms src-505 `tok-505 `tre-505) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-505 `typ-505))
2825+ (weld (check ~.types-union-tag-atoms src-506 `tok-506 `tre-506) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-506 `typ-506))
28202826++ test-types-union-tags
2821− (weld (check ~.types-union-tags src-506 `tok-506 `tre-506) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-506 `typ-506))
2827+ (weld (check ~.types-union-tags src-507 `tok-507 `tre-507) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-507 `typ-507))
28222828++ test-types-union-unresolved
2823− (weld (check ~.types-union-unresolved src-507 `tok-507 `tre-507) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-507 `typ-507))
2829+ (weld (check ~.types-union-unresolved src-508 `tok-508 `tre-508) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-508 `typ-508))
28242830++ test-types-union-unresolved-flow
2825− (weld (check ~.types-union-unresolved-flow src-508 `tok-508 `tre-508) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-508 `typ-508))
2831+ (weld (check ~.types-union-unresolved-flow src-509 `tok-509 `tre-509) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-509 `typ-509))
28262832++ test-types-unit-context
2827− (weld (check ~.types-unit-context src-509 `tok-509 `tre-509) (check-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-509 `typ-509))
2833+ (weld (check ~.types-unit-context src-510 `tok-510 `tre-510) (check-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-510 `typ-510))
28282834++ test-types-unit-patterns
2829− (weld (check ~.types-unit-patterns src-510 `tok-510 `tre-510) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-510 `typ-510))
2835+ (weld (check ~.types-unit-patterns src-511 `tok-511 `tre-511) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-511 `typ-511))
28302836::
28312837:: +check: run golden:jibb on a case and compare both outputs
28322838::