on master help sign in
Contextualize finite patterns and record poke decision
commit7ff15f1f139f17420aecc88d37da42347669e2fc authoriko <mail@iko.soy> dateSat 31 Oct 2026, 01:54 (10 hours ago) parent67f900e
15 files changed+1085−184
docs/compiler.md+1−1 docs/open-questions.md+2−2 docs/prompts/milestone-2.md+1−1 docs/spec/decisions.md+1 docs/spec/grammar.md+1−1 docs/spec/overview.md+1−1 docs/status.md+7−6 jibb-dev/lib/jibb.hoon+44−22 tests/golden/types-union-finite-context/about.txt+4 tests/golden/types-union-finite-context/modules.txt+1 tests/golden/types-union-finite-context/source.jibb+76 tests/golden/types-union-finite-context/tokens.txt+529 tests/golden/types-union-finite-context/tree.txt+234 tests/golden/types-union-finite-context/types.txt+27 tests/lib/jibb.hoon+156−150
docs/compiler.md+1−1
@@ -76,7 +76,7 @@ A backtick constructs a unit when the supplied prelude has the validated standar
7676
7777A known union of `~` and a null-headed cell can be matched by `~` and `[~ value]` arms in either order. The payload binder is checked for shadowing. Unknown subjects, missing or duplicate arms, and unresolved branch results remain unsupported; this fragment infers the prelude’s `fall` and `need` signatures.
7878
79−A known closed union with two or more arms can be matched when each arm provably covers or excludes each remaining case. The checker first tries whole cases; when a pattern splits a case, it can expand known `?` positions into their two noun values, up to 64 alternatives across the union. Binders retain the original case type, and one arm may bind several refinements of that case. It reports missing alternatives and arms already covered, checks tags by noun value, and supports imported and generic union cases. Other partial patterns, expansions above the limit, binders spanning distinct cases, differing arm result types and some complex two-arm subjects remain unsupported. When a cast or known call sample supplies a result type, a known union subject accessed by a wing can propagate that context through whole-case arms, including nested cell and list positions. 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.
79+A known closed union with two or more arms can be matched when each arm provably covers or excludes each remaining case. The checker first tries whole cases; when a pattern splits a case, it can expand known `?` positions into their two noun values, up to 64 alternatives across the union. Binders retain the original case type, and one arm may bind several refinements of that case. It reports missing alternatives and arms already covered, checks tags by noun value, and supports imported and generic union cases. Other partial patterns, expansions above the limit, binders spanning distinct cases, differing arm result types and some complex two-arm subjects remain unsupported. When a cast or known call sample supplies a result type, a known union subject accessed by a wing can propagate that context through whole-case arms and supported finite loobean refinements, 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.
8080
8181A known closed union can also provide context to each arm of a complete loobean or unit-shaped branch in a cast or a call with a known union sample. Nested branches and transparent groups work; a mismatch reports the expected union and the offending arm. General patterns and context through bodies with local definitions remain unsupported, and unrelated unresolved tags stay pending.
8282
docs/open-questions.md+2−2
@@ -18,7 +18,7 @@ On 2026-10-30, @iko adopted gate-free `eq` arguments and map and set keys, treat
1818
1919## Questions milestone 2 raises
2020
21−Found while writing [prompts/milestone-2.md](prompts/milestone-2.md), checking it against the doc's examples, and building the checker. The numbering is retained so existing references stay valid. Questions 3, 18 and 24 remain open; the other questions are settled.
21+Found while writing [prompts/milestone-2.md](prompts/milestone-2.md), checking it against the doc's examples, and building the checker. The numbering is retained so existing references stay valid. Questions 3 and 18 remain open; the other questions are settled.
2222
23231. **Settled: how the prelude identifies jetted functions.** On 2026-10-30, @iko said the prelude functions have working Jibb implementations, and the compiler recognizes their shapes and uses the Hoon versions so jets can fire.
24242. **Settled: how the prelude keeps helpers private.** On 2026-10-30, @iko chose a separate internal prelude module imported by the prelude, without exposing the imported helpers.
@@ -44,7 +44,7 @@ Found while writing [prompts/milestone-2.md](prompts/milestone-2.md), checking i
444422. **Settled: overlapping imported `$%` and `$?` cases.** On 2026-10-30, @iko confirmed that the general union disjointness rule rejects imported `$%` and `$?` cases that overlap as nouns where the type is used, as it does for `$^`. The importer rejects recognizable overlaps and fails closed when it cannot verify them.
454523. **Settled: converging explicit capitals.** On 2026-10-30, @iko chose that a body cannot force two separately written capitals to be equal. For `++ repeated |= x=(choice A A) x`, `++ f |= x=(choice A B) (repeated x)` is an error; use `A` in both positions when the type must be shared. This also applies across local captures and within generic mold applications.
4646
47−24. **How the internal prelude provides opaque types.** The public prelude needs an opaque `poke` type, but Jibb has no syntax to declare an opaque type in its private internal module. Should the internal module instead be a compiler-provided private interface that the prelude imports and re-exports, or should Jibb gain syntax for private opaque declarations? @iko has been asked; the answer is pending. The separate internal module and private primitives were already agreed in questions 2 and 14.
47+24. **Settled: how the internal prelude provides `poke`.** On 2026-10-31, @iko chose to define `poke` in the source-backed private internal prelude module and expose only its opaque type through the public prelude. The checker hides its representation from ordinary modules; derived gates and `pure` remain its builders. This settles `poke`; it does not decide the representation of `ask` or `qath`.
4848
4949## Grammar questions never put to the doc's author
5050
docs/prompts/milestone-2.md+1−1
@@ -49,7 +49,7 @@ And from the plan's Risks:
4949
5050## First steps
5151
52−1. **Specify the prelude inventory.** The checker needs the prelude's complete exported inventory and signatures; include all names from the listed Hoon library sections except explicitly excluded groups, as `docs/open-questions.md` question 3 records. The prelude imports private helpers and low-level primitives from a separate internal module without exposing them; its public foundational gates are implemented in Jibb on those primitives. How that module supplies opaque types such as `poke` is still awaiting @iko’s answer: question 24 records the alternatives of a compiler-provided private interface or syntax for private opaque declarations.
52+1. **Specify the prelude inventory.** The checker needs the prelude's complete exported inventory and signatures; include all names from the listed Hoon library sections except explicitly excluded groups, as `docs/open-questions.md` question 3 records. The prelude imports private helpers and low-level primitives from a separate internal module without exposing them; its public foundational gates are implemented in Jibb on those primitives. The source-backed internal module defines `poke`; the public prelude exposes only its opaque type, and the checker hides its representation from ordinary modules, as question 24 records. Derived gates and `pure` remain its builders. This decision does not specify the representation of `ask` or `qath`.
5353
5454 The plan's three core-language rules were adopted: gate-free `eq` arguments and map and set keys, with gates opaque for union matching; jetted prelude functions taking gates; and rejection of a non-gate value that depends on itself even through a gate.
55552. **Start the importer early**, as the plan's Risks ask: first on a small `/sur` file, then on Tlon's. "Suggested design" below has a way in.
docs/spec/decisions.md+1
@@ -32,6 +32,7 @@ The choices behind the Language tab, made on 2026-10-23; a later date marks a re
3232| Special rules | No built-ins; type-directed rules are welcome, each listed in the Grammar tab | Decided 2026-10-29 |
3333| Inference | Hindley–Milner with aura variables; `@` is any atom, a specific atom fits `@` and a more specific aura fits an ancestor in its Hoon aura family, but each reverse needs a check, and repeated atom-constrained capitals give the same type; a number takes `@ud` only where its `++` isn't generic over its aura; distinct specific auras remain distinct; faces are part of record types, and an unnamed position can take a face but two different faces don't unify; principal types | Decided 2026-10-30 |
3434| Effects | The library unions `cmd` and `sub`; pokes and requests are opaque, from derived gates and `pure`; islands read agents only by watching; replies get full state, and diffs take a fold; timers carry the time; `%who` gives the owner's `@p`; nacks reach replies as text | Decided 2026-10-29 |
35+| Opaque poke representation | The source-backed private internal prelude module defines `poke`; the public prelude exposes only its opaque type, and the checker hides its representation from ordinary modules. Its builders remain derived gates and `pure` | Decided 2026-10-31 |
3536| Agent APIs | `/ui/api/<agent>.jibb` with `+$ poke` and `+$ paths`, over the agent's mark types; a case is a name, a path and a type, with `(facts full diff …)` for diffs, told apart by mark; an optional scry path, for pages; an island watching such a request has a type error; typed segments by aura | Decided 2026-10-30 |
3637| Mark names | Any name: `/%` names types after marks, and constructors poke with their type's mark; no alias marks | Decided 2026-10-26 |
3738| Derived gates | API files and stores give a constructor per poke type and a checked request per path or store state; clashing names are errors, including a derived name that clashes with an import face | Decided 2026-10-30 |
docs/spec/grammar.md+1−1
@@ -129,7 +129,7 @@ A mold is only a type: never called on a noun, and with no default. Types are in
129129- **Paths**: `/todos` is constant, `/` empty, and `/todo/[id=@ud]` typed by aura. `%/blog/(slug)` is an `qath`, checked against routes and static files.
130130- **Generic molds**: `+$ result |$ [V E]` with cases below; `|$` goes only right after a `+$`'s name.
131131- **Noun**: `*`, not a type variable; use a capital for a generic type. A value already known to have a more specific noun type, such as `@ud`, can be used where `*` is expected. **Empty**: `!!`.
132−- **Opaque**: `poke`, `ask` and `qath`, built only by derived gates, `pure` and application-path literals. `(facts full diff …)` appears only in an API file's `paths`.
132+- **Opaque**: `poke`, `ask` and `qath`, built only by derived gates, `pure` and application-path literals. `poke` is defined in the source-backed private internal prelude module; the public prelude exposes only its opaque type, and the checker hides its representation from ordinary modules. Pokes are built by derived gates and `pure`. `(facts full diff …)` appears only in an API file's `paths`.
133133- **Identity**: recursive molds go by name and module.
134134
135135`eq`'s arguments and map and set keys must contain no gates, even nested inside another value. The checker infers this gate-free constraint on type variables and retains it when generalizing a `++`, so a generic helper that calls `eq` stays generic over gate-free types. Printed types show the constraint as `$-([A A] ?) where A contains no gates`. An inferred atom constraint prints as `$-([A A] A) where A is an atom`. Multiple clauses are comma-separated, as `where A is an atom, B contains no gates`. Union-case matching treats gates as opaque and never inspects a gate to distinguish cases.
docs/spec/overview.md+1−1
@@ -78,7 +78,7 @@ Unused molds are skipped, so unsupported constructs elsewhere in a `/sur` file a
7878
7979## Prelude
8080
81−Hoon's standard library regrouped, written in Jibb and vendored as `/lib/jibb/prelude`; an island's bundle carries only what it uses. The exported inventory includes all names from the Hoon library sections listed below, excluding the groups explicitly left out. Jetted prelude functions have working Jibb implementations; the compiler recognizes their shapes and uses the Hoon versions so jets can fire. They may take gates as arguments (Core language). Private helpers and low-level primitives live in a separate internal prelude module, imported without exposing them; foundational public gates are implemented in Jibb on top of those primitives. The prelude also holds `eq`, `not`, `page`, `program`, `store`, `pure`, `island`, and the layout elements and molds.
81+Hoon's standard library regrouped, written in Jibb and vendored as `/lib/jibb/prelude`; an island's bundle carries only what it uses. The exported inventory includes all names from the Hoon library sections listed below, excluding the groups explicitly left out. Jetted prelude functions have working Jibb implementations; the compiler recognizes their shapes and uses the Hoon versions so jets can fire. They may take gates as arguments (Core language). Private helpers and low-level primitives live in a separate internal prelude module, imported without exposing them; foundational public gates are implemented in Jibb on top of those primitives. This source-backed internal module defines `poke`; the public prelude exposes only its opaque type, and the checker hides its representation from ordinary modules. The prelude also holds `eq`, `not`, `page`, `program`, `store`, `pure`, `island`, and the layout elements and molds.
8282
8383| Group | Hoon | Jibb |
8484| --- | --- | --- |
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, the null singleton, 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 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. Tagged `$%` cases can additionally use restricted local named payload molds, with a 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, 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 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. 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. 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. 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 for a known union accessed by a wing, including nested cell and list positions; 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. The cart-store example’s `init` and `update` now infer, while its kind, declarations and full module 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. 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; mutually recursive local groups and 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 selected Hoon atoms, term singletons, the null singleton, 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 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. Tagged `$%` cases can additionally use restricted local named payload molds, with a 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, 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 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. 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. 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. 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. The cart-store example’s `init` and `update` now infer, while its kind, declarations and full module 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. 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; mutually recursive local groups and 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−- 549 golden cases: 333 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 549-case corpus passed under `urbit eval` in 64.6 s. The fake ship passed all 556 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 37.0 s for sync and 42.9 s for tests. The importer golden compares 169 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+- 550 golden cases: 334 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 550-case corpus passed under `urbit eval` in 66.6 s. The fake ship passed all 557 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 38.4 s for sync and 44.4 s for tests. The importer golden compares 169 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).
@@ -103,14 +103,15 @@ Besides the plan's list:
103103| d69cc52 | 2026-10-31 | Infer longer cell binder patterns and prelude unit helpers |
104104| ae35005 | 2026-10-31 | Import source-verified tagged Hoon unions |
105105| ef2ea71 | 2026-10-31 | Report nested missing tags and contextualize union branch results |
106−| This change | 2026-10-31 | Infer local mutual gates and uncontextualized lists |
106+| 67f900e | 2026-10-31 | Infer local mutual gates and uncontextualized lists |
107+| This change | 2026-10-31 | Contextualize finite union patterns and record opaque poke decision |
107108
108109## Checking it
109110
110111On a machine set up as [development.md](development.md) says:
111112
112113```
113−tools/golden # 549 cases under urbit eval
114+tools/golden # 550 cases under urbit eval
114115tools/importer-test # the Hoon importer fixture projection
115116tools/type-import-test # the importer/checker bridge fixture
116117tools/type-mark-test # the mark/checker bridge fixture
@@ -120,7 +121,7 @@ tools/testdata/selftest # the tools themselves
120121tools/doc-blocks docs/spec # the doc's examples are golden cases
121122tools/ship start
122123tools/ship gen-tests --check # tests/lib/jibb.hoon is up to date
123−tools/ship test # the same 549 cases as -test arms on the ship
124+tools/ship test # the same 550 cases as -test arms on the ship
124125tools/testdata/ship-selftest
125126tools/ship check-commit # |commit stores .jibb files
126127tools/clay-fixtures # example /sur files and marks build through Clay
jibb-dev/lib/jibb.hoon+44−22
@@ -6901,14 +6901,14 @@
69016901 ?: mismatch `[%| ["union branch result matching needs unsupported inference" ~]]
69026902 $(arms t.arms, remaining (skim remaining |=(c=itype !=(%full (union-pattern pat.a c)))), st state.p.body, answer `result)
69036903::
6904−++ infer-known-union-context
6904+++ infer-known-union-context-whole
69056905 |= [e=expr expected=itype env=ienv state=istate context=span]
6906− ^- iresult
6906+ ^- (unit iresult)
69076907 ?> ?=(%branch -.e)
69086908 =/ subject=iresult (infer-fragment subject.e env state)
6909− ?: ?=(%| -.subject) subject
6909+ ?: ?=(%| -.subject) `subject
69106910 =/ typ=itype (itype-normalize typ.p.subject sub.state.p.subject)
6911− ?. ?=(%union -.typ) [%| ["branch is not supported by partial inference" ~]]
6911+ ?. ?=(%union -.typ) `[%| ["branch is not supported by partial inference" ~]]
69126912 =/ cases=(list itype) cases.typ
69136913 =/ remaining=(list itype) cases
69146914 =/ arms=(list arm) arms.e
@@ -6917,37 +6917,37 @@
69176917 |-
69186918 ?~ arms
69196919 ?^ remaining
6920− [%| ["missing union case {(show-itype i.remaining sub.st)}" ~]]
6921− ?~ answer [%| ["empty union branch is not supported by partial inference" ~]]
6922− [%& expected st]
6920+ `[%| ["missing union case {(show-itype i.remaining sub.st)}" ~]]
6921+ ?~ answer `[%| ["empty union branch is not supported by partial inference" ~]]
6922+ `[%& expected st]
69236923 =/ a=arm i.arms
69246924 ?: (lien remaining |=(c=itype =(%unknown (union-pattern pat.a c))))
6925− [%| ["partial union pattern is not supported by partial inference" ~]]
6925+ ~
69266926 =/ matching=(list itype) (skim remaining |=(c=itype =(%full (union-pattern pat.a c))))
69276927 ?~ matching
69286928 ?: (lien cases |=(c=itype =(%full (union-pattern pat.a c))))
6929− [%| ["branch arm is covered by earlier arms" ~[[at.pat.a "covered arm"]]]]
6930− [%| ["union pattern is not supported by partial inference" ~]]
6929+ `[%| ["branch arm is covered by earlier arms" ~[[at.pat.a "covered arm"]]]]
6930+ `[%| ["union pattern is not supported by partial inference" ~]]
69316931 ?: &(?=(^ t.matching) (union-pattern-has-bind pat.a))
6932− [%| ["a union pattern binding several cases is not supported by partial inference" ~]]
6932+ `[%| ["a union pattern binding several cases is not supported by partial inference" ~]]
69336933 =/ bound=(unit ienv) (union-pattern-bind pat.a i.matching env globals.st)
6934− ?~ bound [%| ["pattern binder shadows a name" ~]]
6934+ ?~ bound `[%| ["pattern binder shadows a name" ~]]
69356935 =/ body=iresult (infer-call-context-arg val.a expected u.bound st context)
6936− ?: ?=(%| -.body) body
6936+ ?: ?=(%| -.body) `body
69376937 =/ fit=ifit (itype-fit typ.p.body expected sub.state.p.body next.state.p.body)
6938− ?: ?=(%unknown -.fit) [%| ["union branch result constraint is not supported by partial inference" ~]]
6938+ ?: ?=(%unknown -.fit) `[%| ["union branch result constraint is not supported by partial inference" ~]]
69396939 ?: ?=(%bad -.fit)
69406940 =/ missing=(unit idiag) (missing-union-tag val.a expected sub.state.p.body context)
6941− ?^ missing [%| u.missing]
6941+ ?^ missing `[%| u.missing]
69426942 =/ nested=(unit idiag) (nested-missing-tag val.a typ.p.body expected sub.state.p.body next.state.p.body context)
6943− ?^ nested [%| u.nested]
6944− [%| ["union branch arm does not fit its expected type" ~[[context "expected type"] [(span-of val.a) "branch arm"]]]]
6943+ ?^ nested `[%| u.nested]
6944+ `[%| ["union branch arm does not fit its expected type" ~[[context "expected type"] [(span-of val.a) "branch arm"]]]]
69456945 ?: (itype-has-tag (itype-normalize expected sub.fit))
6946− [%| ["union branch result needs context in partial inference" ~]]
6946+ `[%| ["union branch result needs context in partial inference" ~]]
69476947 $(arms t.arms, remaining (skim remaining |=(c=itype !=(%full (union-pattern pat.a c)))), st state.p.body(sub sub.fit, next next.fit), answer `expected)
69486948::
69496949++ infer-known-union-finite
6950− |= [e=expr env=ienv state=istate]
6950+ |= [e=expr env=ienv state=istate expected=(unit [typ=itype context=span])]
69516951 ^- iresult
69526952 ?> ?=(%branch -.e)
69536953 =/ subject=iresult (infer-fragment subject.e env state)
@@ -6966,7 +6966,8 @@
69666966 ?^ remaining
69676967 [%| ["missing union case {(show-itype part.i.remaining sub.st)}" ~]]
69686968 ?~ answer [%| ["empty union branch is not supported by partial inference" ~]]
6969− [%& u.answer st]
6969+ ?~ expected [%& u.answer st]
6970+ [%& typ.u.expected st]
69706971 =/ a=arm i.arms
69716972 ?: (lien remaining |=(c=ifinite =(%unknown (union-pattern pat.a part.c))))
69726973 [%| ["partial union pattern is not supported by partial inference" ~]]
@@ -6979,8 +6980,22 @@
69796980 [%| ["a union pattern binding several cases is not supported by partial inference" ~]]
69806981 =/ bound=(unit ienv) (union-pattern-bind pat.a base.i.matching env globals.st)
69816982 ?~ bound [%| ["pattern binder shadows a name" ~]]
6982− =/ body=iresult (infer-fragment val.a u.bound st)
6983+ =/ body=iresult
6984+ ?~ expected (infer-fragment val.a u.bound st)
6985+ (infer-call-context-arg val.a typ.u.expected u.bound st context.u.expected)
69836986 ?: ?=(%| -.body) body
6987+ ?^ expected
6988+ =/ fit=ifit (itype-fit typ.p.body typ.u.expected sub.state.p.body next.state.p.body)
6989+ ?: ?=(%unknown -.fit) [%| ["union branch result constraint is not supported by partial inference" ~]]
6990+ ?: ?=(%bad -.fit)
6991+ =/ missing=(unit idiag) (missing-union-tag val.a typ.u.expected sub.state.p.body context.u.expected)
6992+ ?^ missing [%| u.missing]
6993+ =/ nested=(unit idiag) (nested-missing-tag val.a typ.p.body typ.u.expected sub.state.p.body next.state.p.body context.u.expected)
6994+ ?^ nested [%| u.nested]
6995+ [%| ["union branch arm does not fit its expected type" ~[[context.u.expected "expected type"] [(span-of val.a) "branch arm"]]]]
6996+ ?: (itype-has-tag (itype-normalize typ.u.expected sub.fit))
6997+ [%| ["union branch result needs context in partial inference" ~]]
6998+ $(arms t.arms, remaining (skim remaining |=(c=ifinite !=(%full (union-pattern pat.a part.c)))), st state.p.body(sub sub.fit, next next.fit), answer `typ.u.expected)
69846999 =/ result=itype (itype-normalize typ.p.body sub.state.p.body)
69857000 =/ mismatch=? ?~(answer | !=((itype-normalize u.answer sub.state.p.body) result))
69867001 ?: mismatch [%| ["union branch result matching needs unsupported inference" ~]]
@@ -6990,7 +7005,14 @@
69907005 |= [e=expr env=ienv state=istate]
69917006 ^- iresult
69927007 =/ whole=(unit iresult) (infer-known-union-whole e env state)
6993− ?~ whole (infer-known-union-finite e env state)
7008+ ?~ whole (infer-known-union-finite e env state ~)
7009+ u.whole
7010+::
7011+++ infer-known-union-context
7012+ |= [e=expr expected=itype env=ienv state=istate context=span]
7013+ ^- iresult
7014+ =/ whole=(unit iresult) (infer-known-union-context-whole e expected env state context)
7015+ ?~ whole (infer-known-union-finite e env state `[expected context])
69947016 u.whole
69957017::
69967018++ known-union-subject
tests/golden/types-union-finite-context/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Patterns: branches are exhaustive and covered arms are errors; Literals by context: tags, cells and lists take their expected type from context.
2+tests: A known union with finite loobean refinements propagates expected result types through its arms. Missing and covered cases, unsupported partial patterns and cross-case binders, unknown targets and pending tags remain distinct; generic variables retain their scope.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/types-union-finite-context/modules.txtnew file+1
@@ -0,0 +1 @@
1+# Use the prepared prelude.
tests/golden/types-union-finite-context/source.jibbnew file+76
@@ -0,0 +1,76 @@
1++$ input
2+ [%p flag=? text=@t]
3+ %other
4++$ result
5+ %go
6+ %stay
7+++ tags |= x=input ^- result
8+ ?- x
9+ [%p %.y t] %go
10+ [%p %.n t] %stay
11+ %other %stay
12+++ wrong |= x=input ^- result
13+ ?- x
14+ [%p %.y t] %missing
15+ [%p %.n t] %stay
16+ %other %stay
17+++ lists |= x=input ^- (list @t)
18+ ?- x
19+ [%p %.y t] ~[t]
20+ [%p %.n t] ~[]
21+ %other ~
22+++ records |= x=input ^- [text=@t xs=(list @t)]
23+ ?- x
24+ [%p %.y t] [t ~[t]]
25+ [%p %.n t] [t ~[]]
26+ %other ["none" ~]
27+++ missing |= x=input ^- result
28+ ?- x
29+ [%p %.y t] %go
30+ %other %stay
31+++ dead |= x=input ^- result
32+ ?- x
33+ [%p %.y t] %go
34+ [%p %.y t] %stay
35+ * %stay
36+++ binder |= x=input ^- ?
37+ ?- x
38+ [%p flag text] flag
39+ %other %.n
40+++ unresolved |= x=input ^- (list @t)
41+ ~& %pending
42+ ?- x
43+ [%p %.y t] ~[t]
44+ [%p %.n t] ~[]
45+ %other ~
46+++ unknown-target |= [x=input y=A] ^- A
47+ ?- x
48+ [%p %.y t] %go
49+ [%p %.n t] %stay
50+ %other %stay
51+++ partial |= x=input ^- (list @t)
52+ ?- x
53+ [%p %.y "a"] ~[]
54+ * ~[]
55++$ dual
56+ [%p flag=?]
57+ [%q flag=?]
58+++ cross-origin |= x=dual ^- (list @t)
59+ ?- x
60+ [tag %.y] ~[]
61+ [tag %.n] ~[]
62+++ unknown-subject |= x ^- (list @t)
63+ ?- x
64+ [%p %.y t] ~[t]
65+ [%p %.n t] ~[]
66+ %other ~
67+++ generic |= [x=input a=A] ^- (list A)
68+ ?- x
69+ [%p %.y t] ~[a]
70+ [%p %.n t] ~[]
71+ %other ~
72+++ bad-generic |= [x=input a=A] ^- (list A)
73+ ?- x
74+ [%p %.y t] ~["bad"]
75+ [%p %.n t] ~[]
76+ %other ~
tests/golden/types-union-finite-context/tokens.txtnew file+529
@@ -0,0 +1,529 @@
1+1:1 glyph +$
2+1:4 name input
3+2:3 INDENT
4+2:3 glyph [
5+2:4 tight lit %p
6+2:7 name flag
7+2:11 tight glyph =
8+2:12 tight glyph ?
9+2:14 name text
10+2:18 tight glyph =
11+2:19 tight aura @t
12+2:21 tight glyph ]
13+3:3 NEWLINE
14+3:3 lit %other
15+4:1 DEDENT
16+4:1 NEWLINE
17+4:1 glyph +$
18+4:4 name result
19+5:3 INDENT
20+5:3 lit %go
21+6:3 NEWLINE
22+6:3 lit %stay
23+7:1 DEDENT
24+7:1 NEWLINE
25+7:1 glyph ++
26+7:4 name tags
27+7:9 glyph |=
28+7:12 name x
29+7:13 tight glyph =
30+7:14 tight name input
31+7:20 glyph ^-
32+7:23 name result
33+8:3 INDENT
34+8:3 glyph ?-
35+8:6 name x
36+9:5 INDENT
37+9:5 glyph [
38+9:6 tight lit %p
39+9:9 lit %.y
40+9:13 name t
41+9:14 tight glyph ]
42+9:16 lit %go
43+10:5 NEWLINE
44+10:5 glyph [
45+10:6 tight lit %p
46+10:9 lit %.n
47+10:13 name t
48+10:14 tight glyph ]
49+10:16 lit %stay
50+11:5 NEWLINE
51+11:5 lit %other
52+11:12 lit %stay
53+12:1 DEDENT
54+12:1 DEDENT
55+12:1 NEWLINE
56+12:1 glyph ++
57+12:4 name wrong
58+12:10 glyph |=
59+12:13 name x
60+12:14 tight glyph =
61+12:15 tight name input
62+12:21 glyph ^-
63+12:24 name result
64+13:3 INDENT
65+13:3 glyph ?-
66+13:6 name x
67+14:5 INDENT
68+14:5 glyph [
69+14:6 tight lit %p
70+14:9 lit %.y
71+14:13 name t
72+14:14 tight glyph ]
73+14:16 lit %missing
74+15:5 NEWLINE
75+15:5 glyph [
76+15:6 tight lit %p
77+15:9 lit %.n
78+15:13 name t
79+15:14 tight glyph ]
80+15:16 lit %stay
81+16:5 NEWLINE
82+16:5 lit %other
83+16:12 lit %stay
84+17:1 DEDENT
85+17:1 DEDENT
86+17:1 NEWLINE
87+17:1 glyph ++
88+17:4 name lists
89+17:10 glyph |=
90+17:13 name x
91+17:14 tight glyph =
92+17:15 tight name input
93+17:21 glyph ^-
94+17:24 glyph (
95+17:25 tight name list
96+17:30 aura @t
97+17:32 tight glyph )
98+18:3 INDENT
99+18:3 glyph ?-
100+18:6 name x
101+19:5 INDENT
102+19:5 glyph [
103+19:6 tight lit %p
104+19:9 lit %.y
105+19:13 name t
106+19:14 tight glyph ]
107+19:16 glyph ~[
108+19:18 tight name t
109+19:19 tight glyph ]
110+20:5 NEWLINE
111+20:5 glyph [
112+20:6 tight lit %p
113+20:9 lit %.n
114+20:13 name t
115+20:14 tight glyph ]
116+20:16 glyph ~[
117+20:18 tight glyph ]
118+21:5 NEWLINE
119+21:5 lit %other
120+21:12 lit ~
121+22:1 DEDENT
122+22:1 DEDENT
123+22:1 NEWLINE
124+22:1 glyph ++
125+22:4 name records
126+22:12 glyph |=
127+22:15 name x
128+22:16 tight glyph =
129+22:17 tight name input
130+22:23 glyph ^-
131+22:26 glyph [
132+22:27 tight name text
133+22:31 tight glyph =
134+22:32 tight aura @t
135+22:35 name xs
136+22:37 tight glyph =
137+22:38 tight glyph (
138+22:39 tight name list
139+22:44 aura @t
140+22:46 tight glyph )
141+22:47 tight glyph ]
142+23:3 INDENT
143+23:3 glyph ?-
144+23:6 name x
145+24:5 INDENT
146+24:5 glyph [
147+24:6 tight lit %p
148+24:9 lit %.y
149+24:13 name t
150+24:14 tight glyph ]
151+24:16 glyph [
152+24:17 tight name t
153+24:19 glyph ~[
154+24:21 tight name t
155+24:22 tight glyph ]
156+24:23 tight glyph ]
157+25:5 NEWLINE
158+25:5 glyph [
159+25:6 tight lit %p
160+25:9 lit %.n
161+25:13 name t
162+25:14 tight glyph ]
163+25:16 glyph [
164+25:17 tight name t
165+25:19 glyph ~[
166+25:21 tight glyph ]
167+25:22 tight glyph ]
168+26:5 NEWLINE
169+26:5 lit %other
170+26:12 glyph [
171+26:13 tight str "none"
172+26:20 lit ~
173+26:21 tight glyph ]
174+27:1 DEDENT
175+27:1 DEDENT
176+27:1 NEWLINE
177+27:1 glyph ++
178+27:4 name missing
179+27:12 glyph |=
180+27:15 name x
181+27:16 tight glyph =
182+27:17 tight name input
183+27:23 glyph ^-
184+27:26 name result
185+28:3 INDENT
186+28:3 glyph ?-
187+28:6 name x
188+29:5 INDENT
189+29:5 glyph [
190+29:6 tight lit %p
191+29:9 lit %.y
192+29:13 name t
193+29:14 tight glyph ]
194+29:16 lit %go
195+30:5 NEWLINE
196+30:5 lit %other
197+30:12 lit %stay
198+31:1 DEDENT
199+31:1 DEDENT
200+31:1 NEWLINE
201+31:1 glyph ++
202+31:4 name dead
203+31:9 glyph |=
204+31:12 name x
205+31:13 tight glyph =
206+31:14 tight name input
207+31:20 glyph ^-
208+31:23 name result
209+32:3 INDENT
210+32:3 glyph ?-
211+32:6 name x
212+33:5 INDENT
213+33:5 glyph [
214+33:6 tight lit %p
215+33:9 lit %.y
216+33:13 name t
217+33:14 tight glyph ]
218+33:16 lit %go
219+34:5 NEWLINE
220+34:5 glyph [
221+34:6 tight lit %p
222+34:9 lit %.y
223+34:13 name t
224+34:14 tight glyph ]
225+34:16 lit %stay
226+35:5 NEWLINE
227+35:5 glyph *
228+35:7 lit %stay
229+36:1 DEDENT
230+36:1 DEDENT
231+36:1 NEWLINE
232+36:1 glyph ++
233+36:4 name binder
234+36:11 glyph |=
235+36:14 name x
236+36:15 tight glyph =
237+36:16 tight name input
238+36:22 glyph ^-
239+36:25 glyph ?
240+37:3 INDENT
241+37:3 glyph ?-
242+37:6 name x
243+38:5 INDENT
244+38:5 glyph [
245+38:6 tight lit %p
246+38:9 name flag
247+38:14 name text
248+38:18 tight glyph ]
249+38:20 name flag
250+39:5 NEWLINE
251+39:5 lit %other
252+39:12 lit %.n
253+40:1 DEDENT
254+40:1 DEDENT
255+40:1 NEWLINE
256+40:1 glyph ++
257+40:4 name unresolved
258+40:15 glyph |=
259+40:18 name x
260+40:19 tight glyph =
261+40:20 tight name input
262+40:26 glyph ^-
263+40:29 glyph (
264+40:30 tight name list
265+40:35 aura @t
266+40:37 tight glyph )
267+41:3 INDENT
268+41:3 glyph ~&
269+41:6 lit %pending
270+42:5 INDENT
271+42:5 glyph ?-
272+42:8 name x
273+43:7 INDENT
274+43:7 glyph [
275+43:8 tight lit %p
276+43:11 lit %.y
277+43:15 name t
278+43:16 tight glyph ]
279+43:18 glyph ~[
280+43:20 tight name t
281+43:21 tight glyph ]
282+44:7 NEWLINE
283+44:7 glyph [
284+44:8 tight lit %p
285+44:11 lit %.n
286+44:15 name t
287+44:16 tight glyph ]
288+44:18 glyph ~[
289+44:20 tight glyph ]
290+45:7 NEWLINE
291+45:7 lit %other
292+45:14 lit ~
293+46:1 DEDENT
294+46:1 DEDENT
295+46:1 DEDENT
296+46:1 NEWLINE
297+46:1 glyph ++
298+46:4 name unknown-target
299+46:19 glyph |=
300+46:22 glyph [
301+46:23 tight name x
302+46:24 tight glyph =
303+46:25 tight name input
304+46:31 name y
305+46:32 tight glyph =
306+46:33 tight tvar A
307+46:34 tight glyph ]
308+46:36 glyph ^-
309+46:39 tvar A
310+47:3 INDENT
311+47:3 glyph ?-
312+47:6 name x
313+48:5 INDENT
314+48:5 glyph [
315+48:6 tight lit %p
316+48:9 lit %.y
317+48:13 name t
318+48:14 tight glyph ]
319+48:16 lit %go
320+49:5 NEWLINE
321+49:5 glyph [
322+49:6 tight lit %p
323+49:9 lit %.n
324+49:13 name t
325+49:14 tight glyph ]
326+49:16 lit %stay
327+50:5 NEWLINE
328+50:5 lit %other
329+50:12 lit %stay
330+51:1 DEDENT
331+51:1 DEDENT
332+51:1 NEWLINE
333+51:1 glyph ++
334+51:4 name partial
335+51:12 glyph |=
336+51:15 name x
337+51:16 tight glyph =
338+51:17 tight name input
339+51:23 glyph ^-
340+51:26 glyph (
341+51:27 tight name list
342+51:32 aura @t
343+51:34 tight glyph )
344+52:3 INDENT
345+52:3 glyph ?-
346+52:6 name x
347+53:5 INDENT
348+53:5 glyph [
349+53:6 tight lit %p
350+53:9 lit %.y
351+53:13 str "a"
352+53:16 tight glyph ]
353+53:18 glyph ~[
354+53:20 tight glyph ]
355+54:5 NEWLINE
356+54:5 glyph *
357+54:7 glyph ~[
358+54:9 tight glyph ]
359+55:1 DEDENT
360+55:1 DEDENT
361+55:1 NEWLINE
362+55:1 glyph +$
363+55:4 name dual
364+56:3 INDENT
365+56:3 glyph [
366+56:4 tight lit %p
367+56:7 name flag
368+56:11 tight glyph =
369+56:12 tight glyph ?
370+56:13 tight glyph ]
371+57:3 NEWLINE
372+57:3 glyph [
373+57:4 tight lit %q
374+57:7 name flag
375+57:11 tight glyph =
376+57:12 tight glyph ?
377+57:13 tight glyph ]
378+58:1 DEDENT
379+58:1 NEWLINE
380+58:1 glyph ++
381+58:4 name cross-origin
382+58:17 glyph |=
383+58:20 name x
384+58:21 tight glyph =
385+58:22 tight name dual
386+58:27 glyph ^-
387+58:30 glyph (
388+58:31 tight name list
389+58:36 aura @t
390+58:38 tight glyph )
391+59:3 INDENT
392+59:3 glyph ?-
393+59:6 name x
394+60:5 INDENT
395+60:5 glyph [
396+60:6 tight name tag
397+60:10 lit %.y
398+60:13 tight glyph ]
399+60:15 glyph ~[
400+60:17 tight glyph ]
401+61:5 NEWLINE
402+61:5 glyph [
403+61:6 tight name tag
404+61:10 lit %.n
405+61:13 tight glyph ]
406+61:15 glyph ~[
407+61:17 tight glyph ]
408+62:1 DEDENT
409+62:1 DEDENT
410+62:1 NEWLINE
411+62:1 glyph ++
412+62:4 name unknown-subject
413+62:20 glyph |=
414+62:23 name x
415+62:25 glyph ^-
416+62:28 glyph (
417+62:29 tight name list
418+62:34 aura @t
419+62:36 tight glyph )
420+63:3 INDENT
421+63:3 glyph ?-
422+63:6 name x
423+64:5 INDENT
424+64:5 glyph [
425+64:6 tight lit %p
426+64:9 lit %.y
427+64:13 name t
428+64:14 tight glyph ]
429+64:16 glyph ~[
430+64:18 tight name t
431+64:19 tight glyph ]
432+65:5 NEWLINE
433+65:5 glyph [
434+65:6 tight lit %p
435+65:9 lit %.n
436+65:13 name t
437+65:14 tight glyph ]
438+65:16 glyph ~[
439+65:18 tight glyph ]
440+66:5 NEWLINE
441+66:5 lit %other
442+66:12 lit ~
443+67:1 DEDENT
444+67:1 DEDENT
445+67:1 NEWLINE
446+67:1 glyph ++
447+67:4 name generic
448+67:12 glyph |=
449+67:15 glyph [
450+67:16 tight name x
451+67:17 tight glyph =
452+67:18 tight name input
453+67:24 name a
454+67:25 tight glyph =
455+67:26 tight tvar A
456+67:27 tight glyph ]
457+67:29 glyph ^-
458+67:32 glyph (
459+67:33 tight name list
460+67:38 tvar A
461+67:39 tight glyph )
462+68:3 INDENT
463+68:3 glyph ?-
464+68:6 name x
465+69:5 INDENT
466+69:5 glyph [
467+69:6 tight lit %p
468+69:9 lit %.y
469+69:13 name t
470+69:14 tight glyph ]
471+69:16 glyph ~[
472+69:18 tight name a
473+69:19 tight glyph ]
474+70:5 NEWLINE
475+70:5 glyph [
476+70:6 tight lit %p
477+70:9 lit %.n
478+70:13 name t
479+70:14 tight glyph ]
480+70:16 glyph ~[
481+70:18 tight glyph ]
482+71:5 NEWLINE
483+71:5 lit %other
484+71:12 lit ~
485+72:1 DEDENT
486+72:1 DEDENT
487+72:1 NEWLINE
488+72:1 glyph ++
489+72:4 name bad-generic
490+72:16 glyph |=
491+72:19 glyph [
492+72:20 tight name x
493+72:21 tight glyph =
494+72:22 tight name input
495+72:28 name a
496+72:29 tight glyph =
497+72:30 tight tvar A
498+72:31 tight glyph ]
499+72:33 glyph ^-
500+72:36 glyph (
501+72:37 tight name list
502+72:42 tvar A
503+72:43 tight glyph )
504+73:3 INDENT
505+73:3 glyph ?-
506+73:6 name x
507+74:5 INDENT
508+74:5 glyph [
509+74:6 tight lit %p
510+74:9 lit %.y
511+74:13 name t
512+74:14 tight glyph ]
513+74:16 glyph ~[
514+74:18 tight str "bad"
515+74:23 tight glyph ]
516+75:5 NEWLINE
517+75:5 glyph [
518+75:6 tight lit %p
519+75:9 lit %.n
520+75:13 name t
521+75:14 tight glyph ]
522+75:16 glyph ~[
523+75:18 tight glyph ]
524+76:5 NEWLINE
525+76:5 lit %other
526+76:12 lit ~
527+76:13 DEDENT
528+76:13 DEDENT
529+76:13 NEWLINE
tests/golden/types-union-finite-context/tree.txtnew file+234
@@ -0,0 +1,234 @@
1+(module
2+ (mold 1:1 input
3+ (union 2:3
4+ (cell 2:3
5+ (const 2:4 %p)
6+ (face 2:7 flag (flag 2:12))
7+ (face 2:14 text (aura 2:19 @t)))
8+ (const 3:3 %other)))
9+ (mold 4:1 result
10+ (union 5:3 (const 5:3 %go) (const 6:3 %stay)))
11+ (value 7:1 tags
12+ (gate 7:9
13+ (face 7:12 x (ref 7:14 input))
14+ (cast 7:20
15+ (ref 7:23 result)
16+ (body 8:3
17+ (branch 8:3
18+ (wing 8:6 x)
19+ (arm 9:5
20+ (cell 9:5 (lit 9:6 %p) (lit 9:9 %.y) (bind 9:13 t))
21+ (lit 9:16 %go))
22+ (arm 10:5
23+ (cell 10:5 (lit 10:6 %p) (lit 10:9 %.n) (bind 10:13 t))
24+ (lit 10:16 %stay))
25+ (arm 11:5 (lit 11:5 %other) (lit 11:12 %stay)))))))
26+ (value 12:1 wrong
27+ (gate 12:10
28+ (face 12:13 x (ref 12:15 input))
29+ (cast 12:21
30+ (ref 12:24 result)
31+ (body 13:3
32+ (branch 13:3
33+ (wing 13:6 x)
34+ (arm 14:5
35+ (cell 14:5 (lit 14:6 %p) (lit 14:9 %.y) (bind 14:13 t))
36+ (lit 14:16 %missing))
37+ (arm 15:5
38+ (cell 15:5 (lit 15:6 %p) (lit 15:9 %.n) (bind 15:13 t))
39+ (lit 15:16 %stay))
40+ (arm 16:5 (lit 16:5 %other) (lit 16:12 %stay)))))))
41+ (value 17:1 lists
42+ (gate 17:10
43+ (face 17:13 x (ref 17:15 input))
44+ (cast 17:21
45+ (apply 17:24 list (aura 17:30 @t))
46+ (body 18:3
47+ (branch 18:3
48+ (wing 18:6 x)
49+ (arm 19:5
50+ (cell 19:5 (lit 19:6 %p) (lit 19:9 %.y) (bind 19:13 t))
51+ (list 19:16 (wing 19:18 t)))
52+ (arm 20:5
53+ (cell 20:5 (lit 20:6 %p) (lit 20:9 %.n) (bind 20:13 t))
54+ (list 20:16))
55+ (arm 21:5 (lit 21:5 %other) (lit 21:12 ~)))))))
56+ (value 22:1 records
57+ (gate 22:12
58+ (face 22:15 x (ref 22:17 input))
59+ (cast 22:23
60+ (cell 22:26
61+ (face 22:27 text (aura 22:32 @t))
62+ (face 22:35 xs
63+ (apply 22:38 list (aura 22:44 @t))))
64+ (body 23:3
65+ (branch 23:3
66+ (wing 23:6 x)
67+ (arm 24:5
68+ (cell 24:5 (lit 24:6 %p) (lit 24:9 %.y) (bind 24:13 t))
69+ (tuple 24:16
70+ (wing 24:17 t)
71+ (list 24:19 (wing 24:21 t))))
72+ (arm 25:5
73+ (cell 25:5 (lit 25:6 %p) (lit 25:9 %.n) (bind 25:13 t))
74+ (tuple 25:16 (wing 25:17 t) (list 25:19)))
75+ (arm 26:5
76+ (lit 26:5 %other)
77+ (tuple 26:12 (str 26:13 "none") (lit 26:20 ~))))))))
78+ (value 27:1 missing
79+ (gate 27:12
80+ (face 27:15 x (ref 27:17 input))
81+ (cast 27:23
82+ (ref 27:26 result)
83+ (body 28:3
84+ (branch 28:3
85+ (wing 28:6 x)
86+ (arm 29:5
87+ (cell 29:5 (lit 29:6 %p) (lit 29:9 %.y) (bind 29:13 t))
88+ (lit 29:16 %go))
89+ (arm 30:5 (lit 30:5 %other) (lit 30:12 %stay)))))))
90+ (value 31:1 dead
91+ (gate 31:9
92+ (face 31:12 x (ref 31:14 input))
93+ (cast 31:20
94+ (ref 31:23 result)
95+ (body 32:3
96+ (branch 32:3
97+ (wing 32:6 x)
98+ (arm 33:5
99+ (cell 33:5 (lit 33:6 %p) (lit 33:9 %.y) (bind 33:13 t))
100+ (lit 33:16 %go))
101+ (arm 34:5
102+ (cell 34:5 (lit 34:6 %p) (lit 34:9 %.y) (bind 34:13 t))
103+ (lit 34:16 %stay))
104+ (arm 35:5 (any 35:5) (lit 35:7 %stay)))))))
105+ (value 36:1 binder
106+ (gate 36:11
107+ (face 36:14 x (ref 36:16 input))
108+ (cast 36:22
109+ (flag 36:25)
110+ (body 37:3
111+ (branch 37:3
112+ (wing 37:6 x)
113+ (arm 38:5
114+ (cell 38:5 (lit 38:6 %p) (bind 38:9 flag) (bind 38:14 text))
115+ (wing 38:20 flag))
116+ (arm 39:5 (lit 39:5 %other) (lit 39:12 %.n)))))))
117+ (value 40:1 unresolved
118+ (gate 40:15
119+ (face 40:18 x (ref 40:20 input))
120+ (cast 40:26
121+ (apply 40:29 list (aura 40:35 @t))
122+ (body 41:3
123+ (trace 41:3
124+ (lit 41:6 %pending)
125+ (body 42:5
126+ (branch 42:5
127+ (wing 42:8 x)
128+ (arm 43:7
129+ (cell 43:7 (lit 43:8 %p) (lit 43:11 %.y) (bind 43:15 t))
130+ (list 43:18 (wing 43:20 t)))
131+ (arm 44:7
132+ (cell 44:7 (lit 44:8 %p) (lit 44:11 %.n) (bind 44:15 t))
133+ (list 44:18))
134+ (arm 45:7 (lit 45:7 %other) (lit 45:14 ~)))))))))
135+ (value 46:1 unknown-target
136+ (gate 46:19
137+ (cell 46:22
138+ (face 46:23 x (ref 46:25 input))
139+ (face 46:31 y (tvar 46:33 A)))
140+ (cast 46:36
141+ (tvar 46:39 A)
142+ (body 47:3
143+ (branch 47:3
144+ (wing 47:6 x)
145+ (arm 48:5
146+ (cell 48:5 (lit 48:6 %p) (lit 48:9 %.y) (bind 48:13 t))
147+ (lit 48:16 %go))
148+ (arm 49:5
149+ (cell 49:5 (lit 49:6 %p) (lit 49:9 %.n) (bind 49:13 t))
150+ (lit 49:16 %stay))
151+ (arm 50:5 (lit 50:5 %other) (lit 50:12 %stay)))))))
152+ (value 51:1 partial
153+ (gate 51:12
154+ (face 51:15 x (ref 51:17 input))
155+ (cast 51:23
156+ (apply 51:26 list (aura 51:32 @t))
157+ (body 52:3
158+ (branch 52:3
159+ (wing 52:6 x)
160+ (arm 53:5
161+ (cell 53:5 (lit 53:6 %p) (lit 53:9 %.y) (str 53:13 "a"))
162+ (list 53:18))
163+ (arm 54:5 (any 54:5) (list 54:7)))))))
164+ (mold 55:1 dual
165+ (union 56:3
166+ (cell 56:3
167+ (const 56:4 %p)
168+ (face 56:7 flag (flag 56:12)))
169+ (cell 57:3
170+ (const 57:4 %q)
171+ (face 57:7 flag (flag 57:12)))))
172+ (value 58:1 cross-origin
173+ (gate 58:17
174+ (face 58:20 x (ref 58:22 dual))
175+ (cast 58:27
176+ (apply 58:30 list (aura 58:36 @t))
177+ (body 59:3
178+ (branch 59:3
179+ (wing 59:6 x)
180+ (arm 60:5
181+ (cell 60:5 (bind 60:6 tag) (lit 60:10 %.y))
182+ (list 60:15))
183+ (arm 61:5
184+ (cell 61:5 (bind 61:6 tag) (lit 61:10 %.n))
185+ (list 61:15)))))))
186+ (value 62:1 unknown-subject
187+ (gate 62:20
188+ (bind 62:23 x)
189+ (cast 62:25
190+ (apply 62:28 list (aura 62:34 @t))
191+ (body 63:3
192+ (branch 63:3
193+ (wing 63:6 x)
194+ (arm 64:5
195+ (cell 64:5 (lit 64:6 %p) (lit 64:9 %.y) (bind 64:13 t))
196+ (list 64:16 (wing 64:18 t)))
197+ (arm 65:5
198+ (cell 65:5 (lit 65:6 %p) (lit 65:9 %.n) (bind 65:13 t))
199+ (list 65:16))
200+ (arm 66:5 (lit 66:5 %other) (lit 66:12 ~)))))))
201+ (value 67:1 generic
202+ (gate 67:12
203+ (cell 67:15
204+ (face 67:16 x (ref 67:18 input))
205+ (face 67:24 a (tvar 67:26 A)))
206+ (cast 67:29
207+ (apply 67:32 list (tvar 67:38 A))
208+ (body 68:3
209+ (branch 68:3
210+ (wing 68:6 x)
211+ (arm 69:5
212+ (cell 69:5 (lit 69:6 %p) (lit 69:9 %.y) (bind 69:13 t))
213+ (list 69:16 (wing 69:18 a)))
214+ (arm 70:5
215+ (cell 70:5 (lit 70:6 %p) (lit 70:9 %.n) (bind 70:13 t))
216+ (list 70:16))
217+ (arm 71:5 (lit 71:5 %other) (lit 71:12 ~)))))))
218+ (value 72:1 bad-generic
219+ (gate 72:16
220+ (cell 72:19
221+ (face 72:20 x (ref 72:22 input))
222+ (face 72:28 a (tvar 72:30 A)))
223+ (cast 72:33
224+ (apply 72:36 list (tvar 72:42 A))
225+ (body 73:3
226+ (branch 73:3
227+ (wing 73:6 x)
228+ (arm 74:5
229+ (cell 74:5 (lit 74:6 %p) (lit 74:9 %.y) (bind 74:13 t))
230+ (list 74:16 (str 74:18 "bad")))
231+ (arm 75:5
232+ (cell 75:5 (lit 75:6 %p) (lit 75:9 %.n) (bind 75:13 t))
233+ (list 75:16))
234+ (arm 76:5 (lit 76:5 %other) (lit 76:12 ~))))))))
tests/golden/types-union-finite-context/types.txtnew file+27
@@ -0,0 +1,27 @@
1+partial inference; module not checked
2++$ input: cases proven disjoint; mold not checked
3++$ result: cases proven disjoint; mold not checked
4+++ tags: $-(input result)
5+++ wrong: result has no case `%missing`
6+/tests/golden/types-union-finite-context/source.jibb:12:24: expected union
7+++ wrong |= x=input ^- result
8+ ^
9+/tests/golden/types-union-finite-context/source.jibb:14:16: tag
10+ [%p %.y t] %missing
11+ ^
12+++ lists: $-(input (list @t))
13+++ records: $-(input [text=@t xs=(list @t)])
14+++ missing: missing union case [%p [flag=%.n text=@t]]
15+++ dead: branch arm is covered by earlier arms
16+/tests/golden/types-union-finite-context/source.jibb:34:5: covered arm
17+ [%p %.y t] %stay
18+ ^
19+++ binder: $-(input ?)
20+++ unresolved: tag needs context in partial inference
21+++ unknown-target: union branch result needs context in partial inference
22+++ partial: partial union pattern is not supported by partial inference
23++$ dual: cases proven disjoint; mold not checked
24+++ cross-origin: a union pattern binding several cases is not supported by partial inference
25+++ unknown-subject: branch is not supported by partial inference
26+++ generic: $-([x=input a=A] (list A))
27+++ bad-generic: explicit capital constraints are not supported by partial inference
tests/lib/jibb.hoon+156−150
@@ -1848,129 +1848,133 @@
18481848/* tok-522 %txt /tests/golden/types-union-finite/tokens/txt
18491849/* tre-522 %txt /tests/golden/types-union-finite/tree/txt
18501850/* typ-522 %txt /tests/golden/types-union-finite/types/txt
1851−/* src-523 %jibb /tests/golden/types-union-finite-generic/source/jibb
1852−/* tok-523 %txt /tests/golden/types-union-finite-generic/tokens/txt
1853−/* tre-523 %txt /tests/golden/types-union-finite-generic/tree/txt
1854−/* typ-523 %txt /tests/golden/types-union-finite-generic/types/txt
1855−/* src-524 %jibb /tests/golden/types-union-finite-limit/source/jibb
1856−/* tok-524 %txt /tests/golden/types-union-finite-limit/tokens/txt
1857−/* tre-524 %txt /tests/golden/types-union-finite-limit/tree/txt
1858−/* typ-524 %txt /tests/golden/types-union-finite-limit/types/txt
1859−/* src-525 %jibb /tests/golden/types-union-import/source/jibb
1860−/* tok-525 %txt /tests/golden/types-union-import/tokens/txt
1861−/* tre-525 %txt /tests/golden/types-union-import/tree/txt
1862−/* mod-525-1 %jibb /tests/golden/types-union-import/modules/ui/lib/jibb
1863−/* typ-525 %txt /tests/golden/types-union-import/types/txt
1864−/* mtre-525 %txt /tests/golden/types-union-import/module-trees/txt
1865−/* src-526 %jibb /tests/golden/types-union-local-pending/source/jibb
1866−/* tok-526 %txt /tests/golden/types-union-local-pending/tokens/txt
1867−/* tre-526 %txt /tests/golden/types-union-local-pending/tree/txt
1868−/* typ-526 %txt /tests/golden/types-union-local-pending/types/txt
1869−/* src-527 %jibb /tests/golden/types-union-overlap/source/jibb
1870−/* tok-527 %txt /tests/golden/types-union-overlap/tokens/txt
1871−/* tre-527 %txt /tests/golden/types-union-overlap/tree/txt
1872−/* typ-527 %txt /tests/golden/types-union-overlap/types/txt
1873−/* src-528 %jibb /tests/golden/types-union-overlap-nested/source/jibb
1874−/* tok-528 %txt /tests/golden/types-union-overlap-nested/tokens/txt
1875−/* tre-528 %txt /tests/golden/types-union-overlap-nested/tree/txt
1876−/* typ-528 %txt /tests/golden/types-union-overlap-nested/types/txt
1877−/* src-529 %jibb /tests/golden/types-union-pattern-result-context/source/jibb
1878−/* tok-529 %txt /tests/golden/types-union-pattern-result-context/tokens/txt
1879−/* tre-529 %txt /tests/golden/types-union-pattern-result-context/tree/txt
1880−/* typ-529 %txt /tests/golden/types-union-pattern-result-context/types/txt
1881−/* src-530 %jibb /tests/golden/types-union-pattern-result-controls/source/jibb
1882−/* tok-530 %txt /tests/golden/types-union-pattern-result-controls/tokens/txt
1883−/* tre-530 %txt /tests/golden/types-union-pattern-result-controls/tree/txt
1884−/* typ-530 %txt /tests/golden/types-union-pattern-result-controls/types/txt
1885−/* src-531 %jibb /tests/golden/types-union-patterns/source/jibb
1886−/* tok-531 %txt /tests/golden/types-union-patterns/tokens/txt
1887−/* tre-531 %txt /tests/golden/types-union-patterns/tree/txt
1888−/* typ-531 %txt /tests/golden/types-union-patterns/types/txt
1889−/* src-532 %jibb /tests/golden/types-union-patterns-generic/source/jibb
1890−/* tok-532 %txt /tests/golden/types-union-patterns-generic/tokens/txt
1891−/* tre-532 %txt /tests/golden/types-union-patterns-generic/tree/txt
1892−/* typ-532 %txt /tests/golden/types-union-patterns-generic/types/txt
1893−/* src-533 %jibb /tests/golden/types-union-patterns-import/source/jibb
1894−/* tok-533 %txt /tests/golden/types-union-patterns-import/tokens/txt
1895−/* tre-533 %txt /tests/golden/types-union-patterns-import/tree/txt
1896−/* mod-533-1 %jibb /tests/golden/types-union-patterns-import/modules/ui/lib/jibb
1897−/* typ-533 %txt /tests/golden/types-union-patterns-import/types/txt
1898−/* mtre-533 %txt /tests/golden/types-union-patterns-import/module-trees/txt
1899−/* src-534 %jibb /tests/golden/types-union-phantom-generic/source/jibb
1900−/* tok-534 %txt /tests/golden/types-union-phantom-generic/tokens/txt
1901−/* tre-534 %txt /tests/golden/types-union-phantom-generic/tree/txt
1902−/* typ-534 %txt /tests/golden/types-union-phantom-generic/types/txt
1903−/* src-535 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
1904−/* tok-535 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
1905−/* tre-535 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
1906−/* mod-535-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
1907−/* typ-535 %txt /tests/golden/types-union-print-cross-namespace/types/txt
1908−/* mtre-535 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
1909−/* src-536 %jibb /tests/golden/types-union-print-distinct/source/jibb
1910−/* tok-536 %txt /tests/golden/types-union-print-distinct/tokens/txt
1911−/* tre-536 %txt /tests/golden/types-union-print-distinct/tree/txt
1912−/* mod-536-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
1913−/* mod-536-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
1914−/* mod-536-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
1915−/* typ-536 %txt /tests/golden/types-union-print-distinct/types/txt
1916−/* mtre-536 %txt /tests/golden/types-union-print-distinct/module-trees/txt
1917−/* src-537 %jibb /tests/golden/types-union-print-escape/source/jibb
1918−/* tok-537 %txt /tests/golden/types-union-print-escape/tokens/txt
1919−/* tre-537 %txt /tests/golden/types-union-print-escape/tree/txt
1920−/* typ-537 %txt /tests/golden/types-union-print-escape/types/txt
1921−/* src-538 %jibb /tests/golden/types-union-print-local/source/jibb
1922−/* tok-538 %txt /tests/golden/types-union-print-local/tokens/txt
1923−/* tre-538 %txt /tests/golden/types-union-print-local/tree/txt
1924−/* typ-538 %txt /tests/golden/types-union-print-local/types/txt
1925−/* src-539 %jibb /tests/golden/types-union-print-nested/source/jibb
1926−/* tok-539 %txt /tests/golden/types-union-print-nested/tokens/txt
1927−/* tre-539 %txt /tests/golden/types-union-print-nested/tree/txt
1928−/* typ-539 %txt /tests/golden/types-union-print-nested/types/txt
1929−/* src-540 %jibb /tests/golden/types-union-print-same-origin/source/jibb
1930−/* tok-540 %txt /tests/golden/types-union-print-same-origin/tokens/txt
1931−/* tre-540 %txt /tests/golden/types-union-print-same-origin/tree/txt
1932−/* mod-540-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
1933−/* typ-540 %txt /tests/golden/types-union-print-same-origin/types/txt
1934−/* mtre-540 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
1935−/* src-541 %jibb /tests/golden/types-union-print-transitive/source/jibb
1936−/* tok-541 %txt /tests/golden/types-union-print-transitive/tokens/txt
1937−/* tre-541 %txt /tests/golden/types-union-print-transitive/tree/txt
1938−/* mod-541-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
1939−/* mod-541-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
1940−/* typ-541 %txt /tests/golden/types-union-print-transitive/types/txt
1941−/* mtre-541 %txt /tests/golden/types-union-print-transitive/module-trees/txt
1942−/* src-542 %jibb /tests/golden/types-union-singleton/source/jibb
1943−/* tok-542 %txt /tests/golden/types-union-singleton/tokens/txt
1944−/* tre-542 %txt /tests/golden/types-union-singleton/tree/txt
1945−/* typ-542 %txt /tests/golden/types-union-singleton/types/txt
1946−/* src-543 %jibb /tests/golden/types-union-tag-atoms/source/jibb
1947−/* tok-543 %txt /tests/golden/types-union-tag-atoms/tokens/txt
1948−/* tre-543 %txt /tests/golden/types-union-tag-atoms/tree/txt
1949−/* typ-543 %txt /tests/golden/types-union-tag-atoms/types/txt
1950−/* src-544 %jibb /tests/golden/types-union-tags/source/jibb
1951−/* tok-544 %txt /tests/golden/types-union-tags/tokens/txt
1952−/* tre-544 %txt /tests/golden/types-union-tags/tree/txt
1953−/* typ-544 %txt /tests/golden/types-union-tags/types/txt
1954−/* src-545 %jibb /tests/golden/types-union-unresolved/source/jibb
1955−/* tok-545 %txt /tests/golden/types-union-unresolved/tokens/txt
1956−/* tre-545 %txt /tests/golden/types-union-unresolved/tree/txt
1957−/* typ-545 %txt /tests/golden/types-union-unresolved/types/txt
1958−/* src-546 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
1959−/* tok-546 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
1960−/* tre-546 %txt /tests/golden/types-union-unresolved-flow/tree/txt
1961−/* typ-546 %txt /tests/golden/types-union-unresolved-flow/types/txt
1962−/* src-547 %jibb /tests/golden/types-unit-construction/source/jibb
1963−/* tok-547 %txt /tests/golden/types-unit-construction/tokens/txt
1964−/* tre-547 %txt /tests/golden/types-unit-construction/tree/txt
1965−/* typ-547 %txt /tests/golden/types-unit-construction/types/txt
1966−/* src-548 %jibb /tests/golden/types-unit-context/source/jibb
1967−/* tok-548 %txt /tests/golden/types-unit-context/tokens/txt
1968−/* tre-548 %txt /tests/golden/types-unit-context/tree/txt
1969−/* typ-548 %txt /tests/golden/types-unit-context/types/txt
1970−/* src-549 %jibb /tests/golden/types-unit-patterns/source/jibb
1971−/* tok-549 %txt /tests/golden/types-unit-patterns/tokens/txt
1972−/* tre-549 %txt /tests/golden/types-unit-patterns/tree/txt
1973−/* typ-549 %txt /tests/golden/types-unit-patterns/types/txt
1851+/* src-523 %jibb /tests/golden/types-union-finite-context/source/jibb
1852+/* tok-523 %txt /tests/golden/types-union-finite-context/tokens/txt
1853+/* tre-523 %txt /tests/golden/types-union-finite-context/tree/txt
1854+/* typ-523 %txt /tests/golden/types-union-finite-context/types/txt
1855+/* src-524 %jibb /tests/golden/types-union-finite-generic/source/jibb
1856+/* tok-524 %txt /tests/golden/types-union-finite-generic/tokens/txt
1857+/* tre-524 %txt /tests/golden/types-union-finite-generic/tree/txt
1858+/* typ-524 %txt /tests/golden/types-union-finite-generic/types/txt
1859+/* src-525 %jibb /tests/golden/types-union-finite-limit/source/jibb
1860+/* tok-525 %txt /tests/golden/types-union-finite-limit/tokens/txt
1861+/* tre-525 %txt /tests/golden/types-union-finite-limit/tree/txt
1862+/* typ-525 %txt /tests/golden/types-union-finite-limit/types/txt
1863+/* src-526 %jibb /tests/golden/types-union-import/source/jibb
1864+/* tok-526 %txt /tests/golden/types-union-import/tokens/txt
1865+/* tre-526 %txt /tests/golden/types-union-import/tree/txt
1866+/* mod-526-1 %jibb /tests/golden/types-union-import/modules/ui/lib/jibb
1867+/* typ-526 %txt /tests/golden/types-union-import/types/txt
1868+/* mtre-526 %txt /tests/golden/types-union-import/module-trees/txt
1869+/* src-527 %jibb /tests/golden/types-union-local-pending/source/jibb
1870+/* tok-527 %txt /tests/golden/types-union-local-pending/tokens/txt
1871+/* tre-527 %txt /tests/golden/types-union-local-pending/tree/txt
1872+/* typ-527 %txt /tests/golden/types-union-local-pending/types/txt
1873+/* src-528 %jibb /tests/golden/types-union-overlap/source/jibb
1874+/* tok-528 %txt /tests/golden/types-union-overlap/tokens/txt
1875+/* tre-528 %txt /tests/golden/types-union-overlap/tree/txt
1876+/* typ-528 %txt /tests/golden/types-union-overlap/types/txt
1877+/* src-529 %jibb /tests/golden/types-union-overlap-nested/source/jibb
1878+/* tok-529 %txt /tests/golden/types-union-overlap-nested/tokens/txt
1879+/* tre-529 %txt /tests/golden/types-union-overlap-nested/tree/txt
1880+/* typ-529 %txt /tests/golden/types-union-overlap-nested/types/txt
1881+/* src-530 %jibb /tests/golden/types-union-pattern-result-context/source/jibb
1882+/* tok-530 %txt /tests/golden/types-union-pattern-result-context/tokens/txt
1883+/* tre-530 %txt /tests/golden/types-union-pattern-result-context/tree/txt
1884+/* typ-530 %txt /tests/golden/types-union-pattern-result-context/types/txt
1885+/* src-531 %jibb /tests/golden/types-union-pattern-result-controls/source/jibb
1886+/* tok-531 %txt /tests/golden/types-union-pattern-result-controls/tokens/txt
1887+/* tre-531 %txt /tests/golden/types-union-pattern-result-controls/tree/txt
1888+/* typ-531 %txt /tests/golden/types-union-pattern-result-controls/types/txt
1889+/* src-532 %jibb /tests/golden/types-union-patterns/source/jibb
1890+/* tok-532 %txt /tests/golden/types-union-patterns/tokens/txt
1891+/* tre-532 %txt /tests/golden/types-union-patterns/tree/txt
1892+/* typ-532 %txt /tests/golden/types-union-patterns/types/txt
1893+/* src-533 %jibb /tests/golden/types-union-patterns-generic/source/jibb
1894+/* tok-533 %txt /tests/golden/types-union-patterns-generic/tokens/txt
1895+/* tre-533 %txt /tests/golden/types-union-patterns-generic/tree/txt
1896+/* typ-533 %txt /tests/golden/types-union-patterns-generic/types/txt
1897+/* src-534 %jibb /tests/golden/types-union-patterns-import/source/jibb
1898+/* tok-534 %txt /tests/golden/types-union-patterns-import/tokens/txt
1899+/* tre-534 %txt /tests/golden/types-union-patterns-import/tree/txt
1900+/* mod-534-1 %jibb /tests/golden/types-union-patterns-import/modules/ui/lib/jibb
1901+/* typ-534 %txt /tests/golden/types-union-patterns-import/types/txt
1902+/* mtre-534 %txt /tests/golden/types-union-patterns-import/module-trees/txt
1903+/* src-535 %jibb /tests/golden/types-union-phantom-generic/source/jibb
1904+/* tok-535 %txt /tests/golden/types-union-phantom-generic/tokens/txt
1905+/* tre-535 %txt /tests/golden/types-union-phantom-generic/tree/txt
1906+/* typ-535 %txt /tests/golden/types-union-phantom-generic/types/txt
1907+/* src-536 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
1908+/* tok-536 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
1909+/* tre-536 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
1910+/* mod-536-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
1911+/* typ-536 %txt /tests/golden/types-union-print-cross-namespace/types/txt
1912+/* mtre-536 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
1913+/* src-537 %jibb /tests/golden/types-union-print-distinct/source/jibb
1914+/* tok-537 %txt /tests/golden/types-union-print-distinct/tokens/txt
1915+/* tre-537 %txt /tests/golden/types-union-print-distinct/tree/txt
1916+/* mod-537-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
1917+/* mod-537-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
1918+/* mod-537-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
1919+/* typ-537 %txt /tests/golden/types-union-print-distinct/types/txt
1920+/* mtre-537 %txt /tests/golden/types-union-print-distinct/module-trees/txt
1921+/* src-538 %jibb /tests/golden/types-union-print-escape/source/jibb
1922+/* tok-538 %txt /tests/golden/types-union-print-escape/tokens/txt
1923+/* tre-538 %txt /tests/golden/types-union-print-escape/tree/txt
1924+/* typ-538 %txt /tests/golden/types-union-print-escape/types/txt
1925+/* src-539 %jibb /tests/golden/types-union-print-local/source/jibb
1926+/* tok-539 %txt /tests/golden/types-union-print-local/tokens/txt
1927+/* tre-539 %txt /tests/golden/types-union-print-local/tree/txt
1928+/* typ-539 %txt /tests/golden/types-union-print-local/types/txt
1929+/* src-540 %jibb /tests/golden/types-union-print-nested/source/jibb
1930+/* tok-540 %txt /tests/golden/types-union-print-nested/tokens/txt
1931+/* tre-540 %txt /tests/golden/types-union-print-nested/tree/txt
1932+/* typ-540 %txt /tests/golden/types-union-print-nested/types/txt
1933+/* src-541 %jibb /tests/golden/types-union-print-same-origin/source/jibb
1934+/* tok-541 %txt /tests/golden/types-union-print-same-origin/tokens/txt
1935+/* tre-541 %txt /tests/golden/types-union-print-same-origin/tree/txt
1936+/* mod-541-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
1937+/* typ-541 %txt /tests/golden/types-union-print-same-origin/types/txt
1938+/* mtre-541 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
1939+/* src-542 %jibb /tests/golden/types-union-print-transitive/source/jibb
1940+/* tok-542 %txt /tests/golden/types-union-print-transitive/tokens/txt
1941+/* tre-542 %txt /tests/golden/types-union-print-transitive/tree/txt
1942+/* mod-542-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
1943+/* mod-542-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
1944+/* typ-542 %txt /tests/golden/types-union-print-transitive/types/txt
1945+/* mtre-542 %txt /tests/golden/types-union-print-transitive/module-trees/txt
1946+/* src-543 %jibb /tests/golden/types-union-singleton/source/jibb
1947+/* tok-543 %txt /tests/golden/types-union-singleton/tokens/txt
1948+/* tre-543 %txt /tests/golden/types-union-singleton/tree/txt
1949+/* typ-543 %txt /tests/golden/types-union-singleton/types/txt
1950+/* src-544 %jibb /tests/golden/types-union-tag-atoms/source/jibb
1951+/* tok-544 %txt /tests/golden/types-union-tag-atoms/tokens/txt
1952+/* tre-544 %txt /tests/golden/types-union-tag-atoms/tree/txt
1953+/* typ-544 %txt /tests/golden/types-union-tag-atoms/types/txt
1954+/* src-545 %jibb /tests/golden/types-union-tags/source/jibb
1955+/* tok-545 %txt /tests/golden/types-union-tags/tokens/txt
1956+/* tre-545 %txt /tests/golden/types-union-tags/tree/txt
1957+/* typ-545 %txt /tests/golden/types-union-tags/types/txt
1958+/* src-546 %jibb /tests/golden/types-union-unresolved/source/jibb
1959+/* tok-546 %txt /tests/golden/types-union-unresolved/tokens/txt
1960+/* tre-546 %txt /tests/golden/types-union-unresolved/tree/txt
1961+/* typ-546 %txt /tests/golden/types-union-unresolved/types/txt
1962+/* src-547 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
1963+/* tok-547 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
1964+/* tre-547 %txt /tests/golden/types-union-unresolved-flow/tree/txt
1965+/* typ-547 %txt /tests/golden/types-union-unresolved-flow/types/txt
1966+/* src-548 %jibb /tests/golden/types-unit-construction/source/jibb
1967+/* tok-548 %txt /tests/golden/types-unit-construction/tokens/txt
1968+/* tre-548 %txt /tests/golden/types-unit-construction/tree/txt
1969+/* typ-548 %txt /tests/golden/types-unit-construction/types/txt
1970+/* src-549 %jibb /tests/golden/types-unit-context/source/jibb
1971+/* tok-549 %txt /tests/golden/types-unit-context/tokens/txt
1972+/* tre-549 %txt /tests/golden/types-unit-context/tree/txt
1973+/* typ-549 %txt /tests/golden/types-unit-context/types/txt
1974+/* src-550 %jibb /tests/golden/types-unit-patterns/source/jibb
1975+/* tok-550 %txt /tests/golden/types-unit-patterns/tokens/txt
1976+/* tre-550 %txt /tests/golden/types-unit-patterns/tree/txt
1977+/* typ-550 %txt /tests/golden/types-unit-patterns/types/txt
19741978=/ prepared-prelude (prepare-prelude:jibb prelude-source)
19751979|%
19761980:: one arm per case
@@ -3019,60 +3023,62 @@
30193023 (weld (check ~.types-union-context-flow src-521 `tok-521 `tre-521) (check-types ~.types-union-context-flow ~[%tests %golden ~.types-union-context-flow %source %jibb] src-521 `typ-521))
30203024++ test-types-union-finite
30213025 (weld (check ~.types-union-finite src-522 `tok-522 `tre-522) (check-module-types ~.types-union-finite ~[%tests %golden ~.types-union-finite %source %jibb] src-522 `typ-522 ~ ~ ~))
3026+++ test-types-union-finite-context
3027+ (weld (check ~.types-union-finite-context src-523 `tok-523 `tre-523) (check-module-types ~.types-union-finite-context ~[%tests %golden ~.types-union-finite-context %source %jibb] src-523 `typ-523 ~ ~ ~))
30223028++ test-types-union-finite-generic
3023− (weld (check ~.types-union-finite-generic src-523 `tok-523 `tre-523) (check-module-types ~.types-union-finite-generic ~[%tests %golden ~.types-union-finite-generic %source %jibb] src-523 `typ-523 ~ ~ ~))
3029+ (weld (check ~.types-union-finite-generic src-524 `tok-524 `tre-524) (check-module-types ~.types-union-finite-generic ~[%tests %golden ~.types-union-finite-generic %source %jibb] src-524 `typ-524 ~ ~ ~))
30243030++ test-types-union-finite-limit
3025− (weld (check ~.types-union-finite-limit src-524 `tok-524 `tre-524) (check-module-types ~.types-union-finite-limit ~[%tests %golden ~.types-union-finite-limit %source %jibb] src-524 `typ-524 ~ ~ ~))
3031+ (weld (check ~.types-union-finite-limit src-525 `tok-525 `tre-525) (check-module-types ~.types-union-finite-limit ~[%tests %golden ~.types-union-finite-limit %source %jibb] src-525 `typ-525 ~ ~ ~))
30263032++ test-types-union-import
3027− (weld (weld (check ~.types-union-import src-525 `tok-525 `tre-525) (check-module-types ~.types-union-import ~[%tests %golden ~.types-union-import %source %jibb] src-525 `typ-525 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-525-1]])) (check-module-trees ~.types-union-import `mtre-525 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-525-1]]))
3033+ (weld (weld (check ~.types-union-import src-526 `tok-526 `tre-526) (check-module-types ~.types-union-import ~[%tests %golden ~.types-union-import %source %jibb] src-526 `typ-526 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-526-1]])) (check-module-trees ~.types-union-import `mtre-526 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-526-1]]))
30283034++ test-types-union-local-pending
3029− (weld (check ~.types-union-local-pending src-526 `tok-526 `tre-526) (check-types ~.types-union-local-pending ~[%tests %golden ~.types-union-local-pending %source %jibb] src-526 `typ-526))
3035+ (weld (check ~.types-union-local-pending src-527 `tok-527 `tre-527) (check-types ~.types-union-local-pending ~[%tests %golden ~.types-union-local-pending %source %jibb] src-527 `typ-527))
30303036++ test-types-union-overlap
3031− (weld (check ~.types-union-overlap src-527 `tok-527 `tre-527) (check-types ~.types-union-overlap ~[%tests %golden ~.types-union-overlap %source %jibb] src-527 `typ-527))
3037+ (weld (check ~.types-union-overlap src-528 `tok-528 `tre-528) (check-types ~.types-union-overlap ~[%tests %golden ~.types-union-overlap %source %jibb] src-528 `typ-528))
30323038++ test-types-union-overlap-nested
3033− (weld (check ~.types-union-overlap-nested src-528 `tok-528 `tre-528) (check-types ~.types-union-overlap-nested ~[%tests %golden ~.types-union-overlap-nested %source %jibb] src-528 `typ-528))
3039+ (weld (check ~.types-union-overlap-nested src-529 `tok-529 `tre-529) (check-types ~.types-union-overlap-nested ~[%tests %golden ~.types-union-overlap-nested %source %jibb] src-529 `typ-529))
30343040++ test-types-union-pattern-result-context
3035− (weld (check ~.types-union-pattern-result-context src-529 `tok-529 `tre-529) (check-module-types ~.types-union-pattern-result-context ~[%tests %golden ~.types-union-pattern-result-context %source %jibb] src-529 `typ-529 ~ ~ ~))
3041+ (weld (check ~.types-union-pattern-result-context src-530 `tok-530 `tre-530) (check-module-types ~.types-union-pattern-result-context ~[%tests %golden ~.types-union-pattern-result-context %source %jibb] src-530 `typ-530 ~ ~ ~))
30363042++ test-types-union-pattern-result-controls
3037− (weld (check ~.types-union-pattern-result-controls src-530 `tok-530 `tre-530) (check-module-types ~.types-union-pattern-result-controls ~[%tests %golden ~.types-union-pattern-result-controls %source %jibb] src-530 `typ-530 ~ ~ ~))
3043+ (weld (check ~.types-union-pattern-result-controls src-531 `tok-531 `tre-531) (check-module-types ~.types-union-pattern-result-controls ~[%tests %golden ~.types-union-pattern-result-controls %source %jibb] src-531 `typ-531 ~ ~ ~))
30383044++ test-types-union-patterns
3039− (weld (check ~.types-union-patterns src-531 `tok-531 `tre-531) (check-module-types ~.types-union-patterns ~[%tests %golden ~.types-union-patterns %source %jibb] src-531 `typ-531 ~ ~ ~))
3045+ (weld (check ~.types-union-patterns src-532 `tok-532 `tre-532) (check-module-types ~.types-union-patterns ~[%tests %golden ~.types-union-patterns %source %jibb] src-532 `typ-532 ~ ~ ~))
30403046++ test-types-union-patterns-generic
3041− (weld (check ~.types-union-patterns-generic src-532 `tok-532 `tre-532) (check-module-types ~.types-union-patterns-generic ~[%tests %golden ~.types-union-patterns-generic %source %jibb] src-532 `typ-532 ~ ~ ~))
3047+ (weld (check ~.types-union-patterns-generic src-533 `tok-533 `tre-533) (check-module-types ~.types-union-patterns-generic ~[%tests %golden ~.types-union-patterns-generic %source %jibb] src-533 `typ-533 ~ ~ ~))
30423048++ test-types-union-patterns-import
3043− (weld (weld (check ~.types-union-patterns-import src-533 `tok-533 `tre-533) (check-module-types ~.types-union-patterns-import ~[%tests %golden ~.types-union-patterns-import %source %jibb] src-533 `typ-533 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-533-1]])) (check-module-trees ~.types-union-patterns-import `mtre-533 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-533-1]]))
3049+ (weld (weld (check ~.types-union-patterns-import src-534 `tok-534 `tre-534) (check-module-types ~.types-union-patterns-import ~[%tests %golden ~.types-union-patterns-import %source %jibb] src-534 `typ-534 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-534-1]])) (check-module-trees ~.types-union-patterns-import `mtre-534 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-534-1]]))
30443050++ test-types-union-phantom-generic
3045− (weld (check ~.types-union-phantom-generic src-534 `tok-534 `tre-534) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-534 `typ-534))
3051+ (weld (check ~.types-union-phantom-generic src-535 `tok-535 `tre-535) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-535 `typ-535))
30463052++ test-types-union-print-cross-namespace
3047− (weld (weld (check ~.types-union-print-cross-namespace src-535 `tok-535 `tre-535) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-535 `typ-535 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-535-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-535 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-535-1]]))
3053+ (weld (weld (check ~.types-union-print-cross-namespace src-536 `tok-536 `tre-536) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-536 `typ-536 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-536-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-536 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-536-1]]))
30483054++ test-types-union-print-distinct
3049− (weld (weld (check ~.types-union-print-distinct src-536 `tok-536 `tre-536) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-536 `typ-536 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-536-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-536-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-536-3]])) (check-module-trees ~.types-union-print-distinct `mtre-536 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-536-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-536-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-536-3]]))
3055+ (weld (weld (check ~.types-union-print-distinct src-537 `tok-537 `tre-537) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-537 `typ-537 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-537-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-537-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-537-3]])) (check-module-trees ~.types-union-print-distinct `mtre-537 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-537-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-537-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-537-3]]))
30503056++ test-types-union-print-escape
3051− (weld (check ~.types-union-print-escape src-537 `tok-537 `tre-537) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-537 `typ-537))
3057+ (weld (check ~.types-union-print-escape src-538 `tok-538 `tre-538) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-538 `typ-538))
30523058++ test-types-union-print-local
3053− (weld (check ~.types-union-print-local src-538 `tok-538 `tre-538) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-538 `typ-538))
3059+ (weld (check ~.types-union-print-local src-539 `tok-539 `tre-539) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-539 `typ-539))
30543060++ test-types-union-print-nested
3055− (weld (check ~.types-union-print-nested src-539 `tok-539 `tre-539) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-539 `typ-539))
3061+ (weld (check ~.types-union-print-nested src-540 `tok-540 `tre-540) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-540 `typ-540))
30563062++ test-types-union-print-same-origin
3057− (weld (weld (check ~.types-union-print-same-origin src-540 `tok-540 `tre-540) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-540 `typ-540 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-540-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-540 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-540-1]]))
3063+ (weld (weld (check ~.types-union-print-same-origin src-541 `tok-541 `tre-541) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-541 `typ-541 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-541-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-541 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-541-1]]))
30583064++ test-types-union-print-transitive
3059− (weld (weld (check ~.types-union-print-transitive src-541 `tok-541 `tre-541) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-541 `typ-541 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-541-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-541-2]])) (check-module-trees ~.types-union-print-transitive `mtre-541 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-541-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-541-2]]))
3065+ (weld (weld (check ~.types-union-print-transitive src-542 `tok-542 `tre-542) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-542 `typ-542 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-542-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-542-2]])) (check-module-trees ~.types-union-print-transitive `mtre-542 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-542-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-542-2]]))
30603066++ test-types-union-singleton
3061− (weld (check ~.types-union-singleton src-542 `tok-542 `tre-542) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-542 `typ-542))
3067+ (weld (check ~.types-union-singleton src-543 `tok-543 `tre-543) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-543 `typ-543))
30623068++ test-types-union-tag-atoms
3063− (weld (check ~.types-union-tag-atoms src-543 `tok-543 `tre-543) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-543 `typ-543))
3069+ (weld (check ~.types-union-tag-atoms src-544 `tok-544 `tre-544) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-544 `typ-544))
30643070++ test-types-union-tags
3065− (weld (check ~.types-union-tags src-544 `tok-544 `tre-544) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-544 `typ-544))
3071+ (weld (check ~.types-union-tags src-545 `tok-545 `tre-545) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-545 `typ-545))
30663072++ test-types-union-unresolved
3067− (weld (check ~.types-union-unresolved src-545 `tok-545 `tre-545) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-545 `typ-545))
3073+ (weld (check ~.types-union-unresolved src-546 `tok-546 `tre-546) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-546 `typ-546))
30683074++ test-types-union-unresolved-flow
3069− (weld (check ~.types-union-unresolved-flow src-546 `tok-546 `tre-546) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-546 `typ-546))
3075+ (weld (check ~.types-union-unresolved-flow src-547 `tok-547 `tre-547) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-547 `typ-547))
30703076++ test-types-unit-construction
3071− (weld (check ~.types-unit-construction src-547 `tok-547 `tre-547) (check-module-types ~.types-unit-construction ~[%tests %golden ~.types-unit-construction %source %jibb] src-547 `typ-547 ~ ~ ~))
3077+ (weld (check ~.types-unit-construction src-548 `tok-548 `tre-548) (check-module-types ~.types-unit-construction ~[%tests %golden ~.types-unit-construction %source %jibb] src-548 `typ-548 ~ ~ ~))
30723078++ test-types-unit-context
3073− (weld (check ~.types-unit-context src-548 `tok-548 `tre-548) (check-module-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-548 `typ-548 ~ ~ ~))
3079+ (weld (check ~.types-unit-context src-549 `tok-549 `tre-549) (check-module-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-549 `typ-549 ~ ~ ~))
30743080++ test-types-unit-patterns
3075− (weld (check ~.types-unit-patterns src-549 `tok-549 `tre-549) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-549 `typ-549))
3081+ (weld (check ~.types-unit-patterns src-550 `tok-550 `tre-550) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-550 `typ-550))
30763082::
30773083:: +check: run golden:jibb on a case and compare both outputs
30783084::