on master help sign in
Infer contextual unit payloads
commit264a436db8dfaf599fe1f7dece79a31d27e6457d authoriko <mail@iko.soy> dateSat 31 Oct 2026, 00:32 (9 hours ago) parent0bc5113
12 files changed+871−633
docs/compiler.md+1−1 docs/status.md+4−3 jibb-dev/lib/jibb.hoon+35−8 tests/golden/types-unit-construction/about.txt+1−1 tests/golden/types-unit-construction/types.txt+16−4 tests/golden/types-unit-context/about.txt+2−2 tests/golden/types-unit-context/modules.txt+1 tests/golden/types-unit-context/source.jibb+44−68 tests/golden/types-unit-context/tokens.txt+458−343 tests/golden/types-unit-context/tree.txt+218−180 tests/golden/types-unit-context/types.txt+90−22 tests/lib/jibb.hoon+1−1
docs/compiler.md+1−1
@@ -68,7 +68,7 @@ Multi-argument calls form one right-nested sample: `f a b c` supplies `[a [b c]]
6868
6969A list literal can be inferred when a cast or known gate sample supplies a list type and the supplied prelude has the validated standard list definition. Empty, nonempty and nested literals work, including contextual union tags in elements; mismatched elements report the item and expected type. Imported Hoon lists share this representation. Under the same known context, `~` and zero-valued term literals fit an empty list, and a two-item unfaced cell `[head tail]` is a cons; cons cells and list literals can be nested. Mismatched heads or tails report both sites. A known list result also supplies context through complete loobean, unit-shaped and list-shaped branches, including recursive and nested branches. A known gate sample also supplies context to corresponding positions of a single tuple or record argument, including nested cells; a zero literal can therefore fit a list position. A bound zero constant still remains unsupported rather than a definite mismatch, and an unknown callee does not supply context. Faced or longer cells, uncontextualized construction, and a missing or altered prelude list remain unsupported. For a known standard list with a supported element type, it also infers a complete two-arm branch using `~` and `[item rest]`, in either order. The binders have the element and list types and cannot shadow or duplicate names. Unknown subjects, unsupported element types, other patterns and incomplete arms remain unsupported.
7070
71−A backtick constructs a unit when the supplied prelude has the validated standard `unit` template. Its payload is inferred normally, retaining pending literals and generic variables; nested units work and the prelude’s `some` becomes available. Unit payloads that require contextual matching, unrelated union identities, and missing or altered prelude templates remain unsupported.
71+A backtick constructs a unit when the supplied prelude has the validated standard `unit` template. Its payload is inferred normally, retaining pending literals and generic variables; nested units work and the prelude’s `some` becomes available. A known unit in a cast, call, list item or record field supplies its payload context, including nested units and lists; definite mismatches identify the payload and context. Unrelated union identities, some variable-dependent fits, and missing or altered prelude templates remain unsupported.
7272
7373A 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.
7474
docs/status.md+4−3
@@ -19,7 +19,7 @@ On 2026-10-30, @iko decided that Jibb drops `$?`, so a `+$` takes a union's case
1919
2020## Milestone 2: in progress
2121
22−The repository spec records the subsequent type-system and prelude decisions; those changes also need synchronization to the Claude document. An initial inference fragment and a standalone Hoon type reader are being tested. The fragment explicitly reports that it does not check a module; partial bridges pass selected Hoon atoms, term singletons, nested faced or unfaced cells, supported disjoint unions and opaque standard collections from `/sur` molds and marks into inference. Collections retain their names and supported arguments for printing and unification; nested supported union arguments are retained too. The bridge trusts unchanged results from the source-aware reader; a materialized type graph alone cannot reveal cases Hoon already collapsed. The source-validated standard prelude `list` mold shares this representation with imported lists; other Jibb-written collection molds and 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. 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. Local mutual groups, polymorphic recursion, value cycles, 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. 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, some complex two-arm subjects and contextual union-pattern branches remain unsupported. The Grammar’s `step` block infers in this fragment, but its module is not yet checked. 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. Backtick unit construction uses the validated standard prelude unit template, infers its payload without losing pending constraints, and makes the prelude’s `some` available. Context-dependent payload matching 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, 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. 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. Local mutual groups, polymorphic recursion, value cycles, 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. 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, some complex two-arm subjects and contextual union-pattern branches remain unsupported. The Grammar’s `step` block infers in this fragment, but its module is not yet checked. 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. Backtick unit construction uses the validated standard prelude unit template, infers its payload without losing pending constraints, and makes the prelude’s `some` available. 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
@@ -40,7 +40,7 @@ What the plan asks for, and where it is:
4040Besides the plan's list:
4141
4242- 535 golden cases: 319 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 535-case corpus passed under `urbit eval` in 66.0 s. The fake ship passed all 541 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 33.4 s for sync and 40.8 s for tests. The importer golden compares 149 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.
43+- The 535-case corpus passed under `urbit eval` in 62.4 s. The fake ship passed all 541 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 32.8 s for sync and 39.4 s for tests. The importer golden compares 149 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).
@@ -97,7 +97,8 @@ Besides the plan's list:
9797| 9f1517e | 2026-10-30 | Infer whole-case union patterns and prelude `turn` |
9898| 9dd35c8 | 2026-10-31 | Match finite boolean refinements of union cases |
9999| 54852d4 | 2026-10-31 | Contextualize tuple calls and infer known record changes |
100−| This change | 2026-10-31 | Contextualize record initializers and infer unit construction |
100+| 0bc5113 | 2026-10-31 | Contextualize record initializers and infer unit construction |
101+| This change | 2026-10-31 | Contextualize unit payloads in casts, calls and nested values |
101102
102103## Checking it
103104
jibb-dev/lib/jibb.hoon+35−8
@@ -5066,6 +5066,10 @@
50665066 =/ unified=(unit isub) (itype-unify-args args.actual args.expected sub)
50675067 ?^ unified [%ok u.unified next]
50685068 [%unknown ~]
5069+ :: A concrete union value in a tuple may acquire the expected field's
5070+ :: face. A variable-bound union still needs face propagation support.
5071+ ?: &(!uncertain ?=(%union -.actual) ?=(%face -.expected))
5072+ $(expected body.expected)
50695073 ?: ?=(%union -.actual) [%unknown ~]
50705074 ?: &(?=(%union -.expected) |(?=(%avar -.actual) ?=(%nvar -.actual))) [%unknown ~]
50715075 ?: &(?=(%union -.expected) !?=(%var -.actual))
@@ -6521,14 +6525,7 @@
65216525 ^- iresult
65226526 ?~ items [%& expected state]
65236527 =/ target=itype (itype-walk expected sub.state)
6524− =/ value=iresult
6525− ?: &(?=(%union -.target) (context-union-branch i.items))
6526− (infer-union-context i.items target env state context)
6527− ?: &(?=(%collection -.target) =(%list name.target) (context-union-branch i.items))
6528− (infer-union-context i.items target env state context)
6529− ?: &(?=(%collection -.target) =(%list name.target) (context-list-expression i.items))
6530− (infer-list-context i.items target env state context)
6531− (infer-fragment i.items env state)
6528+ =/ value=iresult (infer-call-context-arg i.items target env state context)
65326529 ?: ?=(%| -.value) value
65336530 =/ fit=ifit (itype-fit typ.p.value target sub.state.p.value next.state.p.value)
65346531 ?: ?=(%unknown -.fit) [%| ["list item constraint is not supported by partial inference" ~]]
@@ -7177,12 +7174,42 @@
71777174:: Context can help a call argument or cast value while the final fit
71787175:: checks the complete right-nested type, including any written faces.
71797176::
7177+:: Context can resolve the payload of a canonical prelude unit, but an
7178+:: unrelated union with a similar noun shape is not the same mold.
7179+++ infer-unit-context
7180+ |= [e=expr expected=itype env=ienv state=istate context=span]
7181+ ^- iresult
7182+ ?> ?=(%unit -.e)
7183+ ?> ?=(%union -.expected)
7184+ ?~ prelude.state (infer-fragment e env state)
7185+ =/ standard=(unit ischeme) (find-jibb-mold %unit u.prelude.state)
7186+ ?~ standard (infer-fragment e env state)
7187+ ?. (standard-unit-template u.standard at.u.prelude.state) (infer-fragment e env state)
7188+ ?. =(origin.expected `[at.u.prelude.state %unit]) (infer-fragment e env state)
7189+ ?~ args.expected (infer-fragment e env state)
7190+ ?^ t.args.expected (infer-fragment e env state)
7191+ =/ payload=itype i.args.expected
7192+ =/ canonical=(unit itype) (template-apply u.standard ~[payload])
7193+ ?~ canonical (infer-fragment e env state)
7194+ ?> ?=(%union -.u.canonical)
7195+ ?. =((itype-normalize expected(label ~) sub.state) (itype-normalize u.canonical(label ~) sub.state))
7196+ (infer-fragment e env state)
7197+ =/ value=iresult (infer-call-context-arg val.e payload env state context)
7198+ ?: ?=(%| -.value) value
7199+ =/ fit=ifit (itype-fit typ.p.value payload sub.state.p.value next.state.p.value)
7200+ ?: ?=(%unknown -.fit) [%| ["unit payload constraint is not supported by partial inference" ~]]
7201+ ?: ?=(%bad -.fit)
7202+ [%| ["unit payload does not fit its expected type" ~[[context (site-type-note "expected unit payload" payload sub.state.p.value)] [(span-of val.e) (site-type-note "payload" typ.p.value sub.state.p.value)]]]]
7203+ [%& expected state.p.value(sub sub.fit, next next.fit)]
7204+::
71807205++ infer-call-context-arg
71817206 |= [e=expr expected=itype env=ienv state=istate context=span]
71827207 ^- iresult
71837208 =/ target=itype (itype-walk expected sub.state)
71847209 |-
71857210 ?: ?=(%face -.target) $(target (itype-walk body.target sub.state))
7211+ ?: &(?=(%union -.target) ?=(%unit -.e))
7212+ (infer-unit-context e target env state context)
71867213 ?: &(?=(%union -.target) (context-union-branch e))
71877214 (infer-union-context e target env state context)
71887215 ?: &(?=(%collection -.target) =(%list name.target) (context-union-branch e))
tests/golden/types-unit-construction/about.txt+1−1
@@ -1,4 +1,4 @@
11source: Grammar, Literals: a backtick constructs a `(unit A)`; Tag resolution: tags and `~` take their type from context.
2−tests: Unit construction uses the validated prelude shape, preserves generic and nested payload types, and makes prelude some available at independent types. Unresolved payloads and discarded literals stay pending. Payload constraints and unrelated user-defined unions fail closed where their compatibility is not yet supported.
2+tests: Unit construction uses the validated prelude shape, preserves generic and nested payload types, and makes prelude some available at independent types. Unresolved payloads and discarded literals stay pending. Known payload contexts resolve tags and report definite mismatches; unrelated user-defined unions and forcing explicit capitals remain unsupported.
33expect: parses
44expect-types: a partial inference report
tests/golden/types-unit-construction/types.txt+16−4
@@ -8,13 +8,25 @@ partial inference; module not checked
88++ nested: (unit (unit @t))
99++ same-first: (unit @t)
1010++ same-second: (unit @p)
11−++ ctx: cast constraint is not supported by partial inference
12−++ bad-tag: cast constraint is not supported by partial inference
11+++ ctx: (unit msg)
12+++ bad-tag: unit payload does not fit its expected type
13+/tests/golden/types-unit-construction/source.jibb:17:15: expected unit payload
14+++ bad-tag ^- (unit msg) `%bad
15+ ^
16+/tests/golden/types-unit-construction/source.jibb:17:27: payload
17+++ bad-tag ^- (unit msg) `%bad
18+ ^
1319++ missing-tag: tag needs context in partial inference
1420++ discarded-tag: tag needs context in partial inference
1521++ discarded-null: `~` needs context in partial inference
16−++ mismatch: cast constraint is not supported by partial inference
22+++ mismatch: unit payload does not fit its expected type
23+/tests/golden/types-unit-construction/source.jibb:25:16: expected unit payload has type @p
24+++ mismatch ^- (unit @p) `"hi"
25+ ^
26+/tests/golden/types-unit-construction/source.jibb:25:27: payload has type @t
27+++ mismatch ^- (unit @p) `"hi"
28+ ^
1729++ other-unit: cast constraint is not supported by partial inference
1830++ force: explicit capital constraints are not supported by partial inference
1931++ null-payload: `~` needs context in partial inference
20−++ tag-payload: cast constraint is not supported by partial inference
32+++ tag-payload: (unit @tas)
tests/golden/types-unit-context/about.txt+2−2
@@ -1,4 +1,4 @@
1−source: Grammar, Tag resolution: "A tag literal or `~` gets a fresh type variable and a pending constraint"; Patterns: "A name in a pattern always binds anew".
2−tests: A cast or known sample supplies union context to both unit branch arms, including nested unit and loobean branches; bad cases, unknown subjects, shadowing and unrelated pending tags or nulls fail closed.
1+source: Grammar, Literals: a backtick constructs a `(unit A)`; Tag resolution: tags and `~` take their type from context; Literals by context: cells and lists take their type from context.
2+tests: Known standard unit payloads supply context through casts, calls, nested units, lists and record fields. Invalid tags, auras and faces report errors; different union origins and concrete forcing of written capitals fail closed. Shared capitals and unrelated pending literals are preserved.
33expect: parses
44expect-types: a partial inference report
tests/golden/types-unit-context/modules.txtnew file+1
@@ -0,0 +1 @@
1+# Use the prepared prelude.
tests/golden/types-unit-context/source.jibb+44−68
@@ -1,70 +1,46 @@
1−+$ maybe
2− ~
3− [~ value=@t]
41+$ msg
5− %add
6− [%note text=@t]
7−++ cast |= x=maybe
8− ^- msg
9− ?- x
10− ~ %add
11− [~ text] [%note text]
12−++ reversed |= x=maybe
13− ^- msg
14− ?- x
15− [~ text] [%note text]
16− ~ %add
17−++ consume |= x=msg "ok"
18−++ call |= x=maybe
19− (consume
20− ?- x
21− ~ %add
22− [~ text] [%note text]
23−++ nested |= x=maybe
24− ^- msg
25− ?- x
26− ~
27− ?- %.y
28− %.y %add
29− %.n [%note "hi"]
30− [~ text] [%note text]
31−++ bad-empty |= x=maybe
32− ^- msg
33− ?- x
34− ~ %missing
35− [~ text] [%note text]
36−++ bad-present |= x=maybe
37− ^- msg
38− ?- x
39− ~ %add
40− [~ text] %missing
41−++ unknown |= x
42− ^- msg
43− ?- x
44− ~ %add
45− [~ text] [%note text]
46−++ shadow |= x=maybe
47− ^- msg
48− ?- x
49− ~ %add
50− [~ x] [%note x]
51−++ pending |= x=maybe
52− ~& %unknown
53− ^- msg
54− ?- x
55− ~ %add
56− [~ text] [%note text]
57−++ nested-unit |= x=maybe
58− ^- msg
59− ?- x
60− ~
61− ?- x
62− ~ %add
63− [~ inner] [%note inner]
64− [~ text] [%note text]
65−++ pending-null |= x=maybe
2+ %go
3+ %stay
4++$ mimic |$ [A]
5+ ~
6+ [~ u=A]
7++$ record [u=(unit msg) xs=(list (unit @t))]
8+++ valid ^- (unit msg) `%go
9+++ invalid ^- (unit msg) `%bad
10+++ str ^- (unit @t) `"hi"
11+++ wrong ^- (unit @t) `~zod
12+++ nest ^- (unit (unit @t)) ``"hi"
13+++ nested-bad ^- (unit (unit @t)) ``~zod
14+++ lis ^- (unit (list @t)) `~["hi"]
15+++ list-bad ^- (unit (list @t)) `~[~zod]
16+++ accept |= x=(unit msg) x
17+++ call (accept `%stay)
18+++ bad-call (accept `%bad)
19+++ field ^- record [`%go ~[`"hi"]]
20+++ field-bad ^- record [`%bad ~[`"hi"]]
21+++ mimic-mismatch ^- (mimic @t) `"hi"
22+++ without-context `%go
23+++ pending
24+ ~& %other
25+ ^- (unit msg) `%go
26+++ pending-null
6627 ~& ~
67− ^- msg
68− ?- x
69− ~ %add
70− [~ text] [%note text]
28+ ^- (unit @t) `"hi"
29+++ preserve |= x=A ^- (unit A) `x
30+++ force |= x=A ^- (unit A) `"hi"
31++$ alt
32+ %go
33+ %stay
34+++ field-wrong-payload ^- record [`%go ~[`~zod]]
35+++ wrong-name ^- record [wrong=`%go xs=~[`"hi"]]
36+++ wrong-union |= x=alt ^- record [`x ~[`"hi"]]
37+++ no-field-context |= x=A ^- [a=A] [wrong=x]
38+++ known-left |= x=msg ^- [a=msg] [a=x]
39+++ mismatch-left |= x=msg ^- [a=alt] [a=x]
40+++ contextual |= x=A ^- [a=A b=(unit A)] [a=x b=`x]
41+++ contextual-bad |= x=A ^- [a=A b=(unit A)] [a=x b=`"hi"]
42+++ nested-units ^- (list (unit msg)) ~[`%go `%stay]
43+++ nested-units-bad ^- (list (unit msg)) ~[`%go `%oops]
44+++ case-discarded
45+ ~& %pending
46+ ^- record [`%go ~[`"hi"]]
tests/golden/types-unit-context/tokens.txt+458−343
@@ -1,374 +1,489 @@
111:1 glyph +$
2−1:4 name maybe
2+1:4 name msg
332:3 INDENT
4−2:3 lit ~
4+2:3 lit %go
553:3 NEWLINE
6−3:3 glyph [
7−3:4 tight lit ~
8−3:6 name value
9−3:11 tight glyph =
10−3:12 tight aura @t
11−3:14 tight glyph ]
6+3:3 lit %stay
1274:1 DEDENT
1384:1 NEWLINE
1494:1 glyph +$
15−4:4 name msg
10+4:4 name mimic
11+4:10 glyph |$
12+4:13 glyph [
13+4:14 tight tvar A
14+4:15 tight glyph ]
16155:3 INDENT
17−5:3 lit %add
16+5:3 lit ~
18176:3 NEWLINE
19186:3 glyph [
20−6:4 tight lit %note
21−6:10 name text
22−6:14 tight glyph =
23−6:15 tight aura @t
24−6:17 tight glyph ]
19+6:4 tight lit ~
20+6:6 name u
21+6:7 tight glyph =
22+6:8 tight tvar A
23+6:9 tight glyph ]
25247:1 DEDENT
26257:1 NEWLINE
27−7:1 glyph ++
28−7:4 name cast
29−7:9 glyph |=
30−7:12 name x
26+7:1 glyph +$
27+7:4 name record
28+7:11 glyph [
29+7:12 tight name u
31307:13 tight glyph =
32−7:14 tight name maybe
33−8:3 INDENT
34−8:3 glyph ^-
35−8:6 name msg
36−9:5 INDENT
37−9:5 glyph ?-
38−9:8 name x
39−10:7 INDENT
40−10:7 lit ~
41−10:9 lit %add
42−11:7 NEWLINE
43−11:7 glyph [
44−11:8 tight lit ~
45−11:10 name text
46−11:14 tight glyph ]
47−11:16 glyph [
48−11:17 tight lit %note
49−11:23 name text
50−11:27 tight glyph ]
51−12:1 DEDENT
52−12:1 DEDENT
53−12:1 DEDENT
31+7:14 tight glyph (
32+7:15 tight name unit
33+7:20 name msg
34+7:23 tight glyph )
35+7:25 name xs
36+7:27 tight glyph =
37+7:28 tight glyph (
38+7:29 tight name list
39+7:34 glyph (
40+7:35 tight name unit
41+7:40 aura @t
42+7:42 tight glyph )
43+7:43 tight glyph )
44+7:44 tight glyph ]
45+8:1 NEWLINE
46+8:1 glyph ++
47+8:4 name valid
48+8:10 glyph ^-
49+8:13 glyph (
50+8:14 tight name unit
51+8:19 name msg
52+8:22 tight glyph )
53+8:24 glyph `
54+8:25 tight lit %go
55+9:1 NEWLINE
56+9:1 glyph ++
57+9:4 name invalid
58+9:12 glyph ^-
59+9:15 glyph (
60+9:16 tight name unit
61+9:21 name msg
62+9:24 tight glyph )
63+9:26 glyph `
64+9:27 tight lit %bad
65+10:1 NEWLINE
66+10:1 glyph ++
67+10:4 name str
68+10:8 glyph ^-
69+10:11 glyph (
70+10:12 tight name unit
71+10:17 aura @t
72+10:19 tight glyph )
73+10:21 glyph `
74+10:22 tight str "hi"
75+11:1 NEWLINE
76+11:1 glyph ++
77+11:4 name wrong
78+11:10 glyph ^-
79+11:13 glyph (
80+11:14 tight name unit
81+11:19 aura @t
82+11:21 tight glyph )
83+11:23 glyph `
84+11:24 tight lit ~zod
548512:1 NEWLINE
558612:1 glyph ++
56−12:4 name reversed
57−12:13 glyph |=
58−12:16 name x
59−12:17 tight glyph =
60−12:18 tight name maybe
61−13:3 INDENT
62−13:3 glyph ^-
63−13:6 name msg
64−14:5 INDENT
65−14:5 glyph ?-
66−14:8 name x
67−15:7 INDENT
68−15:7 glyph [
69−15:8 tight lit ~
70−15:10 name text
71−15:14 tight glyph ]
72−15:16 glyph [
73−15:17 tight lit %note
74−15:23 name text
75−15:27 tight glyph ]
76−16:7 NEWLINE
77−16:7 lit ~
78−16:9 lit %add
79−17:1 DEDENT
80−17:1 DEDENT
81−17:1 DEDENT
87+12:4 name nest
88+12:9 glyph ^-
89+12:12 glyph (
90+12:13 tight name unit
91+12:18 glyph (
92+12:19 tight name unit
93+12:24 aura @t
94+12:26 tight glyph )
95+12:27 tight glyph )
96+12:29 glyph `
97+12:30 tight glyph `
98+12:31 tight str "hi"
99+13:1 NEWLINE
100+13:1 glyph ++
101+13:4 name nested-bad
102+13:15 glyph ^-
103+13:18 glyph (
104+13:19 tight name unit
105+13:24 glyph (
106+13:25 tight name unit
107+13:30 aura @t
108+13:32 tight glyph )
109+13:33 tight glyph )
110+13:35 glyph `
111+13:36 tight glyph `
112+13:37 tight lit ~zod
113+14:1 NEWLINE
114+14:1 glyph ++
115+14:4 name lis
116+14:8 glyph ^-
117+14:11 glyph (
118+14:12 tight name unit
119+14:17 glyph (
120+14:18 tight name list
121+14:23 aura @t
122+14:25 tight glyph )
123+14:26 tight glyph )
124+14:28 glyph `
125+14:29 tight glyph ~[
126+14:31 tight str "hi"
127+14:35 tight glyph ]
128+15:1 NEWLINE
129+15:1 glyph ++
130+15:4 name list-bad
131+15:13 glyph ^-
132+15:16 glyph (
133+15:17 tight name unit
134+15:22 glyph (
135+15:23 tight name list
136+15:28 aura @t
137+15:30 tight glyph )
138+15:31 tight glyph )
139+15:33 glyph `
140+15:34 tight glyph ~[
141+15:36 tight lit ~zod
142+15:40 tight glyph ]
143+16:1 NEWLINE
144+16:1 glyph ++
145+16:4 name accept
146+16:11 glyph |=
147+16:14 name x
148+16:15 tight glyph =
149+16:16 tight glyph (
150+16:17 tight name unit
151+16:22 name msg
152+16:25 tight glyph )
153+16:27 name x
8215417:1 NEWLINE
8315517:1 glyph ++
84−17:4 name consume
85−17:12 glyph |=
86−17:15 name x
87−17:16 tight glyph =
88−17:17 tight name msg
89−17:21 str "ok"
156+17:4 name call
157+17:9 glyph (
158+17:10 tight name accept
159+17:17 glyph `
160+17:18 tight lit %stay
161+17:23 tight glyph )
9016218:1 NEWLINE
9116318:1 glyph ++
92−18:4 name call
93−18:9 glyph |=
94−18:12 name x
95−18:13 tight glyph =
96−18:14 tight name maybe
97−19:3 INDENT
98−19:3 glyph (
99−19:4 tight name consume
100−20:5 INDENT
101−20:5 glyph ?-
102−20:8 name x
103−21:7 INDENT
104−21:7 lit ~
105−21:9 lit %add
106−22:7 NEWLINE
107−22:7 glyph [
108−22:8 tight lit ~
109−22:10 name text
110−22:14 tight glyph ]
111−22:16 glyph [
112−22:17 tight lit %note
113−22:23 name text
114−22:27 tight glyph ]
115−23:1 DEDENT
116−23:1 DEDENT
117−23:1 DEDENT
164+18:4 name bad-call
165+18:13 glyph (
166+18:14 tight name accept
167+18:21 glyph `
168+18:22 tight lit %bad
169+18:26 tight glyph )
170+19:1 NEWLINE
171+19:1 glyph ++
172+19:4 name field
173+19:10 glyph ^-
174+19:13 name record
175+19:20 glyph [
176+19:21 tight glyph `
177+19:22 tight lit %go
178+19:26 glyph ~[
179+19:28 tight glyph `
180+19:29 tight str "hi"
181+19:33 tight glyph ]
182+19:34 tight glyph ]
183+20:1 NEWLINE
184+20:1 glyph ++
185+20:4 name field-bad
186+20:14 glyph ^-
187+20:17 name record
188+20:24 glyph [
189+20:25 tight glyph `
190+20:26 tight lit %bad
191+20:31 glyph ~[
192+20:33 tight glyph `
193+20:34 tight str "hi"
194+20:38 tight glyph ]
195+20:39 tight glyph ]
196+21:1 NEWLINE
197+21:1 glyph ++
198+21:4 name mimic-mismatch
199+21:19 glyph ^-
200+21:22 glyph (
201+21:23 tight name mimic
202+21:29 aura @t
203+21:31 tight glyph )
204+21:33 glyph `
205+21:34 tight str "hi"
206+22:1 NEWLINE
207+22:1 glyph ++
208+22:4 name without-context
209+22:20 glyph `
210+22:21 tight lit %go
11821123:1 NEWLINE
11921223:1 glyph ++
120−23:4 name nested
121−23:11 glyph |=
122−23:14 name x
123−23:15 tight glyph =
124−23:16 tight name maybe
213+23:4 name pending
12521424:3 INDENT
126−24:3 glyph ^-
127−24:6 name msg
215+24:3 glyph ~&
216+24:6 lit %other
12821725:5 INDENT
129−25:5 glyph ?-
130−25:8 name x
131−26:7 INDENT
132−26:7 lit ~
133−27:9 INDENT
134−27:9 glyph ?-
135−27:12 lit %.y
136−28:11 INDENT
137−28:11 lit %.y
138−28:15 lit %add
139−29:11 NEWLINE
140−29:11 lit %.n
141−29:15 glyph [
142−29:16 tight lit %note
143−29:22 str "hi"
144−29:26 tight glyph ]
145−30:7 DEDENT
146−30:7 DEDENT
147−30:7 NEWLINE
148−30:7 glyph [
149−30:8 tight lit ~
150−30:10 name text
151−30:14 tight glyph ]
152−30:16 glyph [
153−30:17 tight lit %note
154−30:23 name text
155−30:27 tight glyph ]
156−31:1 DEDENT
157−31:1 DEDENT
158−31:1 DEDENT
218+25:5 glyph ^-
219+25:8 glyph (
220+25:9 tight name unit
221+25:14 name msg
222+25:17 tight glyph )
223+25:19 glyph `
224+25:20 tight lit %go
225+26:1 DEDENT
226+26:1 DEDENT
227+26:1 NEWLINE
228+26:1 glyph ++
229+26:4 name pending-null
230+27:3 INDENT
231+27:3 glyph ~&
232+27:6 lit ~
233+28:5 INDENT
234+28:5 glyph ^-
235+28:8 glyph (
236+28:9 tight name unit
237+28:14 aura @t
238+28:16 tight glyph )
239+28:18 glyph `
240+28:19 tight str "hi"
241+29:1 DEDENT
242+29:1 DEDENT
243+29:1 NEWLINE
244+29:1 glyph ++
245+29:4 name preserve
246+29:13 glyph |=
247+29:16 name x
248+29:17 tight glyph =
249+29:18 tight tvar A
250+29:20 glyph ^-
251+29:23 glyph (
252+29:24 tight name unit
253+29:29 tvar A
254+29:30 tight glyph )
255+29:32 glyph `
256+29:33 tight name x
257+30:1 NEWLINE
258+30:1 glyph ++
259+30:4 name force
260+30:10 glyph |=
261+30:13 name x
262+30:14 tight glyph =
263+30:15 tight tvar A
264+30:17 glyph ^-
265+30:20 glyph (
266+30:21 tight name unit
267+30:26 tvar A
268+30:27 tight glyph )
269+30:29 glyph `
270+30:30 tight str "hi"
15927131:1 NEWLINE
160−31:1 glyph ++
161−31:4 name bad-empty
162−31:14 glyph |=
163−31:17 name x
164−31:18 tight glyph =
165−31:19 tight name maybe
272+31:1 glyph +$
273+31:4 name alt
16627432:3 INDENT
167−32:3 glyph ^-
168−32:6 name msg
169−33:5 INDENT
170−33:5 glyph ?-
171−33:8 name x
172−34:7 INDENT
173−34:7 lit ~
174−34:9 lit %missing
175−35:7 NEWLINE
176−35:7 glyph [
177−35:8 tight lit ~
178−35:10 name text
179−35:14 tight glyph ]
180−35:16 glyph [
181−35:17 tight lit %note
182−35:23 name text
183−35:27 tight glyph ]
184−36:1 DEDENT
185−36:1 DEDENT
186−36:1 DEDENT
275+32:3 lit %go
276+33:3 NEWLINE
277+33:3 lit %stay
278+34:1 DEDENT
279+34:1 NEWLINE
280+34:1 glyph ++
281+34:4 name field-wrong-payload
282+34:24 glyph ^-
283+34:27 name record
284+34:34 glyph [
285+34:35 tight glyph `
286+34:36 tight lit %go
287+34:40 glyph ~[
288+34:42 tight glyph `
289+34:43 tight lit ~zod
290+34:47 tight glyph ]
291+34:48 tight glyph ]
292+35:1 NEWLINE
293+35:1 glyph ++
294+35:4 name wrong-name
295+35:15 glyph ^-
296+35:18 name record
297+35:25 glyph [
298+35:26 tight name wrong
299+35:31 tight glyph =
300+35:32 tight glyph `
301+35:33 tight lit %go
302+35:37 name xs
303+35:39 tight glyph =
304+35:40 tight glyph ~[
305+35:42 tight glyph `
306+35:43 tight str "hi"
307+35:47 tight glyph ]
308+35:48 tight glyph ]
18730936:1 NEWLINE
18831036:1 glyph ++
189−36:4 name bad-present
311+36:4 name wrong-union
19031236:16 glyph |=
19131336:19 name x
19231436:20 tight glyph =
193−36:21 tight name maybe
194−37:3 INDENT
195−37:3 glyph ^-
196−37:6 name msg
197−38:5 INDENT
198−38:5 glyph ?-
199−38:8 name x
200−39:7 INDENT
201−39:7 lit ~
202−39:9 lit %add
203−40:7 NEWLINE
204−40:7 glyph [
205−40:8 tight lit ~
206−40:10 name text
207−40:14 tight glyph ]
208−40:16 lit %missing
209−41:1 DEDENT
210−41:1 DEDENT
211−41:1 DEDENT
315+36:21 tight name alt
316+36:25 glyph ^-
317+36:28 name record
318+36:35 glyph [
319+36:36 tight glyph `
320+36:37 tight name x
321+36:39 glyph ~[
322+36:41 tight glyph `
323+36:42 tight str "hi"
324+36:46 tight glyph ]
325+36:47 tight glyph ]
326+37:1 NEWLINE
327+37:1 glyph ++
328+37:4 name no-field-context
329+37:21 glyph |=
330+37:24 name x
331+37:25 tight glyph =
332+37:26 tight tvar A
333+37:28 glyph ^-
334+37:31 glyph [
335+37:32 tight name a
336+37:33 tight glyph =
337+37:34 tight tvar A
338+37:35 tight glyph ]
339+37:37 glyph [
340+37:38 tight name wrong
341+37:43 tight glyph =
342+37:44 tight name x
343+37:45 tight glyph ]
344+38:1 NEWLINE
345+38:1 glyph ++
346+38:4 name known-left
347+38:15 glyph |=
348+38:18 name x
349+38:19 tight glyph =
350+38:20 tight name msg
351+38:24 glyph ^-
352+38:27 glyph [
353+38:28 tight name a
354+38:29 tight glyph =
355+38:30 tight name msg
356+38:33 tight glyph ]
357+38:35 glyph [
358+38:36 tight name a
359+38:37 tight glyph =
360+38:38 tight name x
361+38:39 tight glyph ]
362+39:1 NEWLINE
363+39:1 glyph ++
364+39:4 name mismatch-left
365+39:18 glyph |=
366+39:21 name x
367+39:22 tight glyph =
368+39:23 tight name msg
369+39:27 glyph ^-
370+39:30 glyph [
371+39:31 tight name a
372+39:32 tight glyph =
373+39:33 tight name alt
374+39:36 tight glyph ]
375+39:38 glyph [
376+39:39 tight name a
377+39:40 tight glyph =
378+39:41 tight name x
379+39:42 tight glyph ]
380+40:1 NEWLINE
381+40:1 glyph ++
382+40:4 name contextual
383+40:15 glyph |=
384+40:18 name x
385+40:19 tight glyph =
386+40:20 tight tvar A
387+40:22 glyph ^-
388+40:25 glyph [
389+40:26 tight name a
390+40:27 tight glyph =
391+40:28 tight tvar A
392+40:30 name b
393+40:31 tight glyph =
394+40:32 tight glyph (
395+40:33 tight name unit
396+40:38 tvar A
397+40:39 tight glyph )
398+40:40 tight glyph ]
399+40:42 glyph [
400+40:43 tight name a
401+40:44 tight glyph =
402+40:45 tight name x
403+40:47 name b
404+40:48 tight glyph =
405+40:49 tight glyph `
406+40:50 tight name x
407+40:51 tight glyph ]
21240841:1 NEWLINE
21340941:1 glyph ++
214−41:4 name unknown
215−41:12 glyph |=
216−41:15 name x
217−42:3 INDENT
218−42:3 glyph ^-
219−42:6 name msg
220−43:5 INDENT
221−43:5 glyph ?-
222−43:8 name x
223−44:7 INDENT
224−44:7 lit ~
225−44:9 lit %add
226−45:7 NEWLINE
227−45:7 glyph [
228−45:8 tight lit ~
229−45:10 name text
230−45:14 tight glyph ]
231−45:16 glyph [
232−45:17 tight lit %note
233−45:23 name text
234−45:27 tight glyph ]
235−46:1 DEDENT
236−46:1 DEDENT
237−46:1 DEDENT
238−46:1 NEWLINE
239−46:1 glyph ++
240−46:4 name shadow
241−46:11 glyph |=
242−46:14 name x
243−46:15 tight glyph =
244−46:16 tight name maybe
245−47:3 INDENT
246−47:3 glyph ^-
247−47:6 name msg
248−48:5 INDENT
249−48:5 glyph ?-
250−48:8 name x
251−49:7 INDENT
252−49:7 lit ~
253−49:9 lit %add
254−50:7 NEWLINE
255−50:7 glyph [
256−50:8 tight lit ~
257−50:10 name x
258−50:11 tight glyph ]
259−50:13 glyph [
260−50:14 tight lit %note
261−50:20 name x
262−50:21 tight glyph ]
263−51:1 DEDENT
264−51:1 DEDENT
265−51:1 DEDENT
266−51:1 NEWLINE
267−51:1 glyph ++
268−51:4 name pending
269−51:12 glyph |=
270−51:15 name x
271−51:16 tight glyph =
272−51:17 tight name maybe
273−52:3 INDENT
274−52:3 glyph ~&
275−52:6 lit %unknown
276−53:5 INDENT
277−53:5 glyph ^-
278−53:8 name msg
279−54:7 INDENT
280−54:7 glyph ?-
281−54:10 name x
282−55:9 INDENT
283−55:9 lit ~
284−55:11 lit %add
285−56:9 NEWLINE
286−56:9 glyph [
287−56:10 tight lit ~
288−56:12 name text
289−56:16 tight glyph ]
290−56:18 glyph [
291−56:19 tight lit %note
292−56:25 name text
293−56:29 tight glyph ]
294−57:1 DEDENT
295−57:1 DEDENT
296−57:1 DEDENT
297−57:1 DEDENT
298−57:1 NEWLINE
299−57:1 glyph ++
300−57:4 name nested-unit
301−57:16 glyph |=
302−57:19 name x
303−57:20 tight glyph =
304−57:21 tight name maybe
305−58:3 INDENT
306−58:3 glyph ^-
307−58:6 name msg
308−59:5 INDENT
309−59:5 glyph ?-
310−59:8 name x
311−60:7 INDENT
312−60:7 lit ~
313−61:9 INDENT
314−61:9 glyph ?-
315−61:12 name x
316−62:11 INDENT
317−62:11 lit ~
318−62:13 lit %add
319−63:11 NEWLINE
320−63:11 glyph [
321−63:12 tight lit ~
322−63:14 name inner
323−63:19 tight glyph ]
324−63:21 glyph [
325−63:22 tight lit %note
326−63:28 name inner
327−63:33 tight glyph ]
328−64:7 DEDENT
329−64:7 DEDENT
330−64:7 NEWLINE
331−64:7 glyph [
332−64:8 tight lit ~
333−64:10 name text
334−64:14 tight glyph ]
335−64:16 glyph [
336−64:17 tight lit %note
337−64:23 name text
338−64:27 tight glyph ]
339−65:1 DEDENT
340−65:1 DEDENT
341−65:1 DEDENT
342−65:1 NEWLINE
343−65:1 glyph ++
344−65:4 name pending-null
345−65:17 glyph |=
346−65:20 name x
347−65:21 tight glyph =
348−65:22 tight name maybe
349−66:3 INDENT
350−66:3 glyph ~&
351−66:6 lit ~
352−67:5 INDENT
353−67:5 glyph ^-
354−67:8 name msg
355−68:7 INDENT
356−68:7 glyph ?-
357−68:10 name x
358−69:9 INDENT
359−69:9 lit ~
360−69:11 lit %add
361−70:9 NEWLINE
362−70:9 glyph [
363−70:10 tight lit ~
364−70:12 name text
365−70:16 tight glyph ]
366−70:18 glyph [
367−70:19 tight lit %note
368−70:25 name text
369−70:29 tight glyph ]
370−70:30 DEDENT
371−70:30 DEDENT
372−70:30 DEDENT
373−70:30 DEDENT
374−70:30 NEWLINE
410+41:4 name contextual-bad
411+41:19 glyph |=
412+41:22 name x
413+41:23 tight glyph =
414+41:24 tight tvar A
415+41:26 glyph ^-
416+41:29 glyph [
417+41:30 tight name a
418+41:31 tight glyph =
419+41:32 tight tvar A
420+41:34 name b
421+41:35 tight glyph =
422+41:36 tight glyph (
423+41:37 tight name unit
424+41:42 tvar A
425+41:43 tight glyph )
426+41:44 tight glyph ]
427+41:46 glyph [
428+41:47 tight name a
429+41:48 tight glyph =
430+41:49 tight name x
431+41:51 name b
432+41:52 tight glyph =
433+41:53 tight glyph `
434+41:54 tight str "hi"
435+41:58 tight glyph ]
436+42:1 NEWLINE
437+42:1 glyph ++
438+42:4 name nested-units
439+42:17 glyph ^-
440+42:20 glyph (
441+42:21 tight name list
442+42:26 glyph (
443+42:27 tight name unit
444+42:32 name msg
445+42:35 tight glyph )
446+42:36 tight glyph )
447+42:38 glyph ~[
448+42:40 tight glyph `
449+42:41 tight lit %go
450+42:45 glyph `
451+42:46 tight lit %stay
452+42:51 tight glyph ]
453+43:1 NEWLINE
454+43:1 glyph ++
455+43:4 name nested-units-bad
456+43:21 glyph ^-
457+43:24 glyph (
458+43:25 tight name list
459+43:30 glyph (
460+43:31 tight name unit
461+43:36 name msg
462+43:39 tight glyph )
463+43:40 tight glyph )
464+43:42 glyph ~[
465+43:44 tight glyph `
466+43:45 tight lit %go
467+43:49 glyph `
468+43:50 tight lit %oops
469+43:55 tight glyph ]
470+44:1 NEWLINE
471+44:1 glyph ++
472+44:4 name case-discarded
473+45:3 INDENT
474+45:3 glyph ~&
475+45:6 lit %pending
476+46:5 INDENT
477+46:5 glyph ^-
478+46:8 name record
479+46:15 glyph [
480+46:16 tight glyph `
481+46:17 tight lit %go
482+46:21 glyph ~[
483+46:23 tight glyph `
484+46:24 tight str "hi"
485+46:28 tight glyph ]
486+46:29 tight glyph ]
487+46:30 DEDENT
488+46:30 DEDENT
489+46:30 NEWLINE
tests/golden/types-unit-context/tree.txt+218−180
@@ -1,182 +1,220 @@
11(module
2− (mold 1:1 maybe
3− (union 2:3
4− (const 2:3 ~)
5− (cell 3:3
6− (const 3:4 ~)
7− (face 3:6 value (aura 3:12 @t)))))
8− (mold 4:1 msg
9− (union 5:3
10− (const 5:3 %add)
11− (cell 6:3
12− (const 6:4 %note)
13− (face 6:10 text (aura 6:15 @t)))))
14− (value 7:1 cast
15− (gate 7:9
16− (face 7:12 x (ref 7:14 maybe))
17− (body 8:3
18− (cast 8:3
19− (ref 8:6 msg)
20− (body 9:5
21− (branch 9:5
22− (wing 9:8 x)
23− (arm 10:7 (lit 10:7 ~) (lit 10:9 %add))
24− (arm 11:7
25− (cell 11:7 (lit 11:8 ~) (bind 11:10 text))
26− (tuple 11:16 (lit 11:17 %note) (wing 11:23 text)))))))))
27− (value 12:1 reversed
28− (gate 12:13
29− (face 12:16 x (ref 12:18 maybe))
30− (body 13:3
31− (cast 13:3
32− (ref 13:6 msg)
33− (body 14:5
34− (branch 14:5
35− (wing 14:8 x)
36− (arm 15:7
37− (cell 15:7 (lit 15:8 ~) (bind 15:10 text))
38− (tuple 15:16 (lit 15:17 %note) (wing 15:23 text)))
39− (arm 16:7 (lit 16:7 ~) (lit 16:9 %add))))))))
40− (value 17:1 consume
41− (gate 17:12
42− (face 17:15 x (ref 17:17 msg))
43− (str 17:21 "ok")))
44− (value 18:1 call
45− (gate 18:9
46− (face 18:12 x (ref 18:14 maybe))
47− (body 19:3
48− (group 19:3
49− (call 19:4
50− (wing 19:4 consume)
51− (branch 20:5
52− (wing 20:8 x)
53− (arm 21:7 (lit 21:7 ~) (lit 21:9 %add))
54− (arm 22:7
55− (cell 22:7 (lit 22:8 ~) (bind 22:10 text))
56− (tuple 22:16 (lit 22:17 %note) (wing 22:23 text)))))))))
57− (value 23:1 nested
58− (gate 23:11
59− (face 23:14 x (ref 23:16 maybe))
60− (body 24:3
61− (cast 24:3
62− (ref 24:6 msg)
63− (body 25:5
64− (branch 25:5
65− (wing 25:8 x)
66− (arm 26:7
67− (lit 26:7 ~)
68− (body 27:9
69− (branch 27:9
70− (lit 27:12 %.y)
71− (arm 28:11 (lit 28:11 %.y) (lit 28:15 %add))
72− (arm 29:11
73− (lit 29:11 %.n)
74− (tuple 29:15 (lit 29:16 %note) (str 29:22 "hi"))))))
75− (arm 30:7
76− (cell 30:7 (lit 30:8 ~) (bind 30:10 text))
77− (tuple 30:16 (lit 30:17 %note) (wing 30:23 text)))))))))
78− (value 31:1 bad-empty
79− (gate 31:14
80− (face 31:17 x (ref 31:19 maybe))
81− (body 32:3
82− (cast 32:3
83− (ref 32:6 msg)
84− (body 33:5
85− (branch 33:5
86− (wing 33:8 x)
87− (arm 34:7 (lit 34:7 ~) (lit 34:9 %missing))
88− (arm 35:7
89− (cell 35:7 (lit 35:8 ~) (bind 35:10 text))
90− (tuple 35:16 (lit 35:17 %note) (wing 35:23 text)))))))))
91− (value 36:1 bad-present
2+ (mold 1:1 msg
3+ (union 2:3 (const 2:3 %go) (const 3:3 %stay)))
4+ (mold 4:1 mimic
5+ (generic 4:10 A
6+ (union 5:3
7+ (const 5:3 ~)
8+ (cell 6:3
9+ (const 6:4 ~)
10+ (face 6:6 u (tvar 6:8 A))))))
11+ (mold 7:1 record
12+ (cell 7:11
13+ (face 7:12 u
14+ (apply 7:14 unit (ref 7:20 msg)))
15+ (face 7:25 xs
16+ (apply 7:28 list
17+ (apply 7:34 unit (aura 7:40 @t))))))
18+ (value 8:1 valid
19+ (cast 8:10
20+ (apply 8:13 unit (ref 8:19 msg))
21+ (unit 8:24 (lit 8:25 %go))))
22+ (value 9:1 invalid
23+ (cast 9:12
24+ (apply 9:15 unit (ref 9:21 msg))
25+ (unit 9:26 (lit 9:27 %bad))))
26+ (value 10:1 str
27+ (cast 10:8
28+ (apply 10:11 unit (aura 10:17 @t))
29+ (unit 10:21 (str 10:22 "hi"))))
30+ (value 11:1 wrong
31+ (cast 11:10
32+ (apply 11:13 unit (aura 11:19 @t))
33+ (unit 11:23 (lit 11:24 ~zod))))
34+ (value 12:1 nest
35+ (cast 12:9
36+ (apply 12:12 unit
37+ (apply 12:18 unit (aura 12:24 @t)))
38+ (unit 12:29
39+ (unit 12:30 (str 12:31 "hi")))))
40+ (value 13:1 nested-bad
41+ (cast 13:15
42+ (apply 13:18 unit
43+ (apply 13:24 unit (aura 13:30 @t)))
44+ (unit 13:35
45+ (unit 13:36 (lit 13:37 ~zod)))))
46+ (value 14:1 lis
47+ (cast 14:8
48+ (apply 14:11 unit
49+ (apply 14:17 list (aura 14:23 @t)))
50+ (unit 14:28
51+ (list 14:29 (str 14:31 "hi")))))
52+ (value 15:1 list-bad
53+ (cast 15:13
54+ (apply 15:16 unit
55+ (apply 15:22 list (aura 15:28 @t)))
56+ (unit 15:33
57+ (list 15:34 (lit 15:36 ~zod)))))
58+ (value 16:1 accept
59+ (gate 16:11
60+ (face 16:14 x
61+ (apply 16:16 unit (ref 16:22 msg)))
62+ (wing 16:27 x)))
63+ (value 17:1 call
64+ (group 17:9
65+ (call 17:10
66+ (wing 17:10 accept)
67+ (unit 17:17 (lit 17:18 %stay)))))
68+ (value 18:1 bad-call
69+ (group 18:13
70+ (call 18:14
71+ (wing 18:14 accept)
72+ (unit 18:21 (lit 18:22 %bad)))))
73+ (value 19:1 field
74+ (cast 19:10
75+ (ref 19:13 record)
76+ (tuple 19:20
77+ (unit 19:21 (lit 19:22 %go))
78+ (list 19:26
79+ (unit 19:28 (str 19:29 "hi"))))))
80+ (value 20:1 field-bad
81+ (cast 20:14
82+ (ref 20:17 record)
83+ (tuple 20:24
84+ (unit 20:25 (lit 20:26 %bad))
85+ (list 20:31
86+ (unit 20:33 (str 20:34 "hi"))))))
87+ (value 21:1 mimic-mismatch
88+ (cast 21:19
89+ (apply 21:22 mimic (aura 21:29 @t))
90+ (unit 21:33 (str 21:34 "hi"))))
91+ (value 22:1 without-context
92+ (unit 22:20 (lit 22:21 %go)))
93+ (value 23:1 pending
94+ (body 24:3
95+ (trace 24:3
96+ (lit 24:6 %other)
97+ (body 25:5
98+ (cast 25:5
99+ (apply 25:8 unit (ref 25:14 msg))
100+ (unit 25:19 (lit 25:20 %go)))))))
101+ (value 26:1 pending-null
102+ (body 27:3
103+ (trace 27:3
104+ (lit 27:6 ~)
105+ (body 28:5
106+ (cast 28:5
107+ (apply 28:8 unit (aura 28:14 @t))
108+ (unit 28:18 (str 28:19 "hi")))))))
109+ (value 29:1 preserve
110+ (gate 29:13
111+ (face 29:16 x (tvar 29:18 A))
112+ (cast 29:20
113+ (apply 29:23 unit (tvar 29:29 A))
114+ (unit 29:32 (wing 29:33 x)))))
115+ (value 30:1 force
116+ (gate 30:10
117+ (face 30:13 x (tvar 30:15 A))
118+ (cast 30:17
119+ (apply 30:20 unit (tvar 30:26 A))
120+ (unit 30:29 (str 30:30 "hi")))))
121+ (mold 31:1 alt
122+ (union 32:3 (const 32:3 %go) (const 33:3 %stay)))
123+ (value 34:1 field-wrong-payload
124+ (cast 34:24
125+ (ref 34:27 record)
126+ (tuple 34:34
127+ (unit 34:35 (lit 34:36 %go))
128+ (list 34:40
129+ (unit 34:42 (lit 34:43 ~zod))))))
130+ (value 35:1 wrong-name
131+ (cast 35:15
132+ (ref 35:18 record)
133+ (tuple 35:25
134+ (face 35:26 wrong
135+ (unit 35:32 (lit 35:33 %go)))
136+ (face 35:37 xs
137+ (list 35:40
138+ (unit 35:42 (str 35:43 "hi")))))))
139+ (value 36:1 wrong-union
92140 (gate 36:16
93− (face 36:19 x (ref 36:21 maybe))
94− (body 37:3
95− (cast 37:3
96− (ref 37:6 msg)
97− (body 38:5
98− (branch 38:5
99− (wing 38:8 x)
100− (arm 39:7 (lit 39:7 ~) (lit 39:9 %add))
101− (arm 40:7
102− (cell 40:7 (lit 40:8 ~) (bind 40:10 text))
103− (lit 40:16 %missing))))))))
104− (value 41:1 unknown
105− (gate 41:12
106− (bind 41:15 x)
107− (body 42:3
108− (cast 42:3
109− (ref 42:6 msg)
110− (body 43:5
111− (branch 43:5
112− (wing 43:8 x)
113− (arm 44:7 (lit 44:7 ~) (lit 44:9 %add))
114− (arm 45:7
115− (cell 45:7 (lit 45:8 ~) (bind 45:10 text))
116− (tuple 45:16 (lit 45:17 %note) (wing 45:23 text)))))))))
117− (value 46:1 shadow
118− (gate 46:11
119− (face 46:14 x (ref 46:16 maybe))
120− (body 47:3
121− (cast 47:3
122− (ref 47:6 msg)
123− (body 48:5
124− (branch 48:5
125− (wing 48:8 x)
126− (arm 49:7 (lit 49:7 ~) (lit 49:9 %add))
127− (arm 50:7
128− (cell 50:7 (lit 50:8 ~) (bind 50:10 x))
129− (tuple 50:13 (lit 50:14 %note) (wing 50:20 x)))))))))
130− (value 51:1 pending
131− (gate 51:12
132− (face 51:15 x (ref 51:17 maybe))
133− (body 52:3
134− (trace 52:3
135− (lit 52:6 %unknown)
136− (body 53:5
137− (cast 53:5
138− (ref 53:8 msg)
139− (body 54:7
140− (branch 54:7
141− (wing 54:10 x)
142− (arm 55:9 (lit 55:9 ~) (lit 55:11 %add))
143− (arm 56:9
144− (cell 56:9 (lit 56:10 ~) (bind 56:12 text))
145− (tuple 56:18 (lit 56:19 %note) (wing 56:25 text)))))))))))
146− (value 57:1 nested-unit
147− (gate 57:16
148− (face 57:19 x (ref 57:21 maybe))
149− (body 58:3
150− (cast 58:3
151− (ref 58:6 msg)
152− (body 59:5
153− (branch 59:5
154− (wing 59:8 x)
155− (arm 60:7
156− (lit 60:7 ~)
157− (body 61:9
158− (branch 61:9
159− (wing 61:12 x)
160− (arm 62:11 (lit 62:11 ~) (lit 62:13 %add))
161− (arm 63:11
162− (cell 63:11 (lit 63:12 ~) (bind 63:14 inner))
163− (tuple 63:21 (lit 63:22 %note) (wing 63:28 inner))))))
164− (arm 64:7
165− (cell 64:7 (lit 64:8 ~) (bind 64:10 text))
166− (tuple 64:16 (lit 64:17 %note) (wing 64:23 text)))))))))
167− (value 65:1 pending-null
168− (gate 65:17
169− (face 65:20 x (ref 65:22 maybe))
170− (body 66:3
171− (trace 66:3
172− (lit 66:6 ~)
173− (body 67:5
174− (cast 67:5
175− (ref 67:8 msg)
176− (body 68:7
177− (branch 68:7
178− (wing 68:10 x)
179− (arm 69:9 (lit 69:9 ~) (lit 69:11 %add))
180− (arm 70:9
181− (cell 70:9 (lit 70:10 ~) (bind 70:12 text))
182− (tuple 70:18 (lit 70:19 %note) (wing 70:25 text))))))))))))
141+ (face 36:19 x (ref 36:21 alt))
142+ (cast 36:25
143+ (ref 36:28 record)
144+ (tuple 36:35
145+ (unit 36:36 (wing 36:37 x))
146+ (list 36:39
147+ (unit 36:41 (str 36:42 "hi")))))))
148+ (value 37:1 no-field-context
149+ (gate 37:21
150+ (face 37:24 x (tvar 37:26 A))
151+ (cast 37:28
152+ (cell 37:31
153+ (face 37:32 a (tvar 37:34 A)))
154+ (tuple 37:37
155+ (face 37:38 wrong (wing 37:44 x))))))
156+ (value 38:1 known-left
157+ (gate 38:15
158+ (face 38:18 x (ref 38:20 msg))
159+ (cast 38:24
160+ (cell 38:27
161+ (face 38:28 a (ref 38:30 msg)))
162+ (tuple 38:35
163+ (face 38:36 a (wing 38:38 x))))))
164+ (value 39:1 mismatch-left
165+ (gate 39:18
166+ (face 39:21 x (ref 39:23 msg))
167+ (cast 39:27
168+ (cell 39:30
169+ (face 39:31 a (ref 39:33 alt)))
170+ (tuple 39:38
171+ (face 39:39 a (wing 39:41 x))))))
172+ (value 40:1 contextual
173+ (gate 40:15
174+ (face 40:18 x (tvar 40:20 A))
175+ (cast 40:22
176+ (cell 40:25
177+ (face 40:26 a (tvar 40:28 A))
178+ (face 40:30 b
179+ (apply 40:32 unit (tvar 40:38 A))))
180+ (tuple 40:42
181+ (face 40:43 a (wing 40:45 x))
182+ (face 40:47 b
183+ (unit 40:49 (wing 40:50 x)))))))
184+ (value 41:1 contextual-bad
185+ (gate 41:19
186+ (face 41:22 x (tvar 41:24 A))
187+ (cast 41:26
188+ (cell 41:29
189+ (face 41:30 a (tvar 41:32 A))
190+ (face 41:34 b
191+ (apply 41:36 unit (tvar 41:42 A))))
192+ (tuple 41:46
193+ (face 41:47 a (wing 41:49 x))
194+ (face 41:51 b
195+ (unit 41:53 (str 41:54 "hi")))))))
196+ (value 42:1 nested-units
197+ (cast 42:17
198+ (apply 42:20 list
199+ (apply 42:26 unit (ref 42:32 msg)))
200+ (list 42:38
201+ (unit 42:40 (lit 42:41 %go))
202+ (unit 42:45 (lit 42:46 %stay)))))
203+ (value 43:1 nested-units-bad
204+ (cast 43:21
205+ (apply 43:24 list
206+ (apply 43:30 unit (ref 43:36 msg)))
207+ (list 43:42
208+ (unit 43:44 (lit 43:45 %go))
209+ (unit 43:49 (lit 43:50 %oops)))))
210+ (value 44:1 case-discarded
211+ (body 45:3
212+ (trace 45:3
213+ (lit 45:6 %pending)
214+ (body 46:5
215+ (cast 46:5
216+ (ref 46:8 record)
217+ (tuple 46:15
218+ (unit 46:16 (lit 46:17 %go))
219+ (list 46:21
220+ (unit 46:23 (str 46:24 "hi"))))))))))
tests/golden/types-unit-context/types.txt+90−22
@@ -1,27 +1,95 @@
11partial inference; module not checked
2−+$ maybe: cases proven disjoint; mold not checked
32+$ msg: cases proven disjoint; mold not checked
4−++ cast: $-(maybe msg)
5−++ reversed: $-(maybe msg)
6−++ consume: $-(msg @t)
7−++ call: $-(maybe @t)
8−++ nested: $-(maybe msg)
9−++ bad-empty: branch arm does not fit its expected union
10−/tests/golden/types-unit-context/source.jibb:32:6: expected union
11− ^- msg
12− ^
13−/tests/golden/types-unit-context/source.jibb:34:9: branch arm
14− ~ %missing
15− ^
16−++ bad-present: branch arm does not fit its expected union
17−/tests/golden/types-unit-context/source.jibb:37:6: expected union
18− ^- msg
19− ^
20−/tests/golden/types-unit-context/source.jibb:40:16: branch arm
21− [~ text] %missing
3++$ mimic: cases proven disjoint; mold not checked
4++$ record: not checked
5+++ valid: (unit msg)
6+++ invalid: unit payload does not fit its expected type
7+/tests/golden/types-unit-context/source.jibb:9:15: expected unit payload
8+++ invalid ^- (unit msg) `%bad
9+ ^
10+/tests/golden/types-unit-context/source.jibb:9:27: payload
11+++ invalid ^- (unit msg) `%bad
12+ ^
13+++ str: (unit @t)
14+++ wrong: unit payload does not fit its expected type
15+/tests/golden/types-unit-context/source.jibb:11:13: expected unit payload has type @t
16+++ wrong ^- (unit @t) `~zod
17+ ^
18+/tests/golden/types-unit-context/source.jibb:11:24: payload has type @p
19+++ wrong ^- (unit @t) `~zod
20+ ^
21+++ nest: (unit (unit @t))
22+++ nested-bad: unit payload does not fit its expected type
23+/tests/golden/types-unit-context/source.jibb:13:18: expected unit payload has type @t
24+++ nested-bad ^- (unit (unit @t)) ``~zod
25+ ^
26+/tests/golden/types-unit-context/source.jibb:13:37: payload has type @p
27+++ nested-bad ^- (unit (unit @t)) ``~zod
28+ ^
29+++ lis: (unit (list @t))
30+++ list-bad: list item does not fit its expected type
31+/tests/golden/types-unit-context/source.jibb:15:16: expected item has type @t
32+++ list-bad ^- (unit (list @t)) `~[~zod]
2233 ^
23−++ unknown: unit branch subject is not supported by partial inference
24−++ shadow: pattern binder shadows a name
34+/tests/golden/types-unit-context/source.jibb:15:36: list item has type @p
35+++ list-bad ^- (unit (list @t)) `~[~zod]
36+ ^
37+++ accept: $-((unit msg) (unit msg))
38+++ call: (unit msg)
39+++ bad-call: unit payload does not fit its expected type
40+/tests/golden/types-unit-context/source.jibb:18:14: expected unit payload
41+++ bad-call (accept `%bad)
42+ ^
43+/tests/golden/types-unit-context/source.jibb:18:22: payload
44+++ bad-call (accept `%bad)
45+ ^
46+++ field: [u=(unit msg) xs=(list (unit @t))]
47+++ field-bad: unit payload does not fit its expected type
48+/tests/golden/types-unit-context/source.jibb:20:17: expected unit payload
49+++ field-bad ^- record [`%bad ~[`"hi"]]
50+ ^
51+/tests/golden/types-unit-context/source.jibb:20:26: payload
52+++ field-bad ^- record [`%bad ~[`"hi"]]
53+ ^
54+++ mimic-mismatch: cast constraint is not supported by partial inference
55+++ without-context: tag needs context in partial inference
2556++ pending: tag needs context in partial inference
26−++ nested-unit: $-(maybe msg)
2757++ pending-null: `~` needs context in partial inference
58+++ preserve: $-(A (unit A))
59+++ force: explicit capital constraints are not supported by partial inference
60++$ alt: cases proven disjoint; mold not checked
61+++ field-wrong-payload: unit payload does not fit its expected type
62+/tests/golden/types-unit-context/source.jibb:34:27: expected unit payload has type @t
63+++ field-wrong-payload ^- record [`%go ~[`~zod]]
64+ ^
65+/tests/golden/types-unit-context/source.jibb:34:43: payload has type @p
66+++ field-wrong-payload ^- record [`%go ~[`~zod]]
67+ ^
68+++ wrong-name: cast mold and expression type do not unify
69+/tests/golden/types-unit-context/source.jibb:35:18: cast mold
70+++ wrong-name ^- record [wrong=`%go xs=~[`"hi"]]
71+ ^
72+/tests/golden/types-unit-context/source.jibb:35:25: expression
73+++ wrong-name ^- record [wrong=`%go xs=~[`"hi"]]
74+ ^
75+++ wrong-union: unit payload constraint is not supported by partial inference
76+++ no-field-context: cast mold and expression type do not unify
77+/tests/golden/types-unit-context/source.jibb:37:31: cast mold has type [a=A]
78+++ no-field-context |= x=A ^- [a=A] [wrong=x]
79+ ^
80+/tests/golden/types-unit-context/source.jibb:37:37: expression has type [wrong=A]
81+++ no-field-context |= x=A ^- [a=A] [wrong=x]
82+ ^
83+++ known-left: $-(msg [a=msg])
84+++ mismatch-left: cast constraint is not supported by partial inference
85+++ contextual: $-(A [a=A b=(unit A)])
86+++ contextual-bad: explicit capital constraints are not supported by partial inference
87+++ nested-units: (list (unit msg))
88+++ nested-units-bad: unit payload does not fit its expected type
89+/tests/golden/types-unit-context/source.jibb:43:24: expected unit payload
90+++ nested-units-bad ^- (list (unit msg)) ~[`%go `%oops]
91+ ^
92+/tests/golden/types-unit-context/source.jibb:43:50: payload
93+++ nested-units-bad ^- (list (unit msg)) ~[`%go `%oops]
94+ ^
95+++ case-discarded: tag needs context in partial inference
tests/lib/jibb.hoon+1−1
@@ -2984,7 +2984,7 @@
29842984++ test-types-unit-construction
29852985 (weld (check ~.types-unit-construction src-533 `tok-533 `tre-533) (check-module-types ~.types-unit-construction ~[%tests %golden ~.types-unit-construction %source %jibb] src-533 `typ-533 ~ ~ ~))
29862986++ test-types-unit-context
2987− (weld (check ~.types-unit-context src-534 `tok-534 `tre-534) (check-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-534 `typ-534))
2987+ (weld (check ~.types-unit-context src-534 `tok-534 `tre-534) (check-module-types ~.types-unit-context ~[%tests %golden ~.types-unit-context %source %jibb] src-534 `typ-534 ~ ~ ~))
29882988++ test-types-unit-patterns
29892989 (weld (check ~.types-unit-patterns src-535 `tok-535 `tre-535) (check-types ~.types-unit-patterns ~[%tests %golden ~.types-unit-patterns %source %jibb] src-535 `typ-535))
29902990::