on master help sign in
Propagate union context and read collection unions
commit0070584c3d1b8d1a10a4aa3cf71285bf0efa7042 authoriko <mail@iko.soy> dateFri 30 Oct 2026, 20:05 (13 hours ago) parent5c73614
28 files changed+1046−140
docs/compiler.md+3−1 docs/prelude-inventory.md+1−1 docs/status.md+7−6 jibb-dev/lib/jibb-import.hoon+134−5 jibb-dev/lib/jibb.hoon+58−2 jibb-dev/lib/jibb/prelude.jibb+6 tests/golden/prelude-unit-list-transforms/about.txt+2−2 tests/golden/prelude-unit-list-transforms/source.jibb+6 tests/golden/prelude-unit-list-transforms/tokens.txt+36−5 tests/golden/prelude-unit-list-transforms/tree.txt+16−1 tests/golden/prelude-unit-list-transforms/types.txt+1 tests/golden/types-union-branch-context/about.txt+4 tests/golden/types-union-branch-context/source.jibb+54 tests/golden/types-union-branch-context/tokens.txt+237 tests/golden/types-union-branch-context/tree.txt+120 tests/golden/types-union-branch-context/types.txt+24 tests/golden/types-union-branch-pending/about.txt+4 tests/golden/types-union-branch-pending/source.jibb+24 tests/golden/types-union-branch-pending/tokens.txt+102 tests/golden/types-union-branch-pending/tree.txt+48 tests/golden/types-union-branch-pending/types.txt+6 tests/golden/types-union-context-flow/types.txt+1−1 tests/importer/about.txt+7−3 tests/importer/shadow-static.txt+1 tests/importer/small.txt+9 tests/importer/tree.txt+14−4 tests/lib/jibb.hoon+120−108 tools/importer-test+1−1
docs/compiler.md+3−1
@@ -60,7 +60,9 @@ The inference fragment supports fixed auras, unrestricted `@`, one-way widening
6060
6161For supported closed unions, the type printer keeps the union’s origin separate from its displayed name. It prints an in-scope name such as `msg` or `msg.lib`, including in records and gates; an accessible imported alias may name a transitive union. A body-local union that escapes its scope, or an origin without an accessible name, prints its cases separated by spaces, parenthesized when nested. That case-list form is print-only. Two faces for the same imported origin remain compatible; compatibility between distinct union origins, including in gate types, remains unsupported. Generic unions remain unsupported, even when a parameter is unused. The Hoon bridge does not yet translate union forks into inference, so this printing support does not complete unnamed Hoon union imports.
6262
63−The separate `jibb-dev/lib/jibb-import.hoon` is an unfinished reader for selected Hoon type graphs. It handles named recursion, nested map, set, queue, list, unit, jar and jug arguments, direct ordered maps, and direct `$^` unions whose source branches can be proved disjoint. It also reads ordered map fields in records when the map arguments are syntactically fixed atom molds and other fields are fixed atom molds or standard collections of static atom molds. Collection names must not be shadowed. The reader can also import a mark door sample, removing its outer sample face and validating its build subject. The reader checks explicit Hoon `$%`, `$?` and `$^` unions against the Grammar’s disjointness rule (doc question 22). It re-evaluates statically recognizable source branches before Hoon can collapse them, checks materialized fork cases, and rejects shapes it cannot prove disjoint. Static records may also have verified standard-collection and `path` siblings. Explicit unions in collection arguments remain unsupported; other nested ordered maps, general source-level disjointness and complete integration with the checker remain unfinished. `+golden-types-imports` can consume fixed-aura atoms and nested faced or unfaced cells with valid Jibb face names from caller-supplied reader results for declared `/-` imports; `+golden-types-with-marks` accepts those same shapes from declared mark imports in a separate list. Other forms remain unsupported. Its disjointness proof is conservative and can reject a valid union it cannot prove disjoint. Collection recognition requires the originating `/sur` core. The reader validates direct zuse subjects and Ford subjects consisting of faced imported cores and a validated tail, checking imported cores transitively; it rejects shadowed names, inconsistent core subjects and other subject shapes. For a recursive reference, the reader matches the exact Hoon hold against named arms in validated cores, including transitive Ford imports; it rejects missing, unlabelled or ambiguous origins. Its fixtures include three real Tlon files; `tools/importer-test` compares the internal projection under eval, and the ship test compares the same golden output. `tools/type-import-test` and `tools/type-mark-test` compare bridge reports under eval and on the ship. `tools/clay-fixtures` also passes Clay-built `/sur` molds and mark samples through the Clay-built importer and partial checker.
63+A known closed union can also provide context to each arm of a complete loobean 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.
64+
65+The separate `jibb-dev/lib/jibb-import.hoon` is an unfinished reader for selected Hoon type graphs. It handles named recursion, nested map, set, queue, list, unit, jar and jug arguments, direct ordered maps, and direct `$^` unions whose source branches can be proved disjoint. It also reads ordered map fields in records when the map arguments are syntactically fixed atom molds and other fields are fixed atom molds or standard collections of static atom molds. Collection names must not be shadowed. The reader can also import a mark door sample, removing its outer sample face and validating its build subject. The reader checks explicit Hoon `$%`, `$?` and `$^` unions against the Grammar’s disjointness rule (doc question 22). It re-evaluates statically recognizable source branches before Hoon can collapse them, checks materialized fork cases, and rejects shapes it cannot prove disjoint. Static records may also have verified standard-collection and `path` siblings. One direct explicit union argument in a standard list, set, map or unit is accepted when its call wrapper and collection provenance are verified and its static cases are pairwise disjoint. Other collection-union forms, nested ordered maps, general source-level disjointness and complete integration with the checker remain unfinished. `+golden-types-imports` can consume fixed-aura atoms and nested faced or unfaced cells with valid Jibb face names from caller-supplied reader results for declared `/-` imports; `+golden-types-with-marks` accepts those same shapes from declared mark imports in a separate list. Other forms remain unsupported. Its disjointness proof is conservative and can reject a valid union it cannot prove disjoint. Collection recognition requires the originating `/sur` core. The reader validates direct zuse subjects and Ford subjects consisting of faced imported cores and a validated tail, checking imported cores transitively; it rejects shadowed names, inconsistent core subjects and other subject shapes. For a recursive reference, the reader matches the exact Hoon hold against named arms in validated cores, including transitive Ford imports; it rejects missing, unlabelled or ambiguous origins. Its fixtures include three real Tlon files; `tools/importer-test` compares the internal projection under eval, and the ship test compares the same golden output. `tools/type-import-test` and `tools/type-mark-test` compare bridge reports under eval and on the ship. `tools/clay-fixtures` also passes Clay-built `/sur` molds and mark samples through the Clay-built importer and partial checker.
6466
6567Callers that have a `/sur` core and a name can use `+read-named`: it checks for a locally declared arm before asking Hoon to evaluate the mold, and reports evaluation failures with the final Hoon trace line. `+read-mold-in` remains available when the caller already has the selected type. The checker currently treats a failed import as unsupported rather than rendering the importer's error.
6668
docs/prelude-inventory.md+1−1
@@ -32,7 +32,7 @@ The following is an audit of the Hoon 135 bodies, not a completed Jibb interface
3232| `clef` | Applies a gate returning a unit when both inputs are present; otherwise returns an absent unit. | Written |
3333| `drop` | Converts an absent unit to an empty list and a present unit to a singleton. | Written |
3434| `fall` | Returns the value of a present unit or the supplied fallback. | Written |
35−| `flit` | Returns a gate that wraps a value only if it satisfies the predicate. | Missing |
35+| `flit` | Returns a gate that wraps a value only if it satisfies the predicate. | Written |
3636| `hunt` | Returns the only present unit or chooses between two present values with an ordering gate. | Missing |
3737| `lift` | Takes a mold and a unit, then applies the mold to a present value as `bind` does. | Missing; Jibb molds are not callable values |
3838| `mate` | Returns the present unit if only one is present; when both are present it returns one if their values are equal and crashes otherwise. | Missing |
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 and nested faced or unfaced cells from `/sur` molds and marks into inference. The reader handles mark samples, recursive molds whose origins can be verified through Ford imports, nested collections, direct ordered maps, certain ordered-map fields, and direct `$^` unions whose cases can be proved disjoint. Ambiguous recursive origins fail closed; recognizable explicit unions are checked from source before Hoon can collapse their cases (doc question 22), while other nested unions, nested ordered maps, general union disjointness and complete import integration remain unfinished. The partial checker resolves a subset of ordinary library imports in dependency order using supplied Jibb sources and the current prelude names, 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, simple and nonrecursive generic mold aliases, selected faced record casts and field reads, and contextual tags and constructors for closed disjoint unions. Variable-dependent face merges remain unsupported. Supported closed unions print using an in-scope name or imported alias; a union whose name is not accessible prints its cases, parenthesized when nested. The latter is print-only. Different import faces for the same origin remain compatible; compatibility across distinct union origins is still unsupported, as are generic unions even when their parameters are unused. The Hoon bridge cannot yet bring union forks into inference. Unfixed decimal literals default to `@ud` in gate-free inferred types; recursive local groups and molds, 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; its golden fixtures include three real Tlon files. The prelude currently has only a few functions, 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 and nested faced or unfaced cells from `/sur` molds and marks into inference. 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 (doc question 22), while other nested unions, nested ordered maps, general union disjointness and complete import integration remain unfinished. The partial checker resolves a subset of ordinary library imports in dependency order using supplied Jibb sources and the current prelude names, 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, simple and nonrecursive generic mold aliases, selected faced record casts and field reads, and contextual tags and constructors for closed disjoint unions, including propagation through complete loobean branches in casts and known union-sample calls. Variable-dependent face merges remain unsupported. Supported closed unions print using an in-scope name or imported alias; a union whose name is not accessible prints its cases, parenthesized when nested. The latter is print-only. Different import faces for the same origin remain compatible; compatibility across distinct union origins is still unsupported, as are generic unions even when their parameters are unused. The Hoon bridge cannot yet bring union forks into inference. Unfixed decimal literals default to `@ud` in gate-free inferred types; recursive local groups and molds, general branch tag context, other constraint cases and defaulting inside gate types still need work. Collection recognition checks the originating core and fails closed on shadows or unsupported Ford subject shapes; its golden fixtures include three real Tlon files. The prelude currently has only a few functions, and [prelude-inventory.md](prelude-inventory.md) is a source audit, not the complete inventory or signatures. The milestone remains unfinished.
2323
2424## Milestone 1: parser and mark
2525
@@ -37,8 +37,8 @@ What the plan asks for, and where it is:
3737
3838Besides the plan's list:
3939
40−- 479 golden cases: 263 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.
41−- The 479-case corpus passed under `urbit eval` in 34.1 s. The fake ship passed all 484 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 25.5 s for sync and 29.8 s for tests. The importer golden compares 130 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.
40+- 481 golden cases: 265 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.
41+- The 481-case corpus passed under `urbit eval` in 57.8 s. The fake ship passed all 486 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 25.7 s for sync and 53.8 s for tests. The importer golden compares 140 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.
4242- `tools/testdata/selftest` (22 checks) and `tools/testdata/ship-selftest` test the tools themselves.
4343- 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.
4444- 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).
@@ -69,14 +69,15 @@ Besides the plan's list:
6969| d8ac47d | 2026-10-30 | Cache library interfaces, preserve imported Hoon record faces, and check nested tagged unions |
7070| edd9277 | 2026-10-30 | Infer nonrecursive generic mold aliases with lexical parameters |
7171| 4406f6f | 2026-10-30 | Resolve selected contextual tags and check explicit imported unions |
72−| This change | 2026-10-30 | Print supported named and escaping union types |
72+| 5c73614 | 2026-10-30 | Print supported named and escaping union types |
73+| This change | 2026-10-30 | Propagate union context through loobean branches, read selected unions in Hoon collections, and add `flit` |
7374
7475## Checking it
7576
7677On a machine set up as [development.md](development.md) says:
7778
7879```
79−tools/golden # 479 cases under urbit eval
80+tools/golden # 481 cases under urbit eval
8081tools/importer-test # the Hoon importer fixture projection
8182tools/type-import-test # the importer/checker bridge fixture
8283tools/type-mark-test # the mark/checker bridge fixture
@@ -86,7 +87,7 @@ tools/testdata/selftest # the tools themselves
8687tools/doc-blocks docs/spec # the doc's examples are golden cases
8788tools/ship start
8889tools/ship gen-tests --check # tests/lib/jibb.hoon is up to date
89−tools/ship test # the same 479 cases as -test arms on the ship
90+tools/ship test # the same 481 cases as -test arms on the ship
9091tools/testdata/ship-selftest
9192tools/ship check-commit # |commit stores .jibb files
9293tools/clay-fixtures # example /sur files and marks build through Clay
jibb-dev/lib/jibb-import.hoon+134−5
@@ -16,7 +16,10 @@
1616:: other nested forms and unprovably disjoint cases remain unsupported. Source-level overlap in
1717:: other unions, general nested ordered maps, broader Ford subject
1818:: shapes, ambiguous recursive origins and full error locations still
19−:: need work. A nested ordered map is recovered only when its key and
19+:: need work. One direct union argument to a standard collection is
20+:: recovered only from its exact call wrapper, static independent cases,
21+:: proven disjoint branches and unshadowed standard names. Other source
22+:: shapes fail closed. A nested ordered map is recovered only when its key and
2023:: value are fixed atom molds and
2124:: the other fields are fixed atoms or collections of static atoms;
2225:: other source shapes fail closed.
@@ -764,6 +767,123 @@
764767 ?. (levy t.found same) ~
765768 [~ choice]
766769::
770+::
771+:: A collection case is independent of the subject only when its
772+:: original spec uses literal atoms, tags and finite record structure.
773+++ static-union-spec
774+ |= s=spec
775+ ^- ?
776+ ?+ s |
777+ [%base *] ?=([%atom *] p.s)
778+ [%leaf *] &
779+ [%bcts *] ?@ p.s $(s q.s)
780+ |
781+ [%bccl *] (static-union-specs p.s)
782+ ==
783+::
784+++ static-union-specs
785+ |= parts=(list spec)
786+ ^- ?
787+ ?~ parts &
788+ &((static-union-spec i.parts) $(parts t.parts))
789+::
790+++ union-spec-parts
791+ |= s=spec
792+ ^- (unit (list spec))
793+ ?+ s ~
794+ [%bcwt *] [~ p.s]
795+ [%bccn *] [~ p.s]
796+ [%bckt *] [~ ~[p.s q.s]]
797+ ==
798+::
799+:: Select one direct union argument, replacing exactly that spec with
800+:: @t. The other arguments must be static and cannot contain unions.
801+++ safe-union-parts
802+ |= cases=(list spec)
803+ ^- ?
804+ ?~ cases |
805+ ?~ t.cases |
806+ =/ rest=(list spec) t.cases
807+ &((static-union-spec i.cases) (levy rest |=(part=spec (static-union-spec part))))
808+::
809+++ split-union-arguments
810+ |= [args=(list hoon) index=@ud]
811+ ^- (unit [args=(list hoon) cases=(list spec) index=@ud])
812+ ?~ args ~
813+ ?. ?=([%ktcl *] i.args) ~
814+ =/ cases (union-spec-parts p.i.args)
815+ ?^ cases
816+ ?. (safe-union-parts u.cases) ~
817+ ?. (static-arguments t.args) ~
818+ [~ [[[%ktcl [%base [%atom %t]]] t.args] u.cases index]]
819+ ?. (static-spec p.i.args) ~
820+ =/ rest $(args t.args, index +(index))
821+ ?~ rest ~
822+ [~ [[i.args args.u.rest] cases.u.rest index.u.rest]]
823+::
824+++ replace-union-argument
825+ |= [args=(list imported) index=@ud union=imported]
826+ ^- (unit (list imported))
827+ ?~ args ~
828+ ?: =(index 0)
829+ ?. =([%atom %t ~] i.args) ~
830+ [~ [union t.args]]
831+ =/ rest $(args t.args, index (dec index))
832+ ?~ rest ~
833+ [~ [i.args u.rest]]
834+::
835+:: Accept only the compiler's direct collection call wrapper.
836+++ direct-collection-source
837+ |= [body=hoon original=hoon]
838+ ^- ?
839+ ?. ?=([%cncl [%tsgr * [%cncl *]] *] body) |
840+ ?. =(p.p.body [%wing ~[[%.y 7]]]) |
841+ ?. =(q.body ~[[%$ 6]]) |
842+ ?. ?=([%tsls * *] original) |
843+ =(q.original [%tsls [%dtts [%$ 14] [%$ 2]] [%$ 6]])
844+::
845+++ collection-union
846+ |= [typ=type module=term sig=signatures seen=visiting context=(unit type)]
847+ ^- imported
848+ ?. ?=([%hold *] typ) [%bad 'a Hoon union needs a source-level disjointness check']
849+ =/ is-cell=? (has-spec-cell-union q.typ)
850+ =/ unsupported=@t
851+ ?: is-cell 'a Hoon $^ union needs a source-level disjointness check'
852+ 'a Hoon union needs a source-level disjointness check'
853+ =/ original=hoon q.typ
854+ ?. ?=([%tsls [%note * *] *] original) [%bad unsupported]
855+ =/ body=hoon q.p.original
856+ =/ alias (source-alias body)
857+ ?~ alias [%bad unsupported]
858+ ?. (alias-safe context u.alias) [%bad 'Hoon collection provenance is unavailable or shadowed']
859+ =/ names=(list term) ~[%map %set %qeu %list %unit %jar %jug]
860+ ?: (lien names |=(n=term &((source-uses body n) !(alias-safe context n))))
861+ [%bad 'Hoon collection provenance is unavailable or shadowed']
862+ ?. (direct-collection-source body original) [%bad unsupported]
863+ ?> ?=([%cncl [%tsgr * [%cncl *]] *] body)
864+ =/ split (split-union-arguments q.q.p.body 0)
865+ ?~ split [%bad unsupported]
866+ =/ tried=(each (list type) tang)
867+ (mule |.((turn cases.u.split |=(s=spec (~(play ut p.typ) [%kttr s])))))
868+ ?. ?=([%& *] tried) [%bad unsupported]
869+ =/ cases=(list imported)
870+ (turn p.tried |=(t=type (walk module t sig seen context)))
871+ =/ err (first-bads cases)
872+ ?^ err [%bad u.err]
873+ ?. (all-disjoint cases)
874+ [%bad ?:(is-cell 'a Hoon $^ union has overlapping cases' 'a Hoon union has overlapping cases')]
875+ =/ rewritten=hoon original(q.p body(q.q.p args.u.split))
876+ =/ attempt=(each type tang) (mule |.((~(play ut p.typ) rewritten)))
877+ ?. ?=([%& *] attempt) [%bad unsupported]
878+ =/ out=imported (walk module p.attempt sig seen context)
879+ ?. ?=([%apply *] out) [%bad unsupported]
880+ ?. =(name.out u.alias) [%bad unsupported]
881+ =/ replacement=imported
882+ [%fork (sort cases |=(pair=[imported imported] (dor -.pair +.pair)))]
883+ =/ args (replace-union-argument args.out index.u.split replacement)
884+ ?~ args [%bad unsupported]
885+ [%apply name.out u.args]
886+::
767887++ walk
768888 |= [module=term typ=type sig=signatures seen=visiting context=(unit type)]
769889 ^- imported
@@ -788,10 +908,9 @@
788908 [%fork (sort cases |=(pair=[imported imported] (dor -.pair +.pair)))]
789909 [%hint *] $(typ q.typ)
790910 [%hold *]
791− ?: &(?=([%tsls [%note * *] *] q.typ) (has-spec-cell-union q.typ))
792− [%bad 'a Hoon $^ union needs a source-level disjointness check']
793− ?: &(?=([%tsls [%note * *] *] q.typ) (has-spec-general-union q.typ))
794− [%bad 'a Hoon union needs a source-level disjointness check']
911+ ?: &(?=([%tsls [%note * *] *] q.typ) |((has-spec-cell-union q.typ) (has-spec-general-union q.typ)))
912+ =/ nm (hold-name q.typ)
913+ (collection-union typ module sig [[typ nm] seen] context)
795914 =/ named=(unit term) (match-signature q.typ sig)
796915 ?^ named
797916 =/ name u.named
@@ -1230,6 +1349,16 @@
12301349 (crip "explicit-three: {(show-result (sample %explicit-three))}")
12311350 (crip "explicit-unknown: {(show-result (sample %explicit-unknown))}")
12321351 (crip "explicit-nested: {(show-result (sample %explicit-nested))}")
1352+ (crip "collection-union-list: {(show-result (sample %collection-union-list))}")
1353+ (crip "collection-union-set: {(show-result (sample %collection-union-set))}")
1354+ (crip "collection-union-map-key: {(show-result (sample %collection-union-map-key))}")
1355+ (crip "collection-union-map-value: {(show-result (sample %collection-union-map-value))}")
1356+ (crip "collection-union-unit: {(show-result (sample %collection-union-unit))}")
1357+ (crip "collection-union-collapsed: {(show-result (sample %collection-union-collapsed))}")
1358+ (crip "collection-union-multiple: {(show-result (sample %collection-union-multiple))}")
1359+ (crip "collection-union-nested: {(show-result (sample %collection-union-nested))}")
1360+ (crip "collection-union-dependent: {(show-result (sample %collection-union-dependent))}")
1361+ (crip "collection-union-shadow: {(show-result (read-named %shadow %collection-union-shadow xc))}")
12331362 (crip "explicit-list: {(show-result (sample %explicit-list))}")
12341363 (crip "explicit-set: {(show-result (sample %explicit-set))}")
12351364 (crip "explicit-faces: {(show-result (sample %explicit-faces))}")
jibb-dev/lib/jibb.hoon+58−2
@@ -5781,6 +5781,55 @@
57815781 ?^ t.found [%| ["field name is ambiguous in partial inference" ~]]
57825782 $(fields t.fields, typ i.found)
57835783::
5784+:: Propagate a known union through a direct loobean branch. Empty bodies
5785+:: and groups are transparent; bodies with definitions keep their normal
5786+:: scoping and wait for general bidirectional inference.
5787+::
5788+++ context-union-branch
5789+ |= e=expr
5790+ ^- ?
5791+ ?- -.e
5792+ %branch &
5793+ %group $(e inner.e)
5794+ %body ?~(defs.e $(e final.e) |)
5795+ * |
5796+ ==
5797+::
5798+++ infer-union-context
5799+ |= [e=expr expected=itype env=ienv state=istate context=span]
5800+ ^- iresult
5801+ ?: ?=(%group -.e) $(e inner.e)
5802+ ?: &(?=(%body -.e) ?=(~ defs.e)) $(e final.e)
5803+ ?: ?=(%branch -.e)
5804+ ?~ arms.e [%| ["branch is not supported by partial inference" ~]]
5805+ ?~ t.arms.e [%| ["branch pattern is not supported by partial inference" ~]]
5806+ ?^ t.t.arms.e [%| ["branch is not supported by partial inference" ~]]
5807+ =/ x=arm i.arms.e
5808+ =/ y=arm i.t.arms.e
5809+ ?. &(?=(%lit -.pat.x) ?=(%lit -.pat.y))
5810+ [%| ["branch pattern is not supported by partial inference" ~]]
5811+ ?. &(=(%loobean form.lit.pat.x) =(%loobean form.lit.pat.y))
5812+ [%| ["branch pattern is not supported by partial inference" ~]]
5813+ ?: =(val.lit.pat.x val.lit.pat.y)
5814+ [%| ["branch does not cover both loobeans" ~]]
5815+ =/ subject=iresult (infer-fragment subject.e env state)
5816+ ?: ?=(%| -.subject) subject
5817+ =/ su=(unit isub) (itype-unify typ.p.subject [%flag ~] sub.state.p.subject)
5818+ ?~ su [%| ["loobean branch subject does not unify with ?" ~]]
5819+ =/ left=iresult $(e val.x, state state.p.subject(sub u.su))
5820+ ?: ?=(%| -.left) left
5821+ =/ right=iresult $(e val.y, state state.p.left)
5822+ ?: ?=(%| -.right) right
5823+ [%& expected state.p.right]
5824+ =/ value=iresult (infer-fragment e env state)
5825+ ?: ?=(%| -.value) value
5826+ =/ fit=ifit (itype-fit typ.p.value expected sub.state.p.value next.state.p.value)
5827+ ?: ?=(%unknown -.fit)
5828+ [%| ["branch union constraint is not supported by partial inference" ~]]
5829+ ?: ?=(%bad -.fit)
5830+ [%| ["branch arm does not fit its expected union" ~[[context "expected union"] [(span-of e) "branch arm"]]]]
5831+ [%& expected state.p.value(sub sub.fit, next next.fit)]
5832+::
57845833++ infer-fragment
57855834 |= [e=expr env=ienv state=istate]
57865835 ^- iresult
@@ -5881,7 +5930,10 @@
58815930 %cast
58825931 =/ target=(unit [typ=itype state=istate]) (infer-simple-shape shape.e state)
58835932 ?~ target [%| ["cast mold is not supported by partial inference" ~]]
5884− =/ value=iresult $(e val.e, state state.u.target)
5933+ =/ value=iresult
5934+ ?: &(?=(%union -.typ.u.target) (context-union-branch val.e))
5935+ (infer-union-context val.e typ.u.target env state.u.target at.shape.e)
5936+ $(e val.e, state state.u.target)
58855937 ?: ?=(%| -.value) value
58865938 =/ fit=ifit (itype-fit typ.p.value typ.u.target sub.state.p.value next.state.p.value)
58875939 ?: ?=(%unknown -.fit) [%| ["cast constraint is not supported by partial inference" ~]]
@@ -5907,7 +5959,11 @@
59075959 ?^ t.args.e [%| ["multiple arguments are not supported by partial inference" ~]]
59085960 =/ head=iresult $(e head.e)
59095961 ?: ?=(%| -.head) head
5910− =/ arg=iresult $(e i.args.e, state state.p.head)
5962+ =/ head-type=itype (itype-walk typ.p.head sub.state.p.head)
5963+ =/ arg=iresult
5964+ ?: &(?=(%fn -.head-type) ?=(%union -.sample.head-type) (context-union-branch i.args.e))
5965+ (infer-union-context i.args.e sample.head-type env state.p.head (span-of head.e))
5966+ $(e i.args.e, state state.p.head)
59115967 ?: ?=(%| -.arg) arg
59125968 =/ st=istate state.p.arg
59135969 =/ ht=itype (itype-walk typ.p.head sub.st)
jibb-dev/lib/jibb/prelude.jibb+6
@@ -229,3 +229,9 @@
229229 ?- xs
230230 ~ start
231231 [item rest] (combine item (reel rest start combine))
232+
233+++ flit |= predicate=$-(A ?)
234+ |= value=A
235+ ?- (predicate value)
236+ %.y `value
237+ %.n ~
tests/golden/prelude-unit-list-transforms/about.txt+2−2
@@ -1,4 +1,4 @@
1−source: Overview, Prelude: "The exported inventory includes all names from the Hoon library sections listed below, excluding the groups explicitly left out"; Hoon 2a includes `drop`, `bind`, `biff`, `both` and `clef`, and 2b includes `skim`, `skip`, `levy`, `lien`, `roll` and `reel`. Folds take an explicit start.
2−tests: The complete current prelude parses, including unit-to-list conversion, unit mapping and flat mapping, two ways to combine units, complementary list filters, all/any predicates, and left and right folds. The filters retain the order of their selected items.
1+source: Overview, Prelude: "The exported inventory includes all names from the Hoon library sections listed below, excluding the groups explicitly left out"; Hoon 2a includes `drop`, `bind`, `biff`, `flit`, `both` and `clef`, and 2b includes `skim`, `skip`, `levy`, `lien`, `roll` and `reel`. Folds take an explicit start.
2+tests: The complete current prelude parses, including unit-to-list conversion, unit mapping and flat mapping, a curried unit-producing filter, two ways to combine units, complementary list filters, all/any predicates, and left and right folds. The filters retain the order of their selected items.
33expect: parses
44expect-types: a partial inference report, not a checked module; unit and list gate typing is not complete
tests/golden/prelude-unit-list-transforms/source.jibb+6
@@ -229,3 +229,9 @@
229229 ?- xs
230230 ~ start
231231 [item rest] (combine item (reel rest start combine))
232+
233+++ flit |= predicate=$-(A ?)
234+ |= value=A
235+ ?- (predicate value)
236+ %.y `value
237+ %.n ~
tests/golden/prelude-unit-list-transforms/tokens.txt+36−5
@@ -1424,8 +1424,39 @@
14241424231:52 name combine
14251425231:59 tight glyph )
14261426231:60 tight glyph )
1427−231:61 DEDENT
1428−231:61 DEDENT
1429−231:61 DEDENT
1430−231:61 DEDENT
1431−231:61 NEWLINE
1427+233:1 DEDENT
1428+233:1 DEDENT
1429+233:1 DEDENT
1430+233:1 DEDENT
1431+233:1 NEWLINE
1432+233:1 glyph ++
1433+233:4 name flit
1434+233:9 glyph |=
1435+233:12 name predicate
1436+233:21 tight glyph =
1437+233:22 tight glyph $-(
1438+233:25 tight tvar A
1439+233:27 glyph ?
1440+233:28 tight glyph )
1441+234:3 INDENT
1442+234:3 glyph |=
1443+234:6 name value
1444+234:11 tight glyph =
1445+234:12 tight tvar A
1446+235:5 INDENT
1447+235:5 glyph ?-
1448+235:8 glyph (
1449+235:9 tight name predicate
1450+235:19 name value
1451+235:24 tight glyph )
1452+236:7 INDENT
1453+236:7 lit %.y
1454+236:11 glyph `
1455+236:12 tight name value
1456+237:7 NEWLINE
1457+237:7 lit %.n
1458+237:11 lit ~
1459+237:12 DEDENT
1460+237:12 DEDENT
1461+237:12 DEDENT
1462+237:12 NEWLINE
tests/golden/prelude-unit-list-transforms/tree.txt+16−1
@@ -609,4 +609,19 @@
609609 (wing 231:22 combine)
610610 (wing 231:30 item)
611611 (group 231:35
612− (call 231:36 (wing 231:36 reel) (wing 231:41 rest) (wing 231:46 start) (wing 231:52 combine))))))))))))))
612+ (call 231:36 (wing 231:36 reel) (wing 231:41 rest) (wing 231:46 start) (wing 231:52 combine)))))))))))))
613+ (value 233:1 flit
614+ (gate 233:9
615+ (face 233:12 predicate
616+ (fn 233:22 (tvar 233:25 A) (flag 233:27)))
617+ (body 234:3
618+ (gate 234:3
619+ (face 234:6 value (tvar 234:12 A))
620+ (body 235:5
621+ (branch 235:5
622+ (group 235:8
623+ (call 235:9 (wing 235:9 predicate) (wing 235:19 value)))
624+ (arm 236:7
625+ (lit 236:7 %.y)
626+ (unit 236:11 (wing 236:12 value)))
627+ (arm 237:7 (lit 237:7 %.n) (lit 237:11 ~)))))))))
tests/golden/prelude-unit-list-transforms/types.txt+1
@@ -50,3 +50,4 @@ partial inference; module not checked
5050++ lien: sample mold is not supported by partial inference
5151++ roll: sample mold is not supported by partial inference
5252++ reel: sample mold is not supported by partial inference
53+++ flit: expression is not supported by partial inference
tests/golden/types-union-branch-context/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Tag resolution: "tags take their union from context"; Patterns: "An arm that earlier arms cover ... is an error."
2+tests: An explicit union cast or known sample supplies branch result context, including tagged records, nested and grouped branches; invalid tags, duplicate patterns and unsupported subjects are reported without claiming a complete check.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/types-union-branch-context/source.jibbnew file+54
@@ -0,0 +1,54 @@
1++$ msg
2+ %add
3+ %remove
4+ [%noted text=@t]
5+++ choose |= b=?
6+ ^- msg
7+ ?- b
8+ %.y %add
9+ %.n %remove
10+++ records |= b=?
11+ ^- msg
12+ ?- b
13+ %.y [%noted "hi"]
14+ %.n %add
15+++ bad |= b=?
16+ ^- msg
17+ ?- b
18+ %.y %add
19+ %.n %missing
20+++ bad-first |= b=?
21+ ^- msg
22+ ?- b
23+ %.y %missing
24+ %.n %remove
25+++ nested |= b=?
26+ ^- msg
27+ ?- b
28+ %.y
29+ ?- b
30+ %.y %add
31+ %.n %remove
32+ %.n %remove
33+++ grouped |= b=?
34+ ^- msg
35+ (
36+ ?- b
37+ %.y %add
38+ %.n %remove
39+++ consume |= x=msg "ok"
40+++ call |= b=?
41+ (consume
42+ ?- b
43+ %.y %add
44+ %.n %remove
45+++ repeated |= b=?
46+ ^- msg
47+ ?- b
48+ %.y %add
49+ %.y %remove
50+++ non-loobean |= x=@t
51+ ^- msg
52+ ?- x
53+ "a" %add
54+ * %remove
tests/golden/types-union-branch-context/tokens.txtnew file+237
@@ -0,0 +1,237 @@
1+1:1 glyph +$
2+1:4 name msg
3+2:3 INDENT
4+2:3 lit %add
5+3:3 NEWLINE
6+3:3 lit %remove
7+4:3 NEWLINE
8+4:3 glyph [
9+4:4 tight lit %noted
10+4:11 name text
11+4:15 tight glyph =
12+4:16 tight aura @t
13+4:18 tight glyph ]
14+5:1 DEDENT
15+5:1 NEWLINE
16+5:1 glyph ++
17+5:4 name choose
18+5:11 glyph |=
19+5:14 name b
20+5:15 tight glyph =
21+5:16 tight glyph ?
22+6:3 INDENT
23+6:3 glyph ^-
24+6:6 name msg
25+7:5 INDENT
26+7:5 glyph ?-
27+7:8 name b
28+8:7 INDENT
29+8:7 lit %.y
30+8:11 lit %add
31+9:7 NEWLINE
32+9:7 lit %.n
33+9:11 lit %remove
34+10:1 DEDENT
35+10:1 DEDENT
36+10:1 DEDENT
37+10:1 NEWLINE
38+10:1 glyph ++
39+10:4 name records
40+10:12 glyph |=
41+10:15 name b
42+10:16 tight glyph =
43+10:17 tight glyph ?
44+11:3 INDENT
45+11:3 glyph ^-
46+11:6 name msg
47+12:5 INDENT
48+12:5 glyph ?-
49+12:8 name b
50+13:7 INDENT
51+13:7 lit %.y
52+13:11 glyph [
53+13:12 tight lit %noted
54+13:19 str "hi"
55+13:23 tight glyph ]
56+14:7 NEWLINE
57+14:7 lit %.n
58+14:11 lit %add
59+15:1 DEDENT
60+15:1 DEDENT
61+15:1 DEDENT
62+15:1 NEWLINE
63+15:1 glyph ++
64+15:4 name bad
65+15:8 glyph |=
66+15:11 name b
67+15:12 tight glyph =
68+15:13 tight glyph ?
69+16:3 INDENT
70+16:3 glyph ^-
71+16:6 name msg
72+17:5 INDENT
73+17:5 glyph ?-
74+17:8 name b
75+18:7 INDENT
76+18:7 lit %.y
77+18:11 lit %add
78+19:7 NEWLINE
79+19:7 lit %.n
80+19:11 lit %missing
81+20:1 DEDENT
82+20:1 DEDENT
83+20:1 DEDENT
84+20:1 NEWLINE
85+20:1 glyph ++
86+20:4 name bad-first
87+20:14 glyph |=
88+20:17 name b
89+20:18 tight glyph =
90+20:19 tight glyph ?
91+21:3 INDENT
92+21:3 glyph ^-
93+21:6 name msg
94+22:5 INDENT
95+22:5 glyph ?-
96+22:8 name b
97+23:7 INDENT
98+23:7 lit %.y
99+23:11 lit %missing
100+24:7 NEWLINE
101+24:7 lit %.n
102+24:11 lit %remove
103+25:1 DEDENT
104+25:1 DEDENT
105+25:1 DEDENT
106+25:1 NEWLINE
107+25:1 glyph ++
108+25:4 name nested
109+25:11 glyph |=
110+25:14 name b
111+25:15 tight glyph =
112+25:16 tight glyph ?
113+26:3 INDENT
114+26:3 glyph ^-
115+26:6 name msg
116+27:5 INDENT
117+27:5 glyph ?-
118+27:8 name b
119+28:7 INDENT
120+28:7 lit %.y
121+29:9 INDENT
122+29:9 glyph ?-
123+29:12 name b
124+30:11 INDENT
125+30:11 lit %.y
126+30:15 lit %add
127+31:11 NEWLINE
128+31:11 lit %.n
129+31:15 lit %remove
130+32:7 DEDENT
131+32:7 DEDENT
132+32:7 NEWLINE
133+32:7 lit %.n
134+32:11 lit %remove
135+33:1 DEDENT
136+33:1 DEDENT
137+33:1 DEDENT
138+33:1 NEWLINE
139+33:1 glyph ++
140+33:4 name grouped
141+33:12 glyph |=
142+33:15 name b
143+33:16 tight glyph =
144+33:17 tight glyph ?
145+34:3 INDENT
146+34:3 glyph ^-
147+34:6 name msg
148+35:5 INDENT
149+35:5 glyph (
150+36:7 INDENT
151+36:7 glyph ?-
152+36:10 name b
153+37:9 INDENT
154+37:9 lit %.y
155+37:13 lit %add
156+38:9 NEWLINE
157+38:9 lit %.n
158+38:13 lit %remove
159+39:1 DEDENT
160+39:1 DEDENT
161+39:1 DEDENT
162+39:1 DEDENT
163+39:1 NEWLINE
164+39:1 glyph ++
165+39:4 name consume
166+39:12 glyph |=
167+39:15 name x
168+39:16 tight glyph =
169+39:17 tight name msg
170+39:21 str "ok"
171+40:1 NEWLINE
172+40:1 glyph ++
173+40:4 name call
174+40:9 glyph |=
175+40:12 name b
176+40:13 tight glyph =
177+40:14 tight glyph ?
178+41:3 INDENT
179+41:3 glyph (
180+41:4 tight name consume
181+42:5 INDENT
182+42:5 glyph ?-
183+42:8 name b
184+43:7 INDENT
185+43:7 lit %.y
186+43:11 lit %add
187+44:7 NEWLINE
188+44:7 lit %.n
189+44:11 lit %remove
190+45:1 DEDENT
191+45:1 DEDENT
192+45:1 DEDENT
193+45:1 NEWLINE
194+45:1 glyph ++
195+45:4 name repeated
196+45:13 glyph |=
197+45:16 name b
198+45:17 tight glyph =
199+45:18 tight glyph ?
200+46:3 INDENT
201+46:3 glyph ^-
202+46:6 name msg
203+47:5 INDENT
204+47:5 glyph ?-
205+47:8 name b
206+48:7 INDENT
207+48:7 lit %.y
208+48:11 lit %add
209+49:7 NEWLINE
210+49:7 lit %.y
211+49:11 lit %remove
212+50:1 DEDENT
213+50:1 DEDENT
214+50:1 DEDENT
215+50:1 NEWLINE
216+50:1 glyph ++
217+50:4 name non-loobean
218+50:16 glyph |=
219+50:19 name x
220+50:20 tight glyph =
221+50:21 tight aura @t
222+51:3 INDENT
223+51:3 glyph ^-
224+51:6 name msg
225+52:5 INDENT
226+52:5 glyph ?-
227+52:8 name x
228+53:7 INDENT
229+53:7 str "a"
230+53:11 lit %add
231+54:7 NEWLINE
232+54:7 glyph *
233+54:9 lit %remove
234+54:16 DEDENT
235+54:16 DEDENT
236+54:16 DEDENT
237+54:16 NEWLINE
tests/golden/types-union-branch-context/tree.txtnew file+120
@@ -0,0 +1,120 @@
1+(module
2+ (mold 1:1 msg
3+ (union 2:3
4+ (const 2:3 %add)
5+ (const 3:3 %remove)
6+ (cell 4:3
7+ (const 4:4 %noted)
8+ (face 4:11 text (aura 4:16 @t)))))
9+ (value 5:1 choose
10+ (gate 5:11
11+ (face 5:14 b (flag 5:16))
12+ (body 6:3
13+ (cast 6:3
14+ (ref 6:6 msg)
15+ (body 7:5
16+ (branch 7:5
17+ (wing 7:8 b)
18+ (arm 8:7 (lit 8:7 %.y) (lit 8:11 %add))
19+ (arm 9:7 (lit 9:7 %.n) (lit 9:11 %remove))))))))
20+ (value 10:1 records
21+ (gate 10:12
22+ (face 10:15 b (flag 10:17))
23+ (body 11:3
24+ (cast 11:3
25+ (ref 11:6 msg)
26+ (body 12:5
27+ (branch 12:5
28+ (wing 12:8 b)
29+ (arm 13:7
30+ (lit 13:7 %.y)
31+ (tuple 13:11 (lit 13:12 %noted) (str 13:19 "hi")))
32+ (arm 14:7 (lit 14:7 %.n) (lit 14:11 %add))))))))
33+ (value 15:1 bad
34+ (gate 15:8
35+ (face 15:11 b (flag 15:13))
36+ (body 16:3
37+ (cast 16:3
38+ (ref 16:6 msg)
39+ (body 17:5
40+ (branch 17:5
41+ (wing 17:8 b)
42+ (arm 18:7 (lit 18:7 %.y) (lit 18:11 %add))
43+ (arm 19:7 (lit 19:7 %.n) (lit 19:11 %missing))))))))
44+ (value 20:1 bad-first
45+ (gate 20:14
46+ (face 20:17 b (flag 20:19))
47+ (body 21:3
48+ (cast 21:3
49+ (ref 21:6 msg)
50+ (body 22:5
51+ (branch 22:5
52+ (wing 22:8 b)
53+ (arm 23:7 (lit 23:7 %.y) (lit 23:11 %missing))
54+ (arm 24:7 (lit 24:7 %.n) (lit 24:11 %remove))))))))
55+ (value 25:1 nested
56+ (gate 25:11
57+ (face 25:14 b (flag 25:16))
58+ (body 26:3
59+ (cast 26:3
60+ (ref 26:6 msg)
61+ (body 27:5
62+ (branch 27:5
63+ (wing 27:8 b)
64+ (arm 28:7
65+ (lit 28:7 %.y)
66+ (body 29:9
67+ (branch 29:9
68+ (wing 29:12 b)
69+ (arm 30:11 (lit 30:11 %.y) (lit 30:15 %add))
70+ (arm 31:11 (lit 31:11 %.n) (lit 31:15 %remove)))))
71+ (arm 32:7 (lit 32:7 %.n) (lit 32:11 %remove))))))))
72+ (value 33:1 grouped
73+ (gate 33:12
74+ (face 33:15 b (flag 33:17))
75+ (body 34:3
76+ (cast 34:3
77+ (ref 34:6 msg)
78+ (body 35:5
79+ (group 35:5
80+ (branch 36:7
81+ (wing 36:10 b)
82+ (arm 37:9 (lit 37:9 %.y) (lit 37:13 %add))
83+ (arm 38:9 (lit 38:9 %.n) (lit 38:13 %remove)))))))))
84+ (value 39:1 consume
85+ (gate 39:12
86+ (face 39:15 x (ref 39:17 msg))
87+ (str 39:21 "ok")))
88+ (value 40:1 call
89+ (gate 40:9
90+ (face 40:12 b (flag 40:14))
91+ (body 41:3
92+ (group 41:3
93+ (call 41:4
94+ (wing 41:4 consume)
95+ (branch 42:5
96+ (wing 42:8 b)
97+ (arm 43:7 (lit 43:7 %.y) (lit 43:11 %add))
98+ (arm 44:7 (lit 44:7 %.n) (lit 44:11 %remove))))))))
99+ (value 45:1 repeated
100+ (gate 45:13
101+ (face 45:16 b (flag 45:18))
102+ (body 46:3
103+ (cast 46:3
104+ (ref 46:6 msg)
105+ (body 47:5
106+ (branch 47:5
107+ (wing 47:8 b)
108+ (arm 48:7 (lit 48:7 %.y) (lit 48:11 %add))
109+ (arm 49:7 (lit 49:7 %.y) (lit 49:11 %remove))))))))
110+ (value 50:1 non-loobean
111+ (gate 50:16
112+ (face 50:19 x (aura 50:21 @t))
113+ (body 51:3
114+ (cast 51:3
115+ (ref 51:6 msg)
116+ (body 52:5
117+ (branch 52:5
118+ (wing 52:8 x)
119+ (arm 53:7 (str 53:7 "a") (lit 53:11 %add))
120+ (arm 54:7 (any 54:7) (lit 54:9 %remove)))))))))
tests/golden/types-union-branch-context/types.txtnew file+24
@@ -0,0 +1,24 @@
1+partial inference; module not checked
2++$ msg: cases proven disjoint; mold not checked
3+++ choose: $-(? msg)
4+++ records: $-(? msg)
5+++ bad: branch arm does not fit its expected union
6+/tests/golden/types-union-branch-context/source.jibb:16:6: expected union
7+ ^- msg
8+ ^
9+/tests/golden/types-union-branch-context/source.jibb:19:11: branch arm
10+ %.n %missing
11+ ^
12+++ bad-first: branch arm does not fit its expected union
13+/tests/golden/types-union-branch-context/source.jibb:21:6: expected union
14+ ^- msg
15+ ^
16+/tests/golden/types-union-branch-context/source.jibb:23:11: branch arm
17+ %.y %missing
18+ ^
19+++ nested: $-(? msg)
20+++ grouped: $-(? msg)
21+++ consume: $-(msg @t)
22+++ call: $-(? @t)
23+++ repeated: branch does not cover both loobeans
24+++ non-loobean: branch pattern is not supported by partial inference
tests/golden/types-union-branch-pending/about.txtnew file+4
@@ -0,0 +1,4 @@
1+source: Grammar, Tag resolution: "A constrained variable, and any it mentions, doesn't generalize" and "A constraint still open when its module is checked is an error asking for a `^-`; the checker never guesses."
2+tests: Tags lacking context remain unresolved in branches and ignored traces even when another tag has union context.
3+expect: parses
4+expect-types: a partial inference report
tests/golden/types-union-branch-pending/source.jibbnew file+24
@@ -0,0 +1,24 @@
1++$ msg
2+ %add
3+ %remove
4+++ unresolved |= b=?
5+ ?- b
6+ %.y %add
7+ %.n %remove
8+++ discarded |= b=?
9+ ~& %unknown
10+ ^- msg
11+ ?- b
12+ %.y %add
13+ %.n %remove
14+++ one-open |= b=?
15+ ~& ^- msg %add
16+ ?- b
17+ %.y %add
18+ %.n %unknown
19+++ local-pending |= b=?
20+ ++ ignored %unknown
21+ ^- msg
22+ ?- b
23+ %.y %add
24+ %.n %remove
tests/golden/types-union-branch-pending/tokens.txtnew file+102
@@ -0,0 +1,102 @@
1+1:1 glyph +$
2+1:4 name msg
3+2:3 INDENT
4+2:3 lit %add
5+3:3 NEWLINE
6+3:3 lit %remove
7+4:1 DEDENT
8+4:1 NEWLINE
9+4:1 glyph ++
10+4:4 name unresolved
11+4:15 glyph |=
12+4:18 name b
13+4:19 tight glyph =
14+4:20 tight glyph ?
15+5:3 INDENT
16+5:3 glyph ?-
17+5:6 name b
18+6:5 INDENT
19+6:5 lit %.y
20+6:9 lit %add
21+7:5 NEWLINE
22+7:5 lit %.n
23+7:9 lit %remove
24+8:1 DEDENT
25+8:1 DEDENT
26+8:1 NEWLINE
27+8:1 glyph ++
28+8:4 name discarded
29+8:14 glyph |=
30+8:17 name b
31+8:18 tight glyph =
32+8:19 tight glyph ?
33+9:3 INDENT
34+9:3 glyph ~&
35+9:6 lit %unknown
36+10:5 INDENT
37+10:5 glyph ^-
38+10:8 name msg
39+11:7 INDENT
40+11:7 glyph ?-
41+11:10 name b
42+12:9 INDENT
43+12:9 lit %.y
44+12:13 lit %add
45+13:9 NEWLINE
46+13:9 lit %.n
47+13:13 lit %remove
48+14:1 DEDENT
49+14:1 DEDENT
50+14:1 DEDENT
51+14:1 DEDENT
52+14:1 NEWLINE
53+14:1 glyph ++
54+14:4 name one-open
55+14:13 glyph |=
56+14:16 name b
57+14:17 tight glyph =
58+14:18 tight glyph ?
59+15:3 INDENT
60+15:3 glyph ~&
61+15:6 glyph ^-
62+15:9 name msg
63+15:13 lit %add
64+16:5 INDENT
65+16:5 glyph ?-
66+16:8 name b
67+17:7 INDENT
68+17:7 lit %.y
69+17:11 lit %add
70+18:7 NEWLINE
71+18:7 lit %.n
72+18:11 lit %unknown
73+19:1 DEDENT
74+19:1 DEDENT
75+19:1 DEDENT
76+19:1 NEWLINE
77+19:1 glyph ++
78+19:4 name local-pending
79+19:18 glyph |=
80+19:21 name b
81+19:22 tight glyph =
82+19:23 tight glyph ?
83+20:3 INDENT
84+20:3 glyph ++
85+20:6 name ignored
86+20:14 lit %unknown
87+21:3 NEWLINE
88+21:3 glyph ^-
89+21:6 name msg
90+22:5 INDENT
91+22:5 glyph ?-
92+22:8 name b
93+23:7 INDENT
94+23:7 lit %.y
95+23:11 lit %add
96+24:7 NEWLINE
97+24:7 lit %.n
98+24:11 lit %remove
99+24:18 DEDENT
100+24:18 DEDENT
101+24:18 DEDENT
102+24:18 NEWLINE
tests/golden/types-union-branch-pending/tree.txtnew file+48
@@ -0,0 +1,48 @@
1+(module
2+ (mold 1:1 msg
3+ (union 2:3 (const 2:3 %add) (const 3:3 %remove)))
4+ (value 4:1 unresolved
5+ (gate 4:15
6+ (face 4:18 b (flag 4:20))
7+ (body 5:3
8+ (branch 5:3
9+ (wing 5:6 b)
10+ (arm 6:5 (lit 6:5 %.y) (lit 6:9 %add))
11+ (arm 7:5 (lit 7:5 %.n) (lit 7:9 %remove))))))
12+ (value 8:1 discarded
13+ (gate 8:14
14+ (face 8:17 b (flag 8:19))
15+ (body 9:3
16+ (trace 9:3
17+ (lit 9:6 %unknown)
18+ (body 10:5
19+ (cast 10:5
20+ (ref 10:8 msg)
21+ (body 11:7
22+ (branch 11:7
23+ (wing 11:10 b)
24+ (arm 12:9 (lit 12:9 %.y) (lit 12:13 %add))
25+ (arm 13:9 (lit 13:9 %.n) (lit 13:13 %remove))))))))))
26+ (value 14:1 one-open
27+ (gate 14:13
28+ (face 14:16 b (flag 14:18))
29+ (body 15:3
30+ (trace 15:3
31+ (cast 15:6 (ref 15:9 msg) (lit 15:13 %add))
32+ (body 16:5
33+ (branch 16:5
34+ (wing 16:8 b)
35+ (arm 17:7 (lit 17:7 %.y) (lit 17:11 %add))
36+ (arm 18:7 (lit 18:7 %.n) (lit 18:11 %unknown))))))))
37+ (value 19:1 local-pending
38+ (gate 19:18
39+ (face 19:21 b (flag 19:23))
40+ (body 20:3
41+ (value 20:3 ignored (lit 20:14 %unknown))
42+ (cast 21:3
43+ (ref 21:6 msg)
44+ (body 22:5
45+ (branch 22:5
46+ (wing 22:8 b)
47+ (arm 23:7 (lit 23:7 %.y) (lit 23:11 %add))
48+ (arm 24:7 (lit 24:7 %.n) (lit 24:11 %remove)))))))))
tests/golden/types-union-branch-pending/types.txtnew file+6
@@ -0,0 +1,6 @@
1+partial inference; module not checked
2++$ msg: cases proven disjoint; mold not checked
3+++ unresolved: branch tag or union context is not supported by partial inference
4+++ discarded: tag needs context in partial inference
5+++ one-open: branch tag or union context is not supported by partial inference
6+++ local-pending: local definitions need unsupported inference
tests/golden/types-union-context-flow/types.txt+1−1
@@ -1,6 +1,6 @@
11partial inference; module not checked
22+$ msg: cases proven disjoint; mold not checked
33++ only-one: tag needs context in partial inference
4−++ choose: branch tag or union context is not supported by partial inference
4+++ choose: $-(? msg)
55++ id: $-(A A)
66++ through: msg
tests/importer/about.txt+7−3
@@ -4,9 +4,13 @@ shadowing and missing provenance. `shadow-static.txt` checks that a local
44list shadow alongside a nested ordered map is rejected. Static sibling
55collections and dependent sibling molds are tested separately. Explicit Hoon `$%`, `$?` and `$^` unions are checked from source where
66their branches are static, including cases Hoon would collapse. Materialized
7−forks are checked too. Named or validated branches, multiple nested unions,
8−and explicit unions in collection arguments fail closed; nested `$@` cases
9−remain supported. The provisional reading is recorded in doc question 22. `ford.txt`
7+forks are checked too. A standard list, set, map or unit can have one direct
8+explicit union argument when the exact call wrapper and collection provenance
9+are validated and all union cases are static and pairwise disjoint. Cases
10+cover overlap, collapsed branches, multiple or nested unions, dependent
11+branches and a shadowed collection. A direct forged-wrapper regression
12+still needs a test that compiles in practical time. Unsupported forms fail
13+closed; nested `$@` cases remain supported. The provisional reading is recorded in doc question 22. `ford.txt`
1014checks a synthetic imported subject and selected mold; other cases check
1115transitive imports, named mold lookup, missing names, shadowing, unprovenanced
1216recursive holds, malformed
tests/importer/shadow-static.txt+1
@@ -3,4 +3,5 @@
33++ path path:..zuse
44+$ path-shadow [?(%fil %dir) pa=path nam=@t]
55+$ bad [a=((mop @ud @t) lte) b=(list @ud)]
6++$ collection-union-shadow (list $?([%x @ud] [%y @t]))
67--
tests/importer/small.txt+9
@@ -66,4 +66,13 @@
6666+$ nested-invalid-cell [id=@ud value=$^(@ud @ud)]
6767+$ valid-cell $^(@ud [x=@ud y=@ud])
6868+$ invalid-cell $^(@ud @ud)
69++$ collection-union-list (list $?([%x @ud] [%y @t]))
70++$ collection-union-set (set $%([%x @ud] [%y @t]))
71++$ collection-union-map-key (map $?([%x @ud] [%y @t]) (list @ud))
72++$ collection-union-map-value (map (list @ud) $^(@ud [x=@ud y=@t]))
73++$ collection-union-unit (unit $?(%x %y %z))
74++$ collection-union-collapsed (list $?([%x @ud] [%x @ud]))
75++$ collection-union-multiple (map $?([%x @ud] [%y @t]) $?([%a @ud] [%b @t]))
76++$ collection-union-nested (list [id=@ud value=$?([%x @ud] [%y @t])])
77++$ collection-union-dependent (list $?(action [%x @t]))
6978--
tests/importer/tree.txt+14−4
@@ -60,8 +60,18 @@ explicit-subsumed: error: a Hoon union has overlapping cases
6060explicit-three: (union [a @ud] [b @t] [c @p])
6161explicit-unknown: error: a Hoon union needs a source-level disjointness check
6262explicit-nested: error: a Hoon union has overlapping cases
63−explicit-list: error: a Hoon union needs a source-level disjointness check
64−explicit-set: error: a Hoon union needs a source-level disjointness check
63+collection-union-list: (list (union [x @ud] [y @t]))
64+collection-union-set: (set (union [x @ud] [y @t]))
65+collection-union-map-key: (map (union [x @ud] [y @t]) (list @ud))
66+collection-union-map-value: (map (list @ud) (union [x=@ud y=@t] @ud))
67+collection-union-unit: (unit (union x y z))
68+collection-union-collapsed: error: a Hoon union has overlapping cases
69+collection-union-multiple: error: a Hoon union needs a source-level disjointness check
70+collection-union-nested: error: a Hoon union needs a source-level disjointness check
71+collection-union-dependent: error: a Hoon union needs a source-level disjointness check
72+collection-union-shadow: error: Hoon collection provenance is unavailable or shadowed
73+explicit-list: error: a Hoon union has overlapping cases
74+explicit-set: error: a Hoon union has overlapping cases
6575explicit-faces: (list [bcwt=@t bccn=@ud])
6676explicit-alias: error: a Hoon union has overlapping cases
6777explicit-ford: error: a Hoon union has overlapping cases
@@ -73,8 +83,8 @@ list-nested-atom-cell: (list [id=@ud value=(union [a=@ud b=@t] @ud)])
7383list-nested-valid-cell: error: a Hoon $^ union needs a source-level disjointness check
7484list-nested-invalid-cell: error: a Hoon $^ union needs a source-level disjointness check
7585map-nested-invalid-cell: error: a Hoon $^ union needs a source-level disjointness check
76−set-direct-invalid-cell: error: a Hoon $^ union needs a source-level disjointness check
77−map-key-invalid-cell: error: a Hoon $^ union needs a source-level disjointness check
86+set-direct-invalid-cell: error: a Hoon $^ union has overlapping cases
87+map-key-invalid-cell: error: a Hoon $^ union has overlapping cases
7888nested-atom-cell: [left=(union [a=@ud b=@t] @ud) right=(union [c=@ud d=@t] @t)]
7989nested-tags: [id=@ud value=(union foo bar)]
8090nested-tags-overlap: error: a Hoon $^ union has overlapping cases
tests/lib/jibb.hoon+120−108
@@ -1566,95 +1566,103 @@
15661566/* tok-460 %txt /tests/golden/types-union-alias/tokens/txt
15671567/* tre-460 %txt /tests/golden/types-union-alias/tree/txt
15681568/* typ-460 %txt /tests/golden/types-union-alias/types/txt
1569−/* src-461 %jibb /tests/golden/types-union-constructor-shape/source/jibb
1570−/* tok-461 %txt /tests/golden/types-union-constructor-shape/tokens/txt
1571−/* tre-461 %txt /tests/golden/types-union-constructor-shape/tree/txt
1572−/* typ-461 %txt /tests/golden/types-union-constructor-shape/types/txt
1573−/* src-462 %jibb /tests/golden/types-union-context-flow/source/jibb
1574−/* tok-462 %txt /tests/golden/types-union-context-flow/tokens/txt
1575−/* tre-462 %txt /tests/golden/types-union-context-flow/tree/txt
1576−/* typ-462 %txt /tests/golden/types-union-context-flow/types/txt
1577−/* src-463 %jibb /tests/golden/types-union-import/source/jibb
1578−/* tok-463 %txt /tests/golden/types-union-import/tokens/txt
1579−/* tre-463 %txt /tests/golden/types-union-import/tree/txt
1580−/* mod-463-1 %jibb /tests/golden/types-union-import/modules/ui/lib/jibb
1581−/* typ-463 %txt /tests/golden/types-union-import/types/txt
1582−/* mtre-463 %txt /tests/golden/types-union-import/module-trees/txt
1583−/* src-464 %jibb /tests/golden/types-union-local-pending/source/jibb
1584−/* tok-464 %txt /tests/golden/types-union-local-pending/tokens/txt
1585−/* tre-464 %txt /tests/golden/types-union-local-pending/tree/txt
1586−/* typ-464 %txt /tests/golden/types-union-local-pending/types/txt
1587−/* src-465 %jibb /tests/golden/types-union-overlap/source/jibb
1588−/* tok-465 %txt /tests/golden/types-union-overlap/tokens/txt
1589−/* tre-465 %txt /tests/golden/types-union-overlap/tree/txt
1590−/* typ-465 %txt /tests/golden/types-union-overlap/types/txt
1591−/* src-466 %jibb /tests/golden/types-union-overlap-nested/source/jibb
1592−/* tok-466 %txt /tests/golden/types-union-overlap-nested/tokens/txt
1593−/* tre-466 %txt /tests/golden/types-union-overlap-nested/tree/txt
1594−/* typ-466 %txt /tests/golden/types-union-overlap-nested/types/txt
1595−/* src-467 %jibb /tests/golden/types-union-phantom-generic/source/jibb
1596−/* tok-467 %txt /tests/golden/types-union-phantom-generic/tokens/txt
1597−/* tre-467 %txt /tests/golden/types-union-phantom-generic/tree/txt
1598−/* typ-467 %txt /tests/golden/types-union-phantom-generic/types/txt
1599−/* src-468 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
1600−/* tok-468 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
1601−/* tre-468 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
1602−/* mod-468-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
1603−/* typ-468 %txt /tests/golden/types-union-print-cross-namespace/types/txt
1604−/* mtre-468 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
1605−/* src-469 %jibb /tests/golden/types-union-print-distinct/source/jibb
1606−/* tok-469 %txt /tests/golden/types-union-print-distinct/tokens/txt
1607−/* tre-469 %txt /tests/golden/types-union-print-distinct/tree/txt
1608−/* mod-469-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
1609−/* mod-469-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
1610−/* mod-469-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
1611−/* typ-469 %txt /tests/golden/types-union-print-distinct/types/txt
1612−/* mtre-469 %txt /tests/golden/types-union-print-distinct/module-trees/txt
1613−/* src-470 %jibb /tests/golden/types-union-print-escape/source/jibb
1614−/* tok-470 %txt /tests/golden/types-union-print-escape/tokens/txt
1615−/* tre-470 %txt /tests/golden/types-union-print-escape/tree/txt
1616−/* typ-470 %txt /tests/golden/types-union-print-escape/types/txt
1617−/* src-471 %jibb /tests/golden/types-union-print-local/source/jibb
1618−/* tok-471 %txt /tests/golden/types-union-print-local/tokens/txt
1619−/* tre-471 %txt /tests/golden/types-union-print-local/tree/txt
1620−/* typ-471 %txt /tests/golden/types-union-print-local/types/txt
1621−/* src-472 %jibb /tests/golden/types-union-print-nested/source/jibb
1622−/* tok-472 %txt /tests/golden/types-union-print-nested/tokens/txt
1623−/* tre-472 %txt /tests/golden/types-union-print-nested/tree/txt
1624−/* typ-472 %txt /tests/golden/types-union-print-nested/types/txt
1625−/* src-473 %jibb /tests/golden/types-union-print-same-origin/source/jibb
1626−/* tok-473 %txt /tests/golden/types-union-print-same-origin/tokens/txt
1627−/* tre-473 %txt /tests/golden/types-union-print-same-origin/tree/txt
1628−/* mod-473-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
1629−/* typ-473 %txt /tests/golden/types-union-print-same-origin/types/txt
1630−/* mtre-473 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
1631−/* src-474 %jibb /tests/golden/types-union-print-transitive/source/jibb
1632−/* tok-474 %txt /tests/golden/types-union-print-transitive/tokens/txt
1633−/* tre-474 %txt /tests/golden/types-union-print-transitive/tree/txt
1634−/* mod-474-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
1635−/* mod-474-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
1636−/* typ-474 %txt /tests/golden/types-union-print-transitive/types/txt
1637−/* mtre-474 %txt /tests/golden/types-union-print-transitive/module-trees/txt
1638−/* src-475 %jibb /tests/golden/types-union-singleton/source/jibb
1639−/* tok-475 %txt /tests/golden/types-union-singleton/tokens/txt
1640−/* tre-475 %txt /tests/golden/types-union-singleton/tree/txt
1641−/* typ-475 %txt /tests/golden/types-union-singleton/types/txt
1642−/* src-476 %jibb /tests/golden/types-union-tag-atoms/source/jibb
1643−/* tok-476 %txt /tests/golden/types-union-tag-atoms/tokens/txt
1644−/* tre-476 %txt /tests/golden/types-union-tag-atoms/tree/txt
1645−/* typ-476 %txt /tests/golden/types-union-tag-atoms/types/txt
1646−/* src-477 %jibb /tests/golden/types-union-tags/source/jibb
1647−/* tok-477 %txt /tests/golden/types-union-tags/tokens/txt
1648−/* tre-477 %txt /tests/golden/types-union-tags/tree/txt
1649−/* typ-477 %txt /tests/golden/types-union-tags/types/txt
1650−/* src-478 %jibb /tests/golden/types-union-unresolved/source/jibb
1651−/* tok-478 %txt /tests/golden/types-union-unresolved/tokens/txt
1652−/* tre-478 %txt /tests/golden/types-union-unresolved/tree/txt
1653−/* typ-478 %txt /tests/golden/types-union-unresolved/types/txt
1654−/* src-479 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
1655−/* tok-479 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
1656−/* tre-479 %txt /tests/golden/types-union-unresolved-flow/tree/txt
1657−/* typ-479 %txt /tests/golden/types-union-unresolved-flow/types/txt
1569+/* src-461 %jibb /tests/golden/types-union-branch-context/source/jibb
1570+/* tok-461 %txt /tests/golden/types-union-branch-context/tokens/txt
1571+/* tre-461 %txt /tests/golden/types-union-branch-context/tree/txt
1572+/* typ-461 %txt /tests/golden/types-union-branch-context/types/txt
1573+/* src-462 %jibb /tests/golden/types-union-branch-pending/source/jibb
1574+/* tok-462 %txt /tests/golden/types-union-branch-pending/tokens/txt
1575+/* tre-462 %txt /tests/golden/types-union-branch-pending/tree/txt
1576+/* typ-462 %txt /tests/golden/types-union-branch-pending/types/txt
1577+/* src-463 %jibb /tests/golden/types-union-constructor-shape/source/jibb
1578+/* tok-463 %txt /tests/golden/types-union-constructor-shape/tokens/txt
1579+/* tre-463 %txt /tests/golden/types-union-constructor-shape/tree/txt
1580+/* typ-463 %txt /tests/golden/types-union-constructor-shape/types/txt
1581+/* src-464 %jibb /tests/golden/types-union-context-flow/source/jibb
1582+/* tok-464 %txt /tests/golden/types-union-context-flow/tokens/txt
1583+/* tre-464 %txt /tests/golden/types-union-context-flow/tree/txt
1584+/* typ-464 %txt /tests/golden/types-union-context-flow/types/txt
1585+/* src-465 %jibb /tests/golden/types-union-import/source/jibb
1586+/* tok-465 %txt /tests/golden/types-union-import/tokens/txt
1587+/* tre-465 %txt /tests/golden/types-union-import/tree/txt
1588+/* mod-465-1 %jibb /tests/golden/types-union-import/modules/ui/lib/jibb
1589+/* typ-465 %txt /tests/golden/types-union-import/types/txt
1590+/* mtre-465 %txt /tests/golden/types-union-import/module-trees/txt
1591+/* src-466 %jibb /tests/golden/types-union-local-pending/source/jibb
1592+/* tok-466 %txt /tests/golden/types-union-local-pending/tokens/txt
1593+/* tre-466 %txt /tests/golden/types-union-local-pending/tree/txt
1594+/* typ-466 %txt /tests/golden/types-union-local-pending/types/txt
1595+/* src-467 %jibb /tests/golden/types-union-overlap/source/jibb
1596+/* tok-467 %txt /tests/golden/types-union-overlap/tokens/txt
1597+/* tre-467 %txt /tests/golden/types-union-overlap/tree/txt
1598+/* typ-467 %txt /tests/golden/types-union-overlap/types/txt
1599+/* src-468 %jibb /tests/golden/types-union-overlap-nested/source/jibb
1600+/* tok-468 %txt /tests/golden/types-union-overlap-nested/tokens/txt
1601+/* tre-468 %txt /tests/golden/types-union-overlap-nested/tree/txt
1602+/* typ-468 %txt /tests/golden/types-union-overlap-nested/types/txt
1603+/* src-469 %jibb /tests/golden/types-union-phantom-generic/source/jibb
1604+/* tok-469 %txt /tests/golden/types-union-phantom-generic/tokens/txt
1605+/* tre-469 %txt /tests/golden/types-union-phantom-generic/tree/txt
1606+/* typ-469 %txt /tests/golden/types-union-phantom-generic/types/txt
1607+/* src-470 %jibb /tests/golden/types-union-print-cross-namespace/source/jibb
1608+/* tok-470 %txt /tests/golden/types-union-print-cross-namespace/tokens/txt
1609+/* tre-470 %txt /tests/golden/types-union-print-cross-namespace/tree/txt
1610+/* mod-470-1 %jibb /tests/golden/types-union-print-cross-namespace/modules/ui/lib/jibb
1611+/* typ-470 %txt /tests/golden/types-union-print-cross-namespace/types/txt
1612+/* mtre-470 %txt /tests/golden/types-union-print-cross-namespace/module-trees/txt
1613+/* src-471 %jibb /tests/golden/types-union-print-distinct/source/jibb
1614+/* tok-471 %txt /tests/golden/types-union-print-distinct/tokens/txt
1615+/* tre-471 %txt /tests/golden/types-union-print-distinct/tree/txt
1616+/* mod-471-1 %jibb /tests/golden/types-union-print-distinct/modules/ui/left/jibb
1617+/* mod-471-2 %jibb /tests/golden/types-union-print-distinct/modules/ui/right/jibb
1618+/* mod-471-3 %jibb /tests/golden/types-union-print-distinct/modules/ui/twin/jibb
1619+/* typ-471 %txt /tests/golden/types-union-print-distinct/types/txt
1620+/* mtre-471 %txt /tests/golden/types-union-print-distinct/module-trees/txt
1621+/* src-472 %jibb /tests/golden/types-union-print-escape/source/jibb
1622+/* tok-472 %txt /tests/golden/types-union-print-escape/tokens/txt
1623+/* tre-472 %txt /tests/golden/types-union-print-escape/tree/txt
1624+/* typ-472 %txt /tests/golden/types-union-print-escape/types/txt
1625+/* src-473 %jibb /tests/golden/types-union-print-local/source/jibb
1626+/* tok-473 %txt /tests/golden/types-union-print-local/tokens/txt
1627+/* tre-473 %txt /tests/golden/types-union-print-local/tree/txt
1628+/* typ-473 %txt /tests/golden/types-union-print-local/types/txt
1629+/* src-474 %jibb /tests/golden/types-union-print-nested/source/jibb
1630+/* tok-474 %txt /tests/golden/types-union-print-nested/tokens/txt
1631+/* tre-474 %txt /tests/golden/types-union-print-nested/tree/txt
1632+/* typ-474 %txt /tests/golden/types-union-print-nested/types/txt
1633+/* src-475 %jibb /tests/golden/types-union-print-same-origin/source/jibb
1634+/* tok-475 %txt /tests/golden/types-union-print-same-origin/tokens/txt
1635+/* tre-475 %txt /tests/golden/types-union-print-same-origin/tree/txt
1636+/* mod-475-1 %jibb /tests/golden/types-union-print-same-origin/modules/ui/shared/jibb
1637+/* typ-475 %txt /tests/golden/types-union-print-same-origin/types/txt
1638+/* mtre-475 %txt /tests/golden/types-union-print-same-origin/module-trees/txt
1639+/* src-476 %jibb /tests/golden/types-union-print-transitive/source/jibb
1640+/* tok-476 %txt /tests/golden/types-union-print-transitive/tokens/txt
1641+/* tre-476 %txt /tests/golden/types-union-print-transitive/tree/txt
1642+/* mod-476-1 %jibb /tests/golden/types-union-print-transitive/modules/ui/mid/jibb
1643+/* mod-476-2 %jibb /tests/golden/types-union-print-transitive/modules/ui/base/jibb
1644+/* typ-476 %txt /tests/golden/types-union-print-transitive/types/txt
1645+/* mtre-476 %txt /tests/golden/types-union-print-transitive/module-trees/txt
1646+/* src-477 %jibb /tests/golden/types-union-singleton/source/jibb
1647+/* tok-477 %txt /tests/golden/types-union-singleton/tokens/txt
1648+/* tre-477 %txt /tests/golden/types-union-singleton/tree/txt
1649+/* typ-477 %txt /tests/golden/types-union-singleton/types/txt
1650+/* src-478 %jibb /tests/golden/types-union-tag-atoms/source/jibb
1651+/* tok-478 %txt /tests/golden/types-union-tag-atoms/tokens/txt
1652+/* tre-478 %txt /tests/golden/types-union-tag-atoms/tree/txt
1653+/* typ-478 %txt /tests/golden/types-union-tag-atoms/types/txt
1654+/* src-479 %jibb /tests/golden/types-union-tags/source/jibb
1655+/* tok-479 %txt /tests/golden/types-union-tags/tokens/txt
1656+/* tre-479 %txt /tests/golden/types-union-tags/tree/txt
1657+/* typ-479 %txt /tests/golden/types-union-tags/types/txt
1658+/* src-480 %jibb /tests/golden/types-union-unresolved/source/jibb
1659+/* tok-480 %txt /tests/golden/types-union-unresolved/tokens/txt
1660+/* tre-480 %txt /tests/golden/types-union-unresolved/tree/txt
1661+/* typ-480 %txt /tests/golden/types-union-unresolved/types/txt
1662+/* src-481 %jibb /tests/golden/types-union-unresolved-flow/source/jibb
1663+/* tok-481 %txt /tests/golden/types-union-unresolved-flow/tokens/txt
1664+/* tre-481 %txt /tests/golden/types-union-unresolved-flow/tree/txt
1665+/* typ-481 %txt /tests/golden/types-union-unresolved-flow/types/txt
16581666|%
16591667:: one arm per case
16601668::
@@ -2578,44 +2586,48 @@
25782586 (weld (check ~.types-record-to-tuple src-459 `tok-459 `tre-459) (check-types ~.types-record-to-tuple ~[%tests %golden ~.types-record-to-tuple %source %jibb] src-459 `typ-459))
25792587++ test-types-union-alias
25802588 (weld (check ~.types-union-alias src-460 `tok-460 `tre-460) (check-types ~.types-union-alias ~[%tests %golden ~.types-union-alias %source %jibb] src-460 `typ-460))
2589+++ test-types-union-branch-context
2590+ (weld (check ~.types-union-branch-context src-461 `tok-461 `tre-461) (check-types ~.types-union-branch-context ~[%tests %golden ~.types-union-branch-context %source %jibb] src-461 `typ-461))
2591+++ test-types-union-branch-pending
2592+ (weld (check ~.types-union-branch-pending src-462 `tok-462 `tre-462) (check-types ~.types-union-branch-pending ~[%tests %golden ~.types-union-branch-pending %source %jibb] src-462 `typ-462))
25812593++ test-types-union-constructor-shape
2582− (weld (check ~.types-union-constructor-shape src-461 `tok-461 `tre-461) (check-types ~.types-union-constructor-shape ~[%tests %golden ~.types-union-constructor-shape %source %jibb] src-461 `typ-461))
2594+ (weld (check ~.types-union-constructor-shape src-463 `tok-463 `tre-463) (check-types ~.types-union-constructor-shape ~[%tests %golden ~.types-union-constructor-shape %source %jibb] src-463 `typ-463))
25832595++ test-types-union-context-flow
2584− (weld (check ~.types-union-context-flow src-462 `tok-462 `tre-462) (check-types ~.types-union-context-flow ~[%tests %golden ~.types-union-context-flow %source %jibb] src-462 `typ-462))
2596+ (weld (check ~.types-union-context-flow src-464 `tok-464 `tre-464) (check-types ~.types-union-context-flow ~[%tests %golden ~.types-union-context-flow %source %jibb] src-464 `typ-464))
25852597++ test-types-union-import
2586− (weld (weld (check ~.types-union-import src-463 `tok-463 `tre-463) (check-module-types ~.types-union-import ~[%tests %golden ~.types-union-import %source %jibb] src-463 `typ-463 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-463-1]])) (check-module-trees ~.types-union-import `mtre-463 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-463-1]]))
2598+ (weld (weld (check ~.types-union-import src-465 `tok-465 `tre-465) (check-module-types ~.types-union-import ~[%tests %golden ~.types-union-import %source %jibb] src-465 `typ-465 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-465-1]])) (check-module-trees ~.types-union-import `mtre-465 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-465-1]]))
25872599++ test-types-union-local-pending
2588− (weld (check ~.types-union-local-pending src-464 `tok-464 `tre-464) (check-types ~.types-union-local-pending ~[%tests %golden ~.types-union-local-pending %source %jibb] src-464 `typ-464))
2600+ (weld (check ~.types-union-local-pending src-466 `tok-466 `tre-466) (check-types ~.types-union-local-pending ~[%tests %golden ~.types-union-local-pending %source %jibb] src-466 `typ-466))
25892601++ test-types-union-overlap
2590− (weld (check ~.types-union-overlap src-465 `tok-465 `tre-465) (check-types ~.types-union-overlap ~[%tests %golden ~.types-union-overlap %source %jibb] src-465 `typ-465))
2602+ (weld (check ~.types-union-overlap src-467 `tok-467 `tre-467) (check-types ~.types-union-overlap ~[%tests %golden ~.types-union-overlap %source %jibb] src-467 `typ-467))
25912603++ test-types-union-overlap-nested
2592− (weld (check ~.types-union-overlap-nested src-466 `tok-466 `tre-466) (check-types ~.types-union-overlap-nested ~[%tests %golden ~.types-union-overlap-nested %source %jibb] src-466 `typ-466))
2604+ (weld (check ~.types-union-overlap-nested src-468 `tok-468 `tre-468) (check-types ~.types-union-overlap-nested ~[%tests %golden ~.types-union-overlap-nested %source %jibb] src-468 `typ-468))
25932605++ test-types-union-phantom-generic
2594− (weld (check ~.types-union-phantom-generic src-467 `tok-467 `tre-467) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-467 `typ-467))
2606+ (weld (check ~.types-union-phantom-generic src-469 `tok-469 `tre-469) (check-types ~.types-union-phantom-generic ~[%tests %golden ~.types-union-phantom-generic %source %jibb] src-469 `typ-469))
25952607++ test-types-union-print-cross-namespace
2596− (weld (weld (check ~.types-union-print-cross-namespace src-468 `tok-468 `tre-468) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-468 `typ-468 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-468-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-468 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-468-1]]))
2608+ (weld (weld (check ~.types-union-print-cross-namespace src-470 `tok-470 `tre-470) (check-module-types ~.types-union-print-cross-namespace ~[%tests %golden ~.types-union-print-cross-namespace %source %jibb] src-470 `typ-470 ~ ~ ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-470-1]])) (check-module-trees ~.types-union-print-cross-namespace `mtre-470 ~[['/ui/lib.jibb' ~[~.ui ~.lib ~.jibb] mod-470-1]]))
25972609++ test-types-union-print-distinct
2598− (weld (weld (check ~.types-union-print-distinct src-469 `tok-469 `tre-469) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-469 `typ-469 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-469-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-469-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-469-3]])) (check-module-trees ~.types-union-print-distinct `mtre-469 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-469-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-469-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-469-3]]))
2610+ (weld (weld (check ~.types-union-print-distinct src-471 `tok-471 `tre-471) (check-module-types ~.types-union-print-distinct ~[%tests %golden ~.types-union-print-distinct %source %jibb] src-471 `typ-471 ~ ~ ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-471-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-471-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-471-3]])) (check-module-trees ~.types-union-print-distinct `mtre-471 ~[['/ui/left.jibb' ~[~.ui ~.left ~.jibb] mod-471-1] ['/ui/right.jibb' ~[~.ui ~.right ~.jibb] mod-471-2] ['/ui/twin.jibb' ~[~.ui ~.twin ~.jibb] mod-471-3]]))
25992611++ test-types-union-print-escape
2600− (weld (check ~.types-union-print-escape src-470 `tok-470 `tre-470) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-470 `typ-470))
2612+ (weld (check ~.types-union-print-escape src-472 `tok-472 `tre-472) (check-types ~.types-union-print-escape ~[%tests %golden ~.types-union-print-escape %source %jibb] src-472 `typ-472))
26012613++ test-types-union-print-local
2602− (weld (check ~.types-union-print-local src-471 `tok-471 `tre-471) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-471 `typ-471))
2614+ (weld (check ~.types-union-print-local src-473 `tok-473 `tre-473) (check-types ~.types-union-print-local ~[%tests %golden ~.types-union-print-local %source %jibb] src-473 `typ-473))
26032615++ test-types-union-print-nested
2604− (weld (check ~.types-union-print-nested src-472 `tok-472 `tre-472) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-472 `typ-472))
2616+ (weld (check ~.types-union-print-nested src-474 `tok-474 `tre-474) (check-types ~.types-union-print-nested ~[%tests %golden ~.types-union-print-nested %source %jibb] src-474 `typ-474))
26052617++ test-types-union-print-same-origin
2606− (weld (weld (check ~.types-union-print-same-origin src-473 `tok-473 `tre-473) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-473 `typ-473 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-473-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-473 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-473-1]]))
2618+ (weld (weld (check ~.types-union-print-same-origin src-475 `tok-475 `tre-475) (check-module-types ~.types-union-print-same-origin ~[%tests %golden ~.types-union-print-same-origin %source %jibb] src-475 `typ-475 ~ ~ ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-475-1]])) (check-module-trees ~.types-union-print-same-origin `mtre-475 ~[['/ui/shared.jibb' ~[~.ui ~.shared ~.jibb] mod-475-1]]))
26072619++ test-types-union-print-transitive
2608− (weld (weld (check ~.types-union-print-transitive src-474 `tok-474 `tre-474) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-474 `typ-474 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-474-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-474-2]])) (check-module-trees ~.types-union-print-transitive `mtre-474 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-474-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-474-2]]))
2620+ (weld (weld (check ~.types-union-print-transitive src-476 `tok-476 `tre-476) (check-module-types ~.types-union-print-transitive ~[%tests %golden ~.types-union-print-transitive %source %jibb] src-476 `typ-476 ~ ~ ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-476-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-476-2]])) (check-module-trees ~.types-union-print-transitive `mtre-476 ~[['/ui/mid.jibb' ~[~.ui ~.mid ~.jibb] mod-476-1] ['/ui/base.jibb' ~[~.ui ~.base ~.jibb] mod-476-2]]))
26092621++ test-types-union-singleton
2610− (weld (check ~.types-union-singleton src-475 `tok-475 `tre-475) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-475 `typ-475))
2622+ (weld (check ~.types-union-singleton src-477 `tok-477 `tre-477) (check-types ~.types-union-singleton ~[%tests %golden ~.types-union-singleton %source %jibb] src-477 `typ-477))
26112623++ test-types-union-tag-atoms
2612− (weld (check ~.types-union-tag-atoms src-476 `tok-476 `tre-476) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-476 `typ-476))
2624+ (weld (check ~.types-union-tag-atoms src-478 `tok-478 `tre-478) (check-types ~.types-union-tag-atoms ~[%tests %golden ~.types-union-tag-atoms %source %jibb] src-478 `typ-478))
26132625++ test-types-union-tags
2614− (weld (check ~.types-union-tags src-477 `tok-477 `tre-477) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-477 `typ-477))
2626+ (weld (check ~.types-union-tags src-479 `tok-479 `tre-479) (check-types ~.types-union-tags ~[%tests %golden ~.types-union-tags %source %jibb] src-479 `typ-479))
26152627++ test-types-union-unresolved
2616− (weld (check ~.types-union-unresolved src-478 `tok-478 `tre-478) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-478 `typ-478))
2628+ (weld (check ~.types-union-unresolved src-480 `tok-480 `tre-480) (check-types ~.types-union-unresolved ~[%tests %golden ~.types-union-unresolved %source %jibb] src-480 `typ-480))
26172629++ test-types-union-unresolved-flow
2618− (weld (check ~.types-union-unresolved-flow src-479 `tok-479 `tre-479) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-479 `typ-479))
2630+ (weld (check ~.types-union-unresolved-flow src-481 `tok-481 `tre-481) (check-types ~.types-union-unresolved-flow ~[%tests %golden ~.types-union-unresolved-flow %source %jibb] src-481 `typ-481))
26192631::
26202632:: +check: run golden:jibb on a case and compare both outputs
26212633::
tools/importer-test+1−1
@@ -34,4 +34,4 @@ if result.stdout != expected:
3434 result.stdout.decode().splitlines(keepends=True),
3535 fromfile='expected tree.txt', tofile='actual types'))
3636 sys.exit(1)
37−print('importer golden: 130 projections passed')
37+print('importer golden: 140 projections passed')