on master help sign in
Report nested imported mold errors
054e651iko
docs/compiler.md+1−1
@@ -72,7 +72,7 @@ The separate `jibb-dev/lib/jibb-import.hoon` is an unfinished reader for selecte
72
72
73Self-recursive `/sur` molds can cross the bridge as opaque module-and-name identities when their supported source-aware graph passes validation. Aliases, foreign references, recursive marks, unfolding, construction and field access remain unsupported; the partial printer declines recursive names that are not in scope.
73Self-recursive `/sur` molds can cross the bridge as opaque module-and-name identities when their supported source-aware graph passes validation. Aliases, foreign references, recursive marks, unfolding, construction and field access remain unsupported; the partial printer declines recursive names that are not in scope.
74
74
75−Callers 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 opt-in `+read-named-diagnostic` and `+read-mark-diagnostic` preserve successful graphs and distinguish definite `%invalid` aura and core evidence emitted directly by the reader from `%unsupported` failures. Other failures, including unverified union disjointness and vase recognition based only on a name, remain unsupported. These entry points revalidate and re-walk failed types; the opt-in `+golden-types-with-reader-diagnostics` accepts unchanged structured reader results and reports definite aura or core errors at direct imported `%ref` casts or whole-sample mold use sites, when the import and supplied input are unique. Nested shapes, local aliases, transitive modules and unsupported reader outcomes still report generic limitations; this entry point remains partial. Existing checker entry points continue treating failed imports as unsupported. It also fails closed on repeated field faces along an imported record spine, including recursive roots; the diagnostic remains generic. Hoon type graphs can erase unfaced nested-cell boundaries, so the check may conservatively reject a valid source with equal names in distinct erased scopes. Faced nested records and union alternatives keep separate scopes.
75+Callers 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 opt-in `+read-named-diagnostic` and `+read-mark-diagnostic` preserve successful graphs and distinguish definite `%invalid` aura and core evidence emitted directly by the reader from `%unsupported` failures. Other failures, including unverified union disjointness and vase recognition based only on a name, remain unsupported. These entry points revalidate and re-walk failed types; the opt-in `+golden-types-with-reader-diagnostics` accepts unchanged structured reader results and reports definite aura or core errors at their imported mold use sites, when the import and supplied input are unique. Ordered replay covers direct and nested cell samples, record and function casts, and non-generic same-module aliases; it stops at an unsupported prefix, cycle or shadowing failure. Union molds, generic applications, transitive modules and unsupported reader outcomes still report generic limitations. Replay repeats inference and may add work; this entry point remains partial. Existing checker entry points continue treating failed imports as unsupported. It also fails closed on repeated field faces along an imported record spine, including recursive roots; the diagnostic remains generic. Hoon type graphs can erase unfaced nested-cell boundaries, so the check may conservatively reject a valid source with equal names in distinct erased scopes. Faced nested records and union alternatives keep separate scopes.
76
76
77`+golden-types-with-prelude` accepts case-local Jibb module sources alongside `/sur` and mark results and the vendored prelude source. It resolves reachable ordinary library modules in dependency order, caching completed interfaces per invocation and exporting supported closed value schemes, direct generic unions, and simple or nonrecursive generic mold aliases whose bodies the fragment supports. It detects missing sources and cycles and rejects a dependency if its interface cannot be inferred by the fragment.
77`+golden-types-with-prelude` accepts case-local Jibb module sources alongside `/sur` and mark results and the vendored prelude source. It resolves reachable ordinary library modules in dependency order, caching completed interfaces per invocation and exporting supported closed value schemes, direct generic unions, and simple or nonrecursive generic mold aliases whose bodies the fragment supports. It detects missing sources and cycles and rejects a dependency if its interface cannot be inferred by the fragment.
78
78
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
19
19
20## Milestone 2: in progress
20## Milestone 2: in progress
21
21
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 direct imported cast and whole-sample references when their inputs are unique; nested shapes, aliases, transitive modules and unsupported reader outcomes remain generic. 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. Mutual groups, polymorphic recursion and value cycles remain unsupported. Reporting repeats inference for a recursive gate, so its performance cost remains unmeasured. Contextual null-headed cells fit their cases, but do not supply a `|=%$` constructor; unresolved nulls remain pending and are reported separately from tags. A known union of `~` and a null-headed cell supports a complete `~` / `[~ value]` branch in either order, including shadow checks; unknown subjects, missing or duplicate arms, and unresolved branch results remain unsupported. This fragment infers the prelude’s `fall` and `need` signatures. With the validated prelude list and a known cast or gate sample, empty, nonempty and nested list literals infer their element types, including contextual union tags; a mismatched element names both sites. In that context `~` and zero-valued terms fit an empty list, and two-item unfaced cells form cons lists, including nested cons and imported-list contexts; invalid heads or tails name both sites. Faced or longer cells and a missing or altered prelude list fail closed. A known list result also supplies context through complete loobean, unit-shaped and list-shaped branches, including recursive and nested branches. For a known standard list with a supported element type, a complete `~` / `[item rest]` branch infers the element and tail types in either arm order and checks binders for shadowing. Uncontextualized list construction, unknown subjects, unsupported element types and other or incomplete list patterns remain unsupported. A value with type variable `A` can fit a field whose type is that same `A`, including in generic union payloads and nested or repeated record fields. Other variable-dependent face merges remain unsupported. Forced equality of distinct written capitals now reports both source sites, following @iko’s decision; forcing one to a concrete type remains unsupported. Imported record spines with repeated faces fail closed where used, but only with a generic unsupported diagnostic. Hoon may erase unfaced nested-cell boundaries, so the check can conservatively reject valid names in distinct erased scopes. Supported closed unions print using an in-scope name or imported alias; an unnamed nongeneric union prints its cases, parenthesized when nested. The latter is print-only. Generic union types retain all arguments in their printed name; if that name is unavailable, the partial printer reports the limitation. Different import faces for the same origin remain compatible; compatibility across distinct union origins and some generic-argument comparisons remain unsupported. Nonrecursive generic aliases can reorder, repeat or omit parameters while retaining a union’s origin, including through local scopes and library interfaces. A generic union declared directly inside a body remains unsupported, as do differing-variable face constraints in a union payload. A transitive generic union whose name is unavailable is reported as unsupported instead of hiding its arguments. Unfixed decimal literals default to `@ud` in gate-free inferred types; 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. Mutual groups, polymorphic recursion and value cycles remain unsupported. Reporting repeats inference for a recursive gate, so its performance cost remains unmeasured. Contextual null-headed cells fit their cases, but do not supply a `|=%$` constructor; unresolved nulls remain pending and are reported separately from tags. A known union of `~` and a null-headed cell supports a complete `~` / `[~ value]` branch in either order, including shadow checks; unknown subjects, missing or duplicate arms, and unresolved branch results remain unsupported. This fragment infers the prelude’s `fall` and `need` signatures. With the validated prelude list and a known cast or gate sample, empty, nonempty and nested list literals infer their element types, including contextual union tags; a mismatched element names both sites. In that context `~` and zero-valued terms fit an empty list, and two-item unfaced cells form cons lists, including nested cons and imported-list contexts; invalid heads or tails name both sites. Faced or longer cells and a missing or altered prelude list fail closed. A known list result also supplies context through complete loobean, unit-shaped and list-shaped branches, including recursive and nested branches. For a known standard list with a supported element type, a complete `~` / `[item rest]` branch infers the element and tail types in either arm order and checks binders for shadowing. Uncontextualized list construction, unknown subjects, unsupported element types and other or incomplete list patterns remain unsupported. A value with type variable `A` can fit a field whose type is that same `A`, including in generic union payloads and nested or repeated record fields. Other variable-dependent face merges remain unsupported. Forced equality of distinct written capitals now reports both source sites, following @iko’s decision; forcing one to a concrete type remains unsupported. Imported record spines with repeated faces fail closed where used, but only with a generic unsupported diagnostic. Hoon may erase unfaced nested-cell boundaries, so the check can conservatively reject valid names in distinct erased scopes. Supported closed unions print using an in-scope name or imported alias; an unnamed nongeneric union prints its cases, parenthesized when nested. The latter is print-only. Generic union types retain all arguments in their printed name; if that name is unavailable, the partial printer reports the limitation. Different import faces for the same origin remain compatible; compatibility across distinct union origins and some generic-argument comparisons remain unsupported. Nonrecursive generic aliases can reorder, repeat or omit parameters while retaining a union’s origin, including through local scopes and library interfaces. A generic union declared directly inside a body remains unsupported, as do differing-variable face constraints in a union payload. A transitive generic union whose name is unavailable is reported as unsupported instead of hiding its arguments. Unfixed decimal literals default to `@ud` in gate-free inferred types; 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.
23
23
24The 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` and `snoc`. The validated standard `list` mold is injected when the prelude’s own gates are inferred; `weld` has an ordinary explicit result cast. 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.
24The 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` and `snoc`. The validated standard `list` mold is injected when the prelude’s own gates are inferred; `weld` has an ordinary explicit result cast. 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.
25
25
@@ -40,7 +40,7 @@ What the plan asks for, and where it is:
40Besides the plan's list:
40Besides the plan's list:
41
41
42- 514 golden cases: 298 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.
42- 514 golden cases: 298 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 514-case corpus passed under `urbit eval` in 57.0 s. The fake ship passed all 520 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 31.8 s for sync and 35.3 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 514-case corpus passed under `urbit eval` in 62.6 s. The fake ship passed all 520 tests, including the importer, importer/checker and mark/checker bridges, module scope and unification checks, with 30.5 s for sync and 36.0 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.
44- `tools/testdata/selftest` (22 checks) and `tools/testdata/ship-selftest` test the tools themselves.
44- `tools/testdata/selftest` (22 checks) and `tools/testdata/ship-selftest` test the tools themselves.
45- 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.
45- 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.
46- 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).
46- 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).
@@ -90,7 +90,8 @@ Besides the plan's list:
90| 918acbd | 2026-10-30 | Infer recursive gates from their samples first |
90| 918acbd | 2026-10-30 | Infer recursive gates from their samples first |
91| 1470d18 | 2026-10-30 | Infer selected prelude list helpers |
91| 1470d18 | 2026-10-30 | Infer selected prelude list helpers |
92| 10cbf9c | 2026-10-30 | Infer selected local recursive gates and distinguish reader diagnostics |
92| 10cbf9c | 2026-10-30 | Infer selected local recursive gates and distinguish reader diagnostics |
93−| This change | 2026-10-30 | Infer local capital scopes and report direct reader diagnostics |
93+| 45afb13 | 2026-10-30 | Infer local capital scopes and report direct reader diagnostics |
94+| This change | 2026-10-30 | Report nested reader diagnostics |
94
95
95## Checking it
96## Checking it
96
97
jibb-dev/lib/jibb.hoon+62−10
@@ -5874,16 +5874,68 @@
5874 ?. ?=([%invalid ?(%aura %core) @] raw) ~
5874 ?. ?=([%invalid ?(%aura %core) @] raw) ~
5875 `["{(trip +>.raw)}" ~[[at.sh "invalid imported mold"]]]
5875 `["{(trip +>.raw)}" ~[[at.sh "invalid imported mold"]]]
5876::
5876::
5877−++ direct-sample-invalid
5877+:: Replay only the shape branches whose evaluation order we can prove.
5878+:: Successful prefixes must be checked before descending to a failure.
5879+++ nested-import-invalid
5880+ |= [sh=shape state=istate]
5881+ ^- (unit idiag)
5882+ ?: ?=(^ (infer-simple-shape sh state)) ~
5883+ ?- -.sh
5884+ %ref
5885+ =/ direct=(unit idiag) (direct-import-invalid sh state)
5886+ ?^ direct direct
5887+ ?~ names.sh ~
5888+ ?^ t.names.sh ~
5889+ =/ n=term i.names.sh
5890+ ?: (lien marks.state |=(x=term =(x n))) ~
5891+ ?: (lien active.state |=(x=term =(x n))) ~
5892+ =/ found=(unit shape) (find-simple-mold n molds.state)
5893+ ?~ found ~
5894+ $(sh u.found, state state(active [n active.state], in-mold &, params ~))
5895+ %fn
5896+ =/ first=(unit [typ=itype state=istate]) (infer-simple-shape sample.sh state)
5897+ ?~ first $(sh sample.sh)
5898+ $(sh product.sh, state state.u.first)
5899+ %cell (nested-field-invalid fields.sh state)
5900+ * ~
5901+ ==
5902+::
5903+++ nested-field-invalid
5878− |= [s=sample state=istate]
5904+ |= [fields=(list field) state=istate]
5879 ^- (unit idiag)
5905 ^- (unit idiag)
5906+ ?~ fields ~
5907+ =/ sh=shape
5908+ ?- -.i.fields
5909+ %bare shape.i.fields
5910+ %face shape.i.fields
5911+ %pun [%ref at.i.fields ~[name.i.fields]]
5912+ ==
5913+ =/ out=(unit [typ=itype state=istate]) (infer-simple-shape sh state)
5914+ ?~ out (nested-import-invalid sh state)
5915+ $(fields t.fields, state state.u.out)
5916+::
5917+++ sample-import-invalid
5918+ |= [s=sample env=ienv state=istate]
5919+ ^- (unit idiag)
5920+ =/ result=isample-result (infer-sample s env state)
5921+ ?: ?=(%& -.result) ~
5922+ ?. =(p.result "sample mold is not supported by partial inference") ~
5880 ?- s
5923 ?- s
5881− [%face *] (direct-import-invalid shape.s state)
5924+ [%face *] (nested-import-invalid shape.s state)
5882− [%bare *] (direct-import-invalid shape.s state)
5925+ [%bare *] (nested-import-invalid shape.s state)
5883− [%pun *] (direct-import-invalid [%ref at.s ~[name.s]] state)
5926+ [%pun *] (nested-import-invalid [%ref at.s ~[name.s]] state)
5927+ [%cell *] (nested-samples-invalid items.s env state)
5884 * ~
5928 * ~
5885 ==
5929 ==
5886::
5930::
5931+++ nested-samples-invalid
5932+ |= [items=(list sample) env=ienv state=istate]
5933+ ^- (unit idiag)
5934+ ?~ items ~
5935+ =/ head=isample-result (infer-sample i.items env state)
5936+ ?: ?=(%| -.head) (sample-import-invalid i.items env state)
5937+ $(items t.items, env env.p.head, state state.p.head)
5938+::
5887++ infer-simple-shape
5939++ infer-simple-shape
5888 |= [sh=shape state=istate]
5940 |= [sh=shape state=istate]
5889 ^- (unit [typ=itype state=istate])
5941 ^- (unit [typ=itype state=istate])
@@ -6728,7 +6780,7 @@
6728 %cast
6780 %cast
6729 =/ target=(unit [typ=itype state=istate]) (infer-simple-shape shape.e state)
6781 =/ target=(unit [typ=itype state=istate]) (infer-simple-shape shape.e state)
6730 ?~ target
6782 ?~ target
6731− =/ diag=(unit idiag) (direct-import-invalid shape.e state)
6783+ =/ diag=(unit idiag) (nested-import-invalid shape.e state)
6732 ?^ diag [%| u.diag]
6784 ?^ diag [%| u.diag]
6733 [%| ["cast mold is not supported by partial inference" ~]]
6785 [%| ["cast mold is not supported by partial inference" ~]]
6734 =/ value=iresult
6786 =/ value=iresult
@@ -6750,7 +6802,7 @@
6750 %gate
6802 %gate
6751 =/ sam=isample-result (infer-sample sample.e env state)
6803 =/ sam=isample-result (infer-sample sample.e env state)
6752 ?: ?=(%| -.sam)
6804 ?: ?=(%| -.sam)
6753− =/ diag=(unit idiag) (direct-sample-invalid sample.e state)
6805+ =/ diag=(unit idiag) (sample-import-invalid sample.e env state)
6754 ?: &(=(p.sam "sample mold is not supported by partial inference") ?=(^ diag)) [%| u.diag]
6806 ?: &(=(p.sam "sample mold is not supported by partial inference") ?=(^ diag)) [%| u.diag]
6755 [%| [p.sam ~]]
6807 [%| [p.sam ~]]
6756 =/ body=iresult $(e body.e, env env.p.sam, state state.p.sam)
6808 =/ body=iresult $(e body.e, env env.p.sam, state state.p.sam)
@@ -6759,7 +6811,7 @@
6759 %gate-wide
6811 %gate-wide
6760 =/ sam=isample-result (infer-sample sample.e env state)
6812 =/ sam=isample-result (infer-sample sample.e env state)
6761 ?: ?=(%| -.sam)
6813 ?: ?=(%| -.sam)
6762− =/ diag=(unit idiag) (direct-sample-invalid sample.e state)
6814+ =/ diag=(unit idiag) (sample-import-invalid sample.e env state)
6763 ?: &(=(p.sam "sample mold is not supported by partial inference") ?=(^ diag)) [%| u.diag]
6815 ?: &(=(p.sam "sample mold is not supported by partial inference") ?=(^ diag)) [%| u.diag]
6764 [%| [p.sam ~]]
6816 [%| [p.sam ~]]
6765 =/ body=iresult $(e body.e, env env.p.sam, state state.p.sam)
6817 =/ body=iresult $(e body.e, env env.p.sam, state state.p.sam)
@@ -7241,8 +7293,8 @@
7241 ?: ?=(%| -.sam)
7293 ?: ?=(%| -.sam)
7242 =/ diag=(unit idiag)
7294 =/ diag=(unit idiag)
7243 ?- -.gate
7295 ?- -.gate
7244− %gate (direct-sample-invalid sample.gate state)
7296+ %gate (sample-import-invalid sample.gate env state)
7245− %gate-wide (direct-sample-invalid sample.gate state)
7297+ %gate-wide (sample-import-invalid sample.gate env state)
7246 * ~
7298 * ~
7247 ==
7299 ==
7248 ?: &(=(p.sam "sample mold is not supported by partial inference") ?=(^ diag)) [%| u.diag]
7300 ?: &(=(p.sam "sample mold is not supported by partial inference") ?=(^ diag)) [%| u.diag]
tests/lib/jibb-import-diagnostic.hoon+6−3
@@ -3,6 +3,7 @@
3/* sur %txt /tests/type-import-diagnostic/sur/txt
3/* sur %txt /tests/type-import-diagnostic/sur/txt
4/* mark %txt /tests/type-import-diagnostic/mark/txt
4/* mark %txt /tests/type-import-diagnostic/mark/txt
5/* source %txt /tests/type-import-diagnostic/source/txt
5/* source %txt /tests/type-import-diagnostic/source/txt
6+/* nested %txt /tests/type-import-diagnostic/nested/txt
6/* expected %txt /tests/type-import-diagnostic/expected/txt
7/* expected %txt /tests/type-import-diagnostic/expected/txt
7|%
8|%
8++ text
9++ text
@@ -14,13 +15,14 @@
14 ?~ sur ~[leaf+"diagnostic /sur fixture is missing"]
15 ?~ sur ~[leaf+"diagnostic /sur fixture is missing"]
15 ?~ mark ~[leaf+"diagnostic mark fixture is missing"]
16 ?~ mark ~[leaf+"diagnostic mark fixture is missing"]
16 ?~ source ~[leaf+"diagnostic source fixture is missing"]
17 ?~ source ~[leaf+"diagnostic source fixture is missing"]
18+ ?~ nested ~[leaf+"diagnostic nested source is missing"]
17 ?~ expected ~[leaf+"diagnostic expected output is missing"]
19 ?~ expected ~[leaf+"diagnostic expected output is missing"]
18− =/ got (diagnostic-output (text sur) (text mark) (text source))
20+ =/ got (diagnostic-output (text sur) (text mark) (text source) (text nested))
19 ?. =((to-wain:format (cat 3 got '\0a')) expected)
21 ?. =((to-wain:format (cat 3 got '\0a')) expected)
20 ~[leaf+"import diagnostic output differs from tests/type-import-diagnostic/expected.txt"]
22 ~[leaf+"import diagnostic output differs from tests/type-import-diagnostic/expected.txt"]
21 ~
23 ~
22++ diagnostic-output
24++ diagnostic-output
23− |= [sur-text=@t mark-text=@t src=@t]
25+ |= [sur-text=@t mark-text=@t src=@t nested-src=@t]
24 ^- @t
26 ^- @t
25 =/ cor=type -:(ride -:!>(..zuse) sur-text)
27 =/ cor=type -:(ride -:!>(..zuse) sur-text)
26 =/ mark-cor=type -:(ride -:!>(..zuse) mark-text)
28 =/ mark-cor=type -:(ride -:!>(..zuse) mark-text)
@@ -37,6 +39,7 @@
37 =/ shadow=@t (crip "/- foo\0a++ shadow |= shadow=bad.foo shadow\0a++ safe |= x=@t x\0a")
39 =/ shadow=@t (crip "/- foo\0a++ shadow |= shadow=bad.foo shadow\0a++ safe |= x=@t x\0a")
38 =/ invalid [%invalid %aura 'signed and float auras cannot be imported']
40 =/ invalid [%invalid %aura 'signed and float auras cannot be imported']
39 =/ unsupported [%unsupported 'Hoon type is unsupported']
41 =/ unsupported [%unsupported 'Hoon type is unsupported']
42+ =/ nested-report (golden-types-with-reader-diagnostics:jibb /ui/test/jibb nested-src ~[[%foo %bad invalid]] ~)
40 =/ dup (golden-types-with-reader-diagnostics:jibb /test/jibb sample ~[[%foo %bad invalid] [%foo %bad invalid]] ~)
43 =/ dup (golden-types-with-reader-diagnostics:jibb /test/jibb sample ~[[%foo %bad invalid] [%foo %bad invalid]] ~)
41 =/ inconclusive (golden-types-with-reader-diagnostics:jibb /test/jibb sample ~[[%foo %bad unsupported]] ~)
44 =/ inconclusive (golden-types-with-reader-diagnostics:jibb /test/jibb sample ~[[%foo %bad unsupported]] ~)
42 =/ bad-code (golden-types-with-reader-diagnostics:jibb /test/jibb sample ~[[%foo %bad [%invalid %other 'forged']]] ~)
45 =/ bad-code (golden-types-with-reader-diagnostics:jibb /test/jibb sample ~[[%foo %bad [%invalid %other 'forged']]] ~)
@@ -52,5 +55,5 @@
52 =/ ic (golden-types-with-reader-diagnostics:jibb /test/jibb import-clash ~[[%foo %bad invalid]] ~[[%foo invalid]])
55 =/ ic (golden-types-with-reader-diagnostics:jibb /test/jibb import-clash ~[[%foo %bad invalid]] ~[[%foo invalid]])
53 =/ vc (golden-types-with-reader-diagnostics:jibb /test/jibb value-clash ~[[%foo %bad invalid]] ~)
56 =/ vc (golden-types-with-reader-diagnostics:jibb /test/jibb value-clash ~[[%foo %bad invalid]] ~)
54 =/ mc (golden-types-with-reader-diagnostics:jibb /test/jibb mold-clash ~ ~[[%foo invalid]])
57 =/ mc (golden-types-with-reader-diagnostics:jibb /test/jibb mold-clash ~ ~[[%foo invalid]])
55− (of-wain:format ~['real reader:' real 'duplicate:' dup 'unsupported:' inconclusive 'unknown code:' bad-code 'malformed message:' bad-message 'missing:' missing 'unused:' unused 'undeclared:' absent 'shadow:' collision 'import clash:' ic 'value clash:' vc 'mold clash:' mc])
58+ (of-wain:format ~['real reader:' real 'nested:' nested-report 'duplicate:' dup 'unsupported:' inconclusive 'unknown code:' bad-code 'malformed message:' bad-message 'missing:' missing 'unused:' unused 'undeclared:' absent 'shadow:' collision 'import clash:' ic 'value clash:' vc 'mold clash:' mc])
56--
59--
tests/type-import-diagnostic/about.txt+5−3
@@ -1,9 +1,11 @@
1The Overview's Hoon import table makes signed and float auras, cores and
1The Overview's Hoon import table makes signed and float auras, cores and
2gates errors where used; unused molds are skipped. This fixture compiles a
2gates errors where used; unused molds are skipped. This fixture compiles a
3/sur file and a mark against zuse and passes unchanged structured reader
3/sur file and a mark against zuse and passes unchanged structured reader
4−results to the partial checker. Proven errors at direct cast and whole-sample
4+results to the partial checker. Proven errors identify the Jibb use site for direct or nested record and
5+function casts, cell samples, and non-generic local aliases. Ordered replay
6+stops at an unsupported prefix, cycle or shadowing failure; unions, generic
7+applications and transitive modules remain unsupported. Valid sibling
5−references identify the Jibb use site. Valid sibling definitions still infer;
8+definitions still infer.
6−nested references and aliases remain unsupported by this partial entry point.
7
9
8Synthetic controls verify that missing, duplicate, unsupported, undeclared or
10Synthetic controls verify that missing, duplicate, unsupported, undeclared or
9unused inputs, shadowing and competing names do not produce a misleading
11unused inputs, shadowing and competing names do not produce a misleading
tests/type-import-diagnostic/expected.txt+35−2
@@ -8,8 +8,14 @@ partial inference; module not checked
8/ui/test.jibb:7:16: invalid imported mold
8/ui/test.jibb:7:16: invalid imported mold
9++ sample |= x=signed.fixture x
9++ sample |= x=signed.fixture x
10 ^
10 ^
11−++ nested: sample mold is not supported by partial inference
11+++ nested: cores and gates cannot be imported
12−++ alias-use: cast mold is not supported by partial inference
12+/ui/test.jibb:4:27: invalid imported mold
13++$ box [ok=@t nested=[bad=core.fixture]]
14+ ^
15+++ alias-use: signed and float auras cannot be imported
16+/ui/test.jibb:3:10: invalid imported mold
17++$ alias signed.fixture
18+ ^
13++ mark-use: signed and float auras cannot be imported
19++ mark-use: signed and float auras cannot be imported
14/ui/test.jibb:10:18: invalid imported mold
20/ui/test.jibb:10:18: invalid imported mold
15++ mark-use |= x=bad-mark x
21++ mark-use |= x=bad-mark x
@@ -26,6 +32,33 @@ partial inference; module not checked
26/ui/test.jibb:13:19: invalid imported mold
32/ui/test.jibb:13:19: invalid imported mold
27++ signed-cast ^- signed.fixture !!
33++ signed-cast ^- signed.fixture !!
28 ^
34 ^
35+nested:
36+partial inference; module not checked
37++$ alias: not checked
38++$ recursive: not checked
39+++ nested: signed and float auras cannot be imported
40+/ui/test.jibb:4:22: invalid imported mold
41+++ nested |= [a=@t b=bad.foo] a
42+ ^
43+++ cast: signed and float auras cannot be imported
44+/ui/test.jibb:5:20: invalid imported mold
45+++ cast ^- [a=@t b=bad.foo] !!
46+ ^
47+++ func: signed and float auras cannot be imported
48+/ui/test.jibb:6:18: invalid imported mold
49+++ func ^- $-(@t bad.foo) !!
50+ ^
51+++ alias-use: signed and float auras cannot be imported
52+/ui/test.jibb:2:10: invalid imported mold
53++$ alias bad.foo
54+ ^
55+++ first-unsupported: cast mold is not supported by partial inference
56+++ recursive-first: cast mold is not supported by partial inference
57+++ shadow: sample shadows a name
58+++ first-invalid: signed and float auras cannot be imported
59+/ui/test.jibb:11:24: invalid imported mold
60+++ first-invalid |= [a=bad.foo b=bad.foo] a
61+ ^
29duplicate:
62duplicate:
30partial inference; module not checked
63partial inference; module not checked
31++ cast: cast mold is not supported by partial inference
64++ cast: cast mold is not supported by partial inference
tests/type-import-diagnostic/nested.txtnew file+11
@@ -0,0 +1,11 @@
1+/- foo
2++$ alias bad.foo
3++$ recursive recursive
4+++ nested |= [a=@t b=bad.foo] a
5+++ cast ^- [a=@t b=bad.foo] !!
6+++ func ^- $-(@t bad.foo) !!
7+++ alias-use ^- alias !!
8+++ first-unsupported ^- [a=* b=bad.foo] !!
9+++ recursive-first ^- [a=recursive b=bad.foo] !!
10+++ shadow |= [a=@t a=bad.foo] a
11+++ first-invalid |= [a=bad.foo b=bad.foo] a
tools/type-import-diagnostic-test+3−1
@@ -16,9 +16,10 @@ expression = ('=/ jibb .\n=/ jibb-import\n' + reader +
16 '\n=/ sur=wain (to-wain:format sur-text)\n'
16 '\n=/ sur=wain (to-wain:format sur-text)\n'
17 '=/ mark=wain (to-wain:format mark-text)\n'
17 '=/ mark=wain (to-wain:format mark-text)\n'
18 '=/ source=wain (to-wain:format source-text)\n'
18 '=/ source=wain (to-wain:format source-text)\n'
19+ '=/ nested=wain (to-wain:format nested-text)\n'
19 '=/ expected=wain (to-wain:format expected-text)\n'
20 '=/ expected=wain (to-wain:format expected-text)\n'
20 '=/ bridge\n' + tests +
21 '=/ bridge\n' + tests +
21− '\n(diagnostic-output:bridge sur-text mark-text source-text)\n')
22+ '\n(diagnostic-output:bridge sur-text mark-text source-text nested-text)\n')
22with tempfile.TemporaryDirectory(prefix='jibb-type-import-') as tmp:
23with tempfile.TemporaryDirectory(prefix='jibb-type-import-') as tmp:
23 program = Path(tmp) / 'bridge.hoon'
24 program = Path(tmp) / 'bridge.hoon'
24 program.write_text(expression)
25 program.write_text(expression)
@@ -27,6 +28,7 @@ with tempfile.TemporaryDirectory(prefix='jibb-type-import-') as tmp:
27 '--cord', 'sur-text=' + str(fixture / 'sur.txt'),
28 '--cord', 'sur-text=' + str(fixture / 'sur.txt'),
28 '--cord', 'mark-text=' + str(fixture / 'mark.txt'),
29 '--cord', 'mark-text=' + str(fixture / 'mark.txt'),
29 '--cord', 'source-text=' + str(fixture / 'source.txt'),
30 '--cord', 'source-text=' + str(fixture / 'source.txt'),
31+ '--cord', 'nested-text=' + str(fixture / 'nested.txt'),
30 '--cord', 'expected-text=' + str(fixture / 'expected.txt')],
32 '--cord', 'expected-text=' + str(fixture / 'expected.txt')],
31 stdout=subprocess.PIPE)
33 stdout=subprocess.PIPE)
32if result.returncode:
34if result.returncode: