From 5def9d7c98b8885b8cb8d0ac5c92aa62c017ac2b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 11:06:07 +0000 Subject: [PATCH 01/17] A generic record literal admits the wrong field type silently at six seams: locate the fail-open, and record two repairs that do NOT close it DESIGN 4b names "values inhabit declared types" as the ordinary compiler floor. A record literal of a GENERIC type does not hold it: measured on eleven single-module probe roots, a wrongly-typed field value is accepted AND EMITTED at six positions -- fn return, let annotation, record field, list element, direct-call argument, and a module-scope data annotation -- while the non-generic control refuses with a located mismatch and the conforming generic control compiles clean. The field PRESENCE axis is unaffected (a generic literal missing a required field still refuses), which rules out "generic declarations are not processed" and confines the class to the field TYPE axis. Mechanism, by execution rather than by reading: the instantiation does reach the literal and the substitution is keyed correctly on "T", but the declaration's field type node carries no name to key on, so the parameter is never substituted and the expectation reaching the judgment is a NAMELESS node -- whereupon kernel_value_declared_type_mismatch returns false on formal_name == "". A second, independent fail-open sits beside it: the substitution value is read with resolved_type, whose Absent arm is the equally nameless error_type. Two repairs were built and run against the full arm table and moved NOTHING; both are recorded because they are the cost of the next attempt. What is still open is where the type-parameter reference loses its name, which is a modelling question in a stage DESIGN names load-bearing -- so no code changes here, and the probe states the exact next question rather than leaving it to be re-derived. Co-Authored-By: Claude Opus 5 (1M context) --- ..._record_field_type_fail_open_2026-08-22.md | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 docs/probes/generic_record_field_type_fail_open_2026-08-22.md diff --git a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md new file mode 100644 index 00000000000..c3c801cd7ac --- /dev/null +++ b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md @@ -0,0 +1,107 @@ +# A generic record literal admits the wrong field type silently, at six seams + +**Subject:** the v1 frontend (`gunbc compile`), source→`.dag`-acceptance path. +**Ref:** built from `967b5bc1b9` (branch `session/calm-heron-887`), release `gunbc`, +built locally (`RUSTC_WRAPPER= CTRL_BUILD_MODE=local cargo build --release -p v1-compiler --bin gunbc`). +**Producer:** eleven single-module probe roots, each written from scratch, one module per arm +(a blocking error truncates the diagnostic set, so arms must not share a module). + +## The class + +DESIGN §4b names "values inhabit declared types" as the **ordinary compiler floor**, where a +failure is a below-baseline safety regression. A record literal of a **generic** type does not +hold that floor: the field expectation derived from the instantiation is a nameless node, and the +judgment that would refuse fails open on it. The wrong program is not merely un-refused — it is +**emitted**. + +This is **below floor, not a rung on the ladder** (§4b), and it is the residue the +`declared_type_conformance_diags` note in `v1.compiler.infer` already named as its own lane: +*"generic record instantiation, and post-substitution generic field access."* + +## Measured, with discriminating controls + +Every arm shares one preamble: `type Box { v: T }` and `type Plain { v: Int }`. + +| arm | source | RC | verdict | +|---|---|---|---| +| `ctl_pos` | `Plain { v: 1 }` | 0 | control: conforming non-generic compiles | +| `ctl_neg` | `Plain { v: "s" }` | 1 | control: **instrument reds** — `type mismatch: expected 'Primitive(Int)', got 'Primitive(String)'` | +| `ret_generic_pos` | `fn f() -> Box { Box { v: 1 } }` | 0 | control: conforming generic compiles | +| `ret_generic` | `fn f() -> Box { Box { v: "s" } }` | **0** | **fail-open, emits** | +| `let_generic` | `let x: Box = Box { v: "s" }` | **0** | **fail-open, emits** | +| `field_generic` | `Holder { b: Box { v: "s" } }`, `b: Box` | **0** | **fail-open, emits** | +| `list_generic` | `fn f() -> List> { [Box { v: "s" }] }` | **0** | **fail-open, emits** | +| `arg_generic` | `takes(b: Box { v: "s" })`, `fn takes(b: Box)` | **0** | **fail-open, emits** | +| `data_generic` | `data d: Box = Box { v: "s" }` | **0** | **fail-open, emits** | +| `missing_plain` | `Plain { }` | 1 | field **presence** holds | +| `missing_generic` | `Box { }` | 1 | field **presence** holds for generics too | + +Two facts the table settles that reasoning would not. **Six seams**, not one — every position that +knows an instantiation loses it, so this is a property of the shared machinery rather than of any +one caller. And the failure is confined to the field **type** axis: `missing_generic` refuses, so +field **completeness** is unaffected, which rules out "generic declarations are simply not +processed" as the explanation. + +## The mechanism, located by execution + +Instrumentation was added to the executing stage0 mirror (`v1_compiler_infer` +`record_lit_instantiated_fields`, `infer_record_lit_structural`), measured, and removed. + +1. The instantiation **does** reach the literal. For `ret_generic`: + `RLIF tn=Some("Box") exp_some=true exp_name=Some("Box") exp_children=1 decl_params=Some(1)` — + name compatible, arity matched, substitution branch entered. +2. The substitution is keyed correctly: `RLIF4 substkeys=["T"]`. +3. The declaration's field type node for `T` **carries no name to key on**: + `RLIF4 field="v" fte_authored="" fte_rawname="" identspan=false inferred=Other children=0 label=""`. + `substitute_generics` looks up `type_node_label(n)`, which is `""` here, so `T` is never + substituted. +4. So the expectation reaching the judgment is nameless: + `FT tn=Box fi=v expected_shape=Primitive() got_shape=Primitive(String)` + against the control `FT tn=Plain fi=v expected_shape=Primitive(Int) got_shape=Primitive(String)`. +5. `kernel_value_declared_type_mismatch` returns `false` the moment `formal_name == ""`. That + arm is the fail-open, and it is reached with a **nameless** formal, not a wrong one. + +A second, independent fail-open sits on the same path and is **not** the cause: the substitution +value is read with `resolved_type(n: arg)`, whose `Absent` arm is `error_type` — also a nameless +node — and a type-argument node carries no `inferred` (`arg_inferred=0`, +`subst_names=[("T", "")]`). So even had step 3 keyed, the value substituted in would have been +nameless too. Both must be closed; closing either alone changes nothing (measured, below). + +## Two repairs attempted and measured as NOT sufficient + +Recorded because they are the cost of the next attempt, not a reason to stop looking. Each was +built and run against the full arm table; **every arm was byte-identical to the table above**. + +1. **`record_lit_instantiated_fields` reads the type argument with `child_type_node` instead of + `resolved_type`.** Closes the `error_type`-as-substitution-value fail-open (step 5 above) and is + the existing authority for "the type this node stands for", already used at the list-element + seam in the same file. No arm moved, because step 3 means the substitution is never applied. +2. **`resolve_item_types` carries `tr.resolved` onto the field's `inferred`** in the record and + variant arms, which today compute the resolution of each field's authored type — with the type + parameters bound via `env_with_type_variable_bindings` — and then **discard `tr.resolved` + except for its `properties`**. No arm moved, which means the declaration inference reads is not + the one this arm produces. + +The discard in (2) is real and worth its own look; it is simply not on the path that feeds +`lookup_type_for` here. + +## What is still open — the next step, stated so it is not re-derived + +Where the `T` reference loses its name. The declaration reaching inference already carries a +field type node that is nameless, span-less and `CompilerError`-inferred, so the loss is upstream +of `resolve_item_types`' record arm. The specific question: **which stage produces the +`TypeBinding` that `lookup_type_for` returns for a generic type, and does it store the +pre- or post-`resolve_item_types` node?** (`build_type_env` in `v1.compiler.infer` is the +producer to read first; note its kernel `Present` payload uses the designed +`TypeVariable { id: ... }` representation, which is exactly what a type-parameter reference in a +generic declaration should resolve to and does not.) + +Until that is answered the repair is a modelling decision in a stage DESIGN names load-bearing, +not a targeted inference edit — which is why nothing is changed here. + +## Rung + +Source→acceptance, generic record field type: **below floor — not a rung** (§4b). The +non-generic position is at least mechanically preventable (executing wall, discriminating RED plus +positive control, both above). The class rung is the minimum across paths, so citing the +non-generic path would be inflation. Next-rung trigger: the open question above. From b4c59feb2ba0fe0b9b00046a00e75c8b0dc73290 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 11:26:32 +0000 Subject: [PATCH 02/17] Correct the mechanism: substitution is innocent, the class is any type declared WITH PARAMETERS, and the paired nonzero makes every zero a reading The first revision of this probe named the type-parameter reference losing its name as the cause. Two no-build discriminators falsify that, and a knowingly stale mechanism claim in a finding other lanes plan against is premise contamination -- so the doc is rewritten in one pass rather than annotated. WHAT CHANGED. A generic declaration whose parameter is UNUSED and whose field is a plain kernel type still fails open, so the trigger is that the declaration carries type parameters at all, not that a field mentions one. And forcing the instantiation to bail out with a wrong arity brings the field judgment back on the SAME declaration -- so record_lit_instantiated_fields does not fail to add an expectation, it preempts a working one. Instrumentation then showed authored_fte="" BEFORE substitution: substitution faithfully returns the nameless node it was given, and the declaration reached by the ident-keyed lookup is already identity-stripped where the name-keyed lookup's is not. PAIRED NONZERO. Every fail-open arm now carries a matched non-generic twin at the same seam, same run, same binary: six zeros, six reds. Plus an undeclared-name arm proving the generic module is compiled and its body judged. The twin design also rules out "that seam is unchecked for any type", which a bare perturbation would have left open. FOUR DEAD ENDS, ONE CAUSE, established by reading the construction site rather than by another build: ResolvedModule.module is the raw parsed node, build_type_env folds THOSE items into the bindings, and resolve_item_types runs later feeding resolved_item -- never the binding. ResolvedModule means import-resolved, not type-resolved. Also recorded: resolve_field is correct and has zero callers while its wired sibling resolve_field_init does not, which makes it an incomplete migration rather than dead scaffolding -- and a cleanup sweep deleting it would leave the lossy hand-rolled copy as the only authority. Claim staked on the PR. Still no code change: the remaining question is an ident-versus-intern address-space read, and a fifth blind repair would repeat the pattern the first four established. Co-Authored-By: Claude Opus 5 (1M context) --- ..._record_field_type_fail_open_2026-08-22.md | 222 +++++++++++------- 1 file changed, 134 insertions(+), 88 deletions(-) diff --git a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md index c3c801cd7ac..c304951ab35 100644 --- a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md +++ b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md @@ -1,107 +1,153 @@ -# A generic record literal admits the wrong field type silently, at six seams +# A record literal of a generic type admits the wrong field type silently, at six seams **Subject:** the v1 frontend (`gunbc compile`), source→`.dag`-acceptance path. **Ref:** built from `967b5bc1b9` (branch `session/calm-heron-887`), release `gunbc`, -built locally (`RUSTC_WRAPPER= CTRL_BUILD_MODE=local cargo build --release -p v1-compiler --bin gunbc`). -**Producer:** eleven single-module probe roots, each written from scratch, one module per arm +built locally (`RUSTC_WRAPPER= CTRL_BUILD_MODE=local cargo build --release -p v1-compiler --bin gunbc` +— sccache fails the `libc` build script). +**Producer:** single-module probe roots, each written from scratch, one module per arm (a blocking error truncates the diagnostic set, so arms must not share a module). ## The class DESIGN §4b names "values inhabit declared types" as the **ordinary compiler floor**, where a -failure is a below-baseline safety regression. A record literal of a **generic** type does not -hold that floor: the field expectation derived from the instantiation is a nameless node, and the -judgment that would refuse fails open on it. The wrong program is not merely un-refused — it is +failure is a below-baseline safety regression. A record literal of a type **declared with type +parameters** does not hold that floor. The wrong program is not merely un-refused — it is **emitted**. This is **below floor, not a rung on the ladder** (§4b), and it is the residue the `declared_type_conformance_diags` note in `v1.compiler.infer` already named as its own lane: *"generic record instantiation, and post-substitution generic field access."* -## Measured, with discriminating controls - -Every arm shares one preamble: `type Box { v: T }` and `type Plain { v: Int }`. - -| arm | source | RC | verdict | -|---|---|---|---| -| `ctl_pos` | `Plain { v: 1 }` | 0 | control: conforming non-generic compiles | -| `ctl_neg` | `Plain { v: "s" }` | 1 | control: **instrument reds** — `type mismatch: expected 'Primitive(Int)', got 'Primitive(String)'` | -| `ret_generic_pos` | `fn f() -> Box { Box { v: 1 } }` | 0 | control: conforming generic compiles | -| `ret_generic` | `fn f() -> Box { Box { v: "s" } }` | **0** | **fail-open, emits** | -| `let_generic` | `let x: Box = Box { v: "s" }` | **0** | **fail-open, emits** | -| `field_generic` | `Holder { b: Box { v: "s" } }`, `b: Box` | **0** | **fail-open, emits** | -| `list_generic` | `fn f() -> List> { [Box { v: "s" }] }` | **0** | **fail-open, emits** | -| `arg_generic` | `takes(b: Box { v: "s" })`, `fn takes(b: Box)` | **0** | **fail-open, emits** | -| `data_generic` | `data d: Box = Box { v: "s" }` | **0** | **fail-open, emits** | -| `missing_plain` | `Plain { }` | 1 | field **presence** holds | -| `missing_generic` | `Box { }` | 1 | field **presence** holds for generics too | - -Two facts the table settles that reasoning would not. **Six seams**, not one — every position that -knows an instantiation loses it, so this is a property of the shared machinery rather than of any -one caller. And the failure is confined to the field **type** axis: `missing_generic` refuses, so -field **completeness** is unaffected, which rules out "generic declarations are simply not -processed" as the explanation. - -## The mechanism, located by execution - -Instrumentation was added to the executing stage0 mirror (`v1_compiler_infer` -`record_lit_instantiated_fields`, `infer_record_lit_structural`), measured, and removed. - -1. The instantiation **does** reach the literal. For `ret_generic`: - `RLIF tn=Some("Box") exp_some=true exp_name=Some("Box") exp_children=1 decl_params=Some(1)` — - name compatible, arity matched, substitution branch entered. -2. The substitution is keyed correctly: `RLIF4 substkeys=["T"]`. -3. The declaration's field type node for `T` **carries no name to key on**: - `RLIF4 field="v" fte_authored="" fte_rawname="" identspan=false inferred=Other children=0 label=""`. - `substitute_generics` looks up `type_node_label(n)`, which is `""` here, so `T` is never - substituted. -4. So the expectation reaching the judgment is nameless: - `FT tn=Box fi=v expected_shape=Primitive() got_shape=Primitive(String)` - against the control `FT tn=Plain fi=v expected_shape=Primitive(Int) got_shape=Primitive(String)`. -5. `kernel_value_declared_type_mismatch` returns `false` the moment `formal_name == ""`. That - arm is the fail-open, and it is reached with a **nameless** formal, not a wrong one. - -A second, independent fail-open sits on the same path and is **not** the cause: the substitution -value is read with `resolved_type(n: arg)`, whose `Absent` arm is `error_type` — also a nameless -node — and a type-argument node carries no `inferred` (`arg_inferred=0`, -`subst_names=[("T", "")]`). So even had step 3 keyed, the value substituted in would have been -nameless too. Both must be closed; closing either alone changes nothing (measured, below). - -## Two repairs attempted and measured as NOT sufficient +## Measured, with a paired nonzero on every zero + +The instrument's silence had to be shown to be a reading rather than an instrument failure, so +**every fail-open arm carries a matched non-generic twin at the same seam**, in the same run, on +the same binary. Preamble `type Box { v: T }` / `type Plain { v: Int }`; the offending value is +`"s"` against a declared `Int` in every row. + +| seam | generic | non-generic twin | +|---|---|---| +| fn return | `fn f() -> Box { Box { v: "s" } }` → **RC=0, emits** | `Plain` → **RC=1** | +| let annotation | `let x: Box = ...` → **RC=0, emits** | `Plain` → **RC=1** | +| record field | `Holder { b: Box { v: "s" } }` → **RC=0, emits** | `Plain` → **RC=1** | +| list element | `[Box { v: "s" }]` → **RC=0, emits** | `Plain` → **RC=1** | +| call argument | `takes(b: Box { v: "s" })` → **RC=0, emits** | `Plain` → **RC=1** | +| module-scope `data` | `data d: Box = ...` → **RC=0, emits** | `Plain` → **RC=1** | + +Every twin refuses with a located `type mismatch: expected 'Primitive(Int)', got +'Primitive(String)'`. A third control, `ret_gen_undecl` — an undeclared name inside the generic +literal — returns **RC=1**, so the generic module is genuinely compiled and its body judged. + +The twin design does more than prove the instrument is live: it rules out *"that seam is simply +unchecked for any type"*, which a bare perturbation would have left open. + +## Two discriminators that moved the diagnosis twice + +**It is not about the type-parameter reference.** A generic declaration whose parameter is +**unused** and whose field is a plain kernel type still fails open: + +``` +type BoxI { v: Int } fn f() -> BoxI { BoxI { v: "s" } } -> RC=0, emits +type Mix { k: Int t: T } wrong value in the `k: Int` field -> RC=0, emits +``` + +So the trigger is that the declaration **carries type parameters at all**, not that a field +*mentions* one. + +**The instantiated path is strictly worse than the fallback it preempts.** Force the instantiation +to bail out by supplying the wrong arity, and the field judgment on the *same declaration* comes +back: + +``` +arity_bail_bad type BoxI { v: Int } fn f() -> BoxI { BoxI { v: "s" } } + RC=1 type BoxI expects 1 type arguments, got 2 + RC=1 type mismatch: expected 'Primitive(Int)', got 'Primitive(String)' <-- FIRES +arity_fire_bad type BoxI { v: Int } fn f() -> BoxI { BoxI { v: "s" } } + RC=0 compiled, 0 diagnostics <-- preempted, silent +arity_mono_bad type BoxI { v: Int } fn f() -> BoxI { BoxI { v: "s" } } + RC=1 type mismatch: expected 'Primitive(Int)', got 'Primitive(String)' +``` + +`record_lit_instantiated_fields` does not merely fail to *add* an expectation — it **preempts a +working one**. + +## The mechanism, located + +Instrumentation was added to the executing stage0 mirror, measured, and removed. On +`arity_fire_bad` — a generic declaration whose field is the kernel type `Int`: + +``` +INST field="v" authored_fte="" authored_shape=Primitive() substituted_shape=Primitive() +FT tn=BoxI fi=v expected_shape=Primitive() got_shape=Primitive(String) +``` + +against the non-generic twin: + +``` +FT tn=BoxI fi=v expected_shape=Primitive(Int) got_shape=Primitive(String) +``` + +`authored_fte=""` is measured **before** substitution. **Substitution is innocent** — it faithfully +returns the nameless node it was given. The declaration reached by the instantiated path already +carries field type nodes stripped of their identity, while the declaration reached by the fallback +path, *for the same declaration in the same module*, carries named ones. + +The two paths differ only in how they reach the declaration: + +- instantiated path — `lookup_type_for(env, exp)`, keyed on the **expected node's `ident`** +- fallback path — `lookup_type_by_name(env, tn)`, keyed on the **name** + +Both read `binding.resolved`, so a single binding cannot explain the divergence; the ident-keyed +route is reaching a different, identity-stripped node. `lookup_binding(env, ident)` does +`map_get(env.bindings, ident)` and, on a miss, feeds the same integer to +`intern_str(table, id)` and retries **by name** — so an occurrence id and an intern id are being +read out of one integer slot. That address-space question is where the next attempt should start. + +Once the expectation is nameless, `kernel_value_declared_type_mismatch` returns `false` on +`formal_name == ""`. **That arm is a second, independent fail-open and deserves its own repair +even after the upstream one lands**: an upstream fix removes today's population, not the arm that +converts a nameless expectation into silence for whatever produces one next. + +## Four repairs attempted and measured as NOT sufficient Recorded because they are the cost of the next attempt, not a reason to stop looking. Each was -built and run against the full arm table; **every arm was byte-identical to the table above**. - -1. **`record_lit_instantiated_fields` reads the type argument with `child_type_node` instead of - `resolved_type`.** Closes the `error_type`-as-substitution-value fail-open (step 5 above) and is - the existing authority for "the type this node stands for", already used at the list-element - seam in the same file. No arm moved, because step 3 means the substitution is never applied. -2. **`resolve_item_types` carries `tr.resolved` onto the field's `inferred`** in the record and - variant arms, which today compute the resolution of each field's authored type — with the type - parameters bound via `env_with_type_variable_bindings` — and then **discard `tr.resolved` - except for its `properties`**. No arm moved, which means the declaration inference reads is not - the one this arm produces. - -The discard in (2) is real and worth its own look; it is simply not on the path that feeds -`lookup_type_for` here. - -## What is still open — the next step, stated so it is not re-derived - -Where the `T` reference loses its name. The declaration reaching inference already carries a -field type node that is nameless, span-less and `CompilerError`-inferred, so the loss is upstream -of `resolve_item_types`' record arm. The specific question: **which stage produces the -`TypeBinding` that `lookup_type_for` returns for a generic type, and does it store the -pre- or post-`resolve_item_types` node?** (`build_type_env` in `v1.compiler.infer` is the -producer to read first; note its kernel `Present` payload uses the designed -`TypeVariable { id: ... }` representation, which is exactly what a type-parameter reference in a -generic declaration should resolve to and does not.) - -Until that is answered the repair is a modelling decision in a stage DESIGN names load-bearing, -not a targeted inference edit — which is why nothing is changed here. +built and run against the full arm table; **every arm was byte-identical** each time. + +1. `record_lit_instantiated_fields` reading the type argument with `child_type_node` instead of + `resolved_type`. Closes a real second-order fail-open — `resolved_type`'s `Absent` arm is + `error_type`, itself nameless, and a type-argument node carries no `inferred` — but the + substitution is never applied, so nothing moves. +2. `resolve_item_types` carrying `tr.resolved` onto the field's `inferred`. +3. `resolve_item_types` installing `tr.resolved` as the field's **type_expr child** (`children[0]`), + which is what `record_lit_instantiated_fields` actually reads. Correct slot, wrong function. +4. *(implied by 2 and 3)* anything else in `resolve_item_types`. + +**One cause for all of them, established by reading the construction site rather than by another +build:** `ResolvedModule.module` is `module_occurrence_input_node(input)` — the raw +parsed/normalized node. `build_type_env`'s `local_bindings` folds **those** items through +`local_binding_for_item`, which copies `children` verbatim. `resolve_item_types` runs later, inside +`analyze_item`, and its output feeds `resolved_item` — **never the binding**. So `ResolvedModule` +means *import*-resolved, not *type*-resolved, and three repair cycles were spent editing a +function whose output the binding never sees. + +## Found on the way, worth its own row + +`v1.compiler.resolve` `resolve_field` does the right thing — it installs `type_resolved` into the +field via `make_field_node` — and has **zero callers**, while `resolve_item_types` hand-rolls a +lossy version beside it that discards `tr.resolved` except for its `properties`. Its sibling +`resolve_field_init` *is* wired, which makes this an **incomplete migration** rather than +abandoned scaffolding. It is emitted into the stage0 mirror, so the seed pays for it today. + +Two authorities for "resolve a field", the correct one dead and the lossy one live, is a §3 +violation at the grain §3 forbids. It is **not** established as this lane's repair — the +discriminators above moved the cause off it — but a cleanup sweep would be entitled to delete it +as a §5 dead scaffold, and that would remove a correct implementation while leaving the lossy one +as the only authority. Claim staked on gunbc#8901. ## Rung -Source→acceptance, generic record field type: **below floor — not a rung** (§4b). The -non-generic position is at least mechanically preventable (executing wall, discriminating RED plus -positive control, both above). The class rung is the minimum across paths, so citing the -non-generic path would be inflation. Next-rung trigger: the open question above. +Source→acceptance, record-literal field type on a type declared with parameters: **below floor — +not a rung** (§4b). The non-generic position is at least mechanically preventable (executing wall, +discriminating RED plus positive control, both above). The class rung is the minimum across paths, +so citing the non-generic path would be inflation. Next-rung trigger: the ident-versus-intern +address-space question above. From 84c65c3124175544e956e460fdfeef700f938a0f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 12:17:55 +0000 Subject: [PATCH 03/17] The class is two rows, and the corpus reds the closed one: report it rather than narrow the wall (#8901) --- ..._record_field_type_fail_open_2026-08-22.md | 125 +++++++++++++----- 1 file changed, 94 insertions(+), 31 deletions(-) diff --git a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md index c304951ab35..44fa5bb8f13 100644 --- a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md +++ b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md @@ -108,46 +108,109 @@ Once the expectation is nameless, `kernel_value_declared_type_mismatch` returns even after the upstream one lands**: an upstream fix removes today's population, not the arm that converts a nameless expectation into silence for whatever produces one next. -## Four repairs attempted and measured as NOT sufficient +## The class is TWO rows, not one -Recorded because they are the cost of the next attempt, not a reason to stop looking. Each was -built and run against the full arm table; **every arm was byte-identical** each time. +Two stacked defects, which is why every single-cause theory died in turn. + +### Row (a) — concrete-typed field in a parameter-carrying declaration. CAUSE FOUND, repair measured and NOT landable. + +`type BoxI { v: Int }` — parameter declared but **unused**, field a plain kernel type — fails +open at `BoxI { v: "s" }` against `BoxI`. So the trigger is that the declaration carries type +parameters at all, not that a field mentions one. + +**Cause, measured:** a field node carries its declared type in `sf.inferred`; `children[0]` is a +stripped placeholder (`inf=true`, `field_node_type_expr` authored name `""`). +`record_lit_instantiated_fields` substitutes into `field_node_type_expr(sf)` — the placeholder — +while every other consumer reads `sf.inferred` first. Two readings of one field, and the +instantiated path took the wrong one, so it **preempted a working expectation with a nameless +node**. Forcing the instantiation to bail out on a wrong arity brings the judgment back on the same +declaration, which is what proves the preemption: + +``` +arity_bail_bad BoxI RC=1 arity error + RC=1 type mismatch <-- judgment FIRES +arity_fire_bad BoxI RC=0 compiled, 0 diagnostics <-- preempted, silent +arity_mono_bad non-generic RC=1 type mismatch +``` + +**Repair built:** extract `field_declared_type_node` as the single authority for "a field's declared +type node" (`sf.inferred` first, `field_node_type_expr` as fallback) and point both the instantiated +path and the consumption site at it. `kernelfield_gen_bad` flips **RC=0 → RC=1** with a located +`expected 'Primitive(Int)', got 'Primitive(String)'`; `kernelfield_gen_ok` stays green. + +**Why it is NOT landed — the corpus refuses it.** Whole-tree compile, `dag` + `src/v2`, at +`b4c59feb2b`. Baseline (unpatched, same tree, same binary vintage): **2** hard diagnostics, both +unrelated (`workflow CLI default`, `dag/gunbc/tools/review_codex.dag`). Patched: the run emits +**12** diagnostics over **8** files, none of which the baseline emits: + +- **8 × `empty list literal: expected type is not a collection`** — `dag/std/claim_evidence.dag`, + `dag/gunbc/source_integration_landing_spine.dag`, `src/v2/std/bounded_lattice_completeness.dag` + (×2), `dag/extdeps/git/object_store.dag` (×2), `src/v2/lens/mandatory_tag.dag`, + `dag/test/claim/host_effect_plan_witness_test.dag`. Every one a `fn(_) { [] }` / `fn(l) { [l] }` + lambda body in a **function-typed** generic field (`EvidenceInferenceFold` and kin). With the + substitution now producing a real type, the expectation reaching the lambda body is the + **function type instead of its return type**. That is the repair being *incomplete*, not wrong, + and it is the single next thing to fix. +- **4 × frontier-row count mismatch on receiver type `Primitive()`** — `any`/`map`/`flat_map` in + `dag/extdeps/mercurial.dag`, `dag/gunbc/scm_compatibility/mercurial.dag`, + `dag/extdeps/git/object_store.dag` (×2). Downstream census rows keyed on a receiver type that + changes once the expectation is real. + +The repair is recorded here rather than shipped because narrowing it until the corpus greens is how +a wall keeps its name and loses its population. What the measurement actually shows is that **the +instantiated path's silence was masking these representation gaps**, so the wall cannot land ahead +of them. + +### Row (b) — type-parameter-typed field (`v: T`). OPEN. + +All six seams still RC=0 under the row (a) repair, and `Pair { a: A, b: B }` with them. +`sf.inferred` for a `v: T` field holds a nameless node, because `T` is not resolvable when the +binding is constructed. Distinct from (a) and unaddressed. + +## Repairs attempted and measured as NOT sufficient + +Recorded because they are the cost of the next attempt. Each was built and run against the full arm +table; **every arm was byte-identical** each time. 1. `record_lit_instantiated_fields` reading the type argument with `child_type_node` instead of `resolved_type`. Closes a real second-order fail-open — `resolved_type`'s `Absent` arm is - `error_type`, itself nameless, and a type-argument node carries no `inferred` — but the - substitution is never applied, so nothing moves. + `error_type`, itself nameless — but the substitution is never applied, so nothing moves. 2. `resolve_item_types` carrying `tr.resolved` onto the field's `inferred`. -3. `resolve_item_types` installing `tr.resolved` as the field's **type_expr child** (`children[0]`), - which is what `record_lit_instantiated_fields` actually reads. Correct slot, wrong function. -4. *(implied by 2 and 3)* anything else in `resolve_item_types`. - -**One cause for all of them, established by reading the construction site rather than by another -build:** `ResolvedModule.module` is `module_occurrence_input_node(input)` — the raw -parsed/normalized node. `build_type_env`'s `local_bindings` folds **those** items through -`local_binding_for_item`, which copies `children` verbatim. `resolve_item_types` runs later, inside -`analyze_item`, and its output feeds `resolved_item` — **never the binding**. So `ResolvedModule` -means *import*-resolved, not *type*-resolved, and three repair cycles were spent editing a -function whose output the binding never sees. +3. `resolve_item_types` installing `tr.resolved` as the field's type_expr child (`children[0]`). -## Found on the way, worth its own row +**One cause for all three, established by reading the construction site rather than by another +build:** `ResolvedModule.module` is `module_occurrence_input_node(input)` — the raw parsed node. +`build_type_env`'s `local_bindings` folds **those** items through `local_binding_for_item`, which +copies `children` verbatim. `resolve_item_types` runs later, inside `analyze_item`, and its output +feeds `resolved_item` — **never the binding**. `ResolvedModule` means *import*-resolved, not +*type*-resolved. + +## A refuted lead, recorded so it is not re-run -`v1.compiler.resolve` `resolve_field` does the right thing — it installs `type_resolved` into the -field via `make_field_node` — and has **zero callers**, while `resolve_item_types` hand-rolls a -lossy version beside it that discards `tr.resolved` except for its `properties`. Its sibling -`resolve_field_init` *is* wired, which makes this an **incomplete migration** rather than -abandoned scaffolding. It is emitted into the stage0 mirror, so the seed pays for it today. +The ident-versus-intern address-space theory is **dead**, by source read plus measurement. +`Node.ident` is set from `intern(...).id` in exactly three places — the module node and two import +nodes — so a type use site carries `ident=None`; measured `exp_ident=None`, the ident arm is never +taken, and both `lookup_type_for` and `lookup_type_by_name` return **identical** field lists. + +Two §5 defects were found on that path and are real but unrelated to this bug, each worth its own +row: `intern_str` returns `""` on a miss in a `String`-not-`String?` carrier, so a refusal is +unrepresentable — and its arm is **unreachable from all three live call sites**, since the other two +iterate `map_keys(bindings)`, which are intern ids by construction, so it can be proved dead and +deleted. And `lookup_binding` does not refuse on a miss; it retries through a different lookup, +uncounted. + +## Found on the way, worth its own row -Two authorities for "resolve a field", the correct one dead and the lossy one live, is a §3 -violation at the grain §3 forbids. It is **not** established as this lane's repair — the -discriminators above moved the cause off it — but a cleanup sweep would be entitled to delete it -as a §5 dead scaffold, and that would remove a correct implementation while leaving the lossy one -as the only authority. Claim staked on gunbc#8901. +`v1.compiler.resolve` `resolve_field` installs `type_resolved` into the field via `make_field_node` +and has **zero callers**, while `resolve_item_types` hand-rolls a lossy version beside it. Its +sibling `resolve_field_init` *is* wired, which makes this an **incomplete migration** rather than +abandoned scaffolding, and it is emitted into the stage0 mirror. It is **not** this lane's repair — +the discriminators moved the cause off it — but a cleanup sweep would be entitled to delete it as a +§5 dead scaffold and leave the lossy copy as the only authority. Claim staked on gunbc#8901. ## Rung Source→acceptance, record-literal field type on a type declared with parameters: **below floor — -not a rung** (§4b). The non-generic position is at least mechanically preventable (executing wall, -discriminating RED plus positive control, both above). The class rung is the minimum across paths, -so citing the non-generic path would be inflation. Next-rung trigger: the ident-versus-intern -address-space question above. +not a rung** (§4b), for both rows. Row (a) has a cause and a measured repair blocked on the +function-typed-field propagation above; row (b) has neither. The non-generic position is at least +mechanically preventable. Class rung is the minimum across paths, so citing the non-generic path +would be inflation. From 6552623137c9ac233cc59dcf8110fc0497b87ca7 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 12:20:10 +0000 Subject: [PATCH 04/17] The 8 and the 4 have different dispositions: the census rows encode the old answer (#8901) --- ..._record_field_type_fail_open_2026-08-22.md | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md index 44fa5bb8f13..6455b6b0f00 100644 --- a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md +++ b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md @@ -108,7 +108,7 @@ Once the expectation is nameless, `kernel_value_declared_type_mismatch` returns even after the upstream one lands**: an upstream fix removes today's population, not the arm that converts a nameless expectation into silence for whatever produces one next. -## The class is TWO rows, not one +## The class is THREE rows, plus four census rows of settled disposition Two stacked defects, which is why every single-cause theory died in turn. @@ -150,16 +150,43 @@ unrelated (`workflow CLI default`, `dag/gunbc/tools/review_codex.dag`). Patched: substitution now producing a real type, the expectation reaching the lambda body is the **function type instead of its return type**. That is the repair being *incomplete*, not wrong, and it is the single next thing to fix. -- **4 × frontier-row count mismatch on receiver type `Primitive()`** — `any`/`map`/`flat_map` in - `dag/extdeps/mercurial.dag`, `dag/gunbc/scm_compatibility/mercurial.dag`, - `dag/extdeps/git/object_store.dag` (×2). Downstream census rows keyed on a receiver type that - changes once the expectation is real. +- **4 × frontier-row count mismatch on receiver type `Primitive()`** — `extdeps.git.object_store` + (`map`, `flat_map`), `extdeps.mercurial` (`any`), `gunbc.scm_compatibility.mercurial` (`map`). + **These are not reds on correct code, and the row read is what establishes it.** Each is a + declared row in `v1.compiler.infer` `unresolved_method_frontier`, keyed on receiver shape + `Primitive()` — the `ReceiverTypeUnestablished` class, whose declared cause is deficit (2) in + `method_existence_wall_note`: *a lambda parameter receiver whose type never propagates from the + declared fn type it is bound under*, naming the `StoreObjectFold` lambdas in `object_store` + explicitly. That is precisely the population row (a) starts supplying real types to, and the row's + own diagnostic states the contract in both directions: fewer observed means *the deficit has + partly dissolved and the row must be lowered or deleted so the ratchet keeps its new ground*. So + these rows **encode the old, nameless answer**, and the ratchet firing is the repair working. + + Two honesty limits on that, stated rather than assumed. The **direction is inferred, not + measured** — the counts ride on the diagnostic as fields and are absent from the captured message + text, so a rerun must confirm *fewer* rather than *more*. And the two `object_store` rows are + **confounded**: that module also carries two of the eight blocking empty-list errors, and a + blocking error truncates the diagnostic set, which lowers an observed count for a reason that has + nothing to do with the deficit. The two Mercurial rows carry **no** blocking error in the same + run, so they are the unconfounded pair and the ones to read first. + + Not to be resolved by editing the counts. An expectation row edited to match new behaviour is + indistinguishable from one edited to silence a regression unless the correct receiver type is + established first — that is narrowing the wall in costume. The repair is recorded here rather than shipped because narrowing it until the corpus greens is how a wall keeps its name and loses its population. What the measurement actually shows is that **the instantiated path's silence was masking these representation gaps**, so the wall cannot land ahead of them. +### Row (c) — expectation not projected through an arrow. NEW, 8 sites, exposed by (a). + +At a lambda body inside a **function-typed** generic field, the substituted expectation arrives as +the *function* type rather than its *return* type, so `fn(_) { [] }` fails with `empty list literal: +expected type is not a collection`. **A second finding, not a cost of the first** — the position was +unreachable before, because nothing ever delivered a real type to it. Row (a) cannot land ahead of +this, so this is where the next owner starts. + ### Row (b) — type-parameter-typed field (`v: T`). OPEN. All six seams still RC=0 under the row (a) repair, and `Pair { a: A, b: B }` with them. @@ -210,7 +237,7 @@ the discriminators moved the cause off it — but a cleanup sweep would be entit ## Rung Source→acceptance, record-literal field type on a type declared with parameters: **below floor — -not a rung** (§4b), for both rows. Row (a) has a cause and a measured repair blocked on the -function-typed-field propagation above; row (b) has neither. The non-generic position is at least +not a rung** (§4b), for both rows. Row (a) has a cause and a measured repair blocked on +row (c); row (c) has a located population and no repair; row (b) has neither. The non-generic position is at least mechanically preventable. Class rung is the minimum across paths, so citing the non-generic path would be inflation. From e636acac088fcd5d959c677c97b740e97e7163fc Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 12:23:00 +0000 Subject: [PATCH 05/17] LexMatchThunk is not generic, so it is none of the three rows: a fourth mechanism, bounded by three baseline arms (#8901) --- ..._record_field_type_fail_open_2026-08-22.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md index 6455b6b0f00..c76eb2e0672 100644 --- a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md +++ b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md @@ -187,6 +187,41 @@ expected type is not a collection`. **A second finding, not a cost of the first* unreachable before, because nothing ever delivered a real type to it. Row (a) cannot land ahead of this, so this is where the next owner starts. +### The `LexMatchThunk` row is NOT (a), (b) or (c) — refuted by source read plus execution + +The `v2.compiler.tokenize` `apply` frontier row (7 occurrences) was proposed as possibly being +row (b). It is not, and the declaration settles it in one line: + +``` +type LexMatchThunk { + apply: fn(String) -> LexMatchResult +} +``` + +**No type parameters, and `apply` is a concrete function type.** So `record_lit_instantiated_fields` +never runs for it — row (a)'s repair could not reach it, which is exactly why it did not move — and +there is no type-parameter-typed field for row (b) to be about. + +Three arms on the **baseline, unpatched** binary make the boundary sharp, and two of them were +surprises: + +| arm | result | +|---|---| +| `apply: fn(String) -> String`, body `fn(s) { [] }` | RC=1, `expected type is not a collection` — **correct refusal** | +| `apply: fn(String) -> List`, body `fn(s) { [] }` | RC=0, clean — **the arrow IS projected** | +| `apply: fn(String) -> String`, body `fn(s) { s \|> no_such_method() }` | RC=1, `not found on receiver type 'Primitive(String)'` — **the parameter type DOES propagate** | + +Two consequences. **Row (c) is specific to the substituted path** — the non-generic path projects +through the arrow correctly, so the function-type-instead-of-return-type expectation is produced by +the substitution, not inherited from a general defect. And **the minimal non-generic reproduction +does not reproduce the frontier row at all**: a lambda parameter bound under a concrete fn-typed +field gets a real receiver type here. So whatever puts those 7 occurrences at `Primitive()` is +narrower than the class name `a lambda parameter receiver whose type never propagates from the +declared fn type it is bound under` suggests — the real sites bind the thunk through `LexRule` and +nested constructions, and one of those layers is where the type is lost. That is a **fourth +mechanism**, unowned, and the minimal arms above are the starting point for it rather than the +class description. + ### Row (b) — type-parameter-typed field (`v: T`). OPEN. All six seams still RC=0 under the row (a) repair, and `Pair { a: A, b: B }` with them. From 871e2eae4f197a8c87172f5c7508786654529a62 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 12:30:27 +0000 Subject: [PATCH 06/17] Withdrawn: the generic carrier is the algebra, not the thunk -- one-variable pair puts the tokenize row in row (b) (#8901) --- ..._record_field_type_fail_open_2026-08-22.md | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md index c76eb2e0672..9d90c03e81e 100644 --- a/docs/probes/generic_record_field_type_fail_open_2026-08-22.md +++ b/docs/probes/generic_record_field_type_fail_open_2026-08-22.md @@ -187,40 +187,45 @@ expected type is not a collection`. **A second finding, not a cost of the first* unreachable before, because nothing ever delivered a real type to it. Row (a) cannot land ahead of this, so this is where the next owner starts. -### The `LexMatchThunk` row is NOT (a), (b) or (c) — refuted by source read plus execution +### The `LexMatchThunk` row IS a generic-instantiation gap — and row (b) now has a minimal reproduction -The `v2.compiler.tokenize` `apply` frontier row (7 occurrences) was proposed as possibly being -row (b). It is not, and the declaration settles it in one line: +**A withdrawn finding, kept because the mistake is the transferable part.** I first read +`type LexMatchThunk { apply: fn(String) -> LexMatchResult }`, saw no type parameters, and concluded +the frontier row was a fourth mechanism outside (a), (b) and (c). **That was wrong, and it was wrong +by the exact move I had just criticised** — linking "the thunk is not generic" to "the row is not a +generic-instantiation gap" by shared vocabulary. The thunk's own concreteness never enters the +question. The generic carrier is the **algebra**: ``` -type LexMatchThunk { - apply: fn(String) -> LexMatchResult -} +std.compilers.lexing type LexPatternFold { ... delimited: fn(R, R, R) -> R } +v2.compiler.tokenize delimited: fn(open_r, body_r, close_r) { match open_r.apply(s) { ... } } ``` -**No type parameters, and `apply` is a concrete function type.** So `record_lit_instantiated_fields` -never runs for it — row (a)'s repair could not reach it, which is exactly why it did not move — and -there is no type-parameter-typed field for row (b) to be about. - -Three arms on the **baseline, unpatched** binary make the boundary sharp, and two of them were -surprises: - -| arm | result | -|---|---| -| `apply: fn(String) -> String`, body `fn(s) { [] }` | RC=1, `expected type is not a collection` — **correct refusal** | -| `apply: fn(String) -> List`, body `fn(s) { [] }` | RC=0, clean — **the arrow IS projected** | -| `apply: fn(String) -> String`, body `fn(s) { s \|> no_such_method() }` | RC=1, `not found on receiver type 'Primitive(String)'` — **the parameter type DOES propagate** | - -Two consequences. **Row (c) is specific to the substituted path** — the non-generic path projects -through the arrow correctly, so the function-type-instead-of-return-type expectation is produced by -the substitution, not inherited from a general defect. And **the minimal non-generic reproduction -does not reproduce the frontier row at all**: a lambda parameter bound under a concrete fn-typed -field gets a real receiver type here. So whatever puts those 7 occurrences at `Primitive()` is -narrower than the class name `a lambda parameter receiver whose type never propagates from the -declared fn type it is bound under` suggests — the real sites bind the thunk through `LexRule` and -nested constructions, and one of those layers is where the type is lost. That is a **fourth -mechanism**, unowned, and the minimal arms above are the starting point for it rather than the -class description. +`open_r` is a lambda parameter whose **declared type is `R`**, a type variable, instantiated at +`R = LexMatchThunk`. My three arms above omitted that variable, so they are the **control** arm, not +a refutation. + +The discriminating pair, one variable, on the pristine baseline binary: + +| arm | carrier | result | +|---|---|---| +| `arm_a` | `type Fold { delimited: fn(Thunk, Thunk) -> String }` — **non-generic** | RC=0, clean | +| `arm_b` | `type Fold { delimited: fn(R, R) -> String }` at `Fold` | RC=1, `receiver type 'Primitive()' establishes no method surface` | + +Same file, same thunk, same body, same `open_r.apply(...)` call. **The generic algebra is the whole +difference**, and `arm_b` reproduces the frontier row's diagnostic verbatim. + +So the `apply` row belongs to **row (b)**, and (b) is bigger and better-founded than the six seams it +was measured on: it now has a minimal reproduction, a named cause — *a type-parameter-typed position +loses its type at instantiation*, whether that position is a **field value** (the six seams) or a +**lambda parameter's declared type** (this row) — and a 7-occurrence frontier population. The +earlier "fourth unowned mechanism" row is **withdrawn**, not held: it rested on a reproduction that +dropped the variable. + +Two things this does **not** establish, kept separate on purpose. The 68 masked `E0599` sites are +`E0308`s *behind* the mask rather than the 7 sites that *are* it, and they have not been shown to be +one population. And the `object_store` rows share the `Primitive()` **key**, which is a shape, not a +mechanism. ### Row (b) — type-parameter-typed field (`v: T`). OPEN. From 6df8af291546546315564fe2ff790fd23995a5cf Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 17:51:11 +0000 Subject: [PATCH 07/17] =?UTF-8?q?WIP:=20(a)=20fork=20dissolution=20?= =?UTF-8?q?=E2=80=94=20field=5Fdeclared=5Ftype=5Fnode,=20authority=20+=20m?= =?UTF-8?q?irror?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v1/04_infer.dag | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index 52750796976..c4c11ebc6ab 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -1112,6 +1112,13 @@ fn record_lit_fields_from_expected(type_name: String?, expected: Node?, scope: I } } +fn field_declared_type_node(sf: Node) -> Node { + match sf.inferred { + Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) + _ => field_node_type_expr(n: sf) + } +} + fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: InferScope) -> List? { match type_name { Present { value: tn } => @@ -1139,7 +1146,7 @@ fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: In Node { name: sf.name, span: sf.span, ident_span: sf.ident_span, children: sf.children, connective: sf.connective, params: sf.params, - inferred: Present { value: Resolved { node: substitute_generics(n: field_node_type_expr(n: sf), subst: subst, source_indices: scope.type_env.source_indices) } }, + inferred: Present { value: Resolved { node: substitute_generics(n: field_declared_type_node(sf: sf), subst: subst, source_indices: scope.type_env.source_indices) } }, return_cardinality: sf.return_cardinality, uses: sf.uses, body: sf.body, transport: sf.transport, properties: sf.properties, type_annotation: sf.type_annotation, is_self_recursive: sf.is_self_recursive, @@ -5398,11 +5405,7 @@ fn infer_record_lit_structural(type_name: String?, field_inits: List, span } let field_declared_type = match struct_fields |> filter(sf => authored_name_at(source_indices: scope.type_env.source_indices, node: sf) == fi_name) |> first { Present { value: sf } => - let ft = match sf.inferred { - Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) - _ => field_node_type_expr(n: sf) - } - Present { value: ft } + Present { value: field_declared_type_node(sf: sf) } Absent => none } let field_expected = match field_declared_type { From 57990aff1b6b9330bb3a38d567065060bfae3ffb Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 18:21:45 +0000 Subject: [PATCH 08/17] (a) mirror half restored: field_declared_type_node in v1_compiler_infer.rs --- .patched_infer_backup.rs | 21414 +++++++++++++++++++++++ src/v1/stage0/src/v1_compiler_infer.rs | 23 +- 2 files changed, 21427 insertions(+), 10 deletions(-) create mode 100644 .patched_infer_backup.rs diff --git a/.patched_infer_backup.rs b/.patched_infer_backup.rs new file mode 100644 index 00000000000..e05b724cef1 --- /dev/null +++ b/.patched_infer_backup.rs @@ -0,0 +1,21414 @@ +// Generated by v1 compiler -- do not edit. +// Source module: v1.compiler.infer + +use self::DescentSizeExpr::*; +pub use crate::extdeps_container_oci_digest::{ + oci_other_digest_algorithm, oci_other_digest_encoded, +}; +pub use crate::std_algebra::AlgebraFieldTemplate; +use crate::std_algebra::CollectionSizeEffect::ShrinkEffect; +pub use crate::std_algebra::{CollectionSizeEffect, FreeMonoid}; +pub use crate::std_coercion::{dag_can_cast, is_dag_cast_domain_type}; +pub use crate::std_computation::ShrinkFactor; +use crate::std_computation::ShrinkFactor::{ConstantShrink, ProportionalShrink, UnitShrink}; +use crate::std_content_hash::ContentHash::*; +pub use crate::std_content_hash::{ + content_hash_atom, content_hash_combine_structural, content_hash_tagged_structural, + content_hash_validate_lower_hex_length, +}; +pub use crate::std_content_hash::{ContentHash, Fnv1a64Structural}; +pub use crate::std_dissolution::DissolutionCondition; +use crate::std_dissolution::DissolutionCondition::*; +pub use crate::std_dissolution::{dissolution_description, unbound_dissolution}; +use crate::std_induction::RecursionShape::{ + DirectRecursion, ListRecursion, MapValueRecursion, OptionalRecursion, SetRecursion, +}; +use crate::std_induction::SubValueRelation::{ + ArithmeticDescent, IteratedSubValue, MixedTop, NonIncreasingValue, PreservedValue, + StrictAxisErased, StrictSubValue, SubValueUnknown, +}; +pub use crate::std_induction::{ + compose_sub_value, compose_sub_value_relations, join_sub_value, meet_sub_value, + sub_value_to_evidence, +}; +pub use crate::std_induction::{InductiveField, RecursionShape, SubValueRelation}; +use crate::std_interface_summary::ExportKind::{ExportData, ExportFn, ExportService, ExportType}; +pub use crate::std_interface_summary::{interface_summary_rollup, signature_contract}; +pub use crate::std_interface_summary::{ExportEntry, ExportKind, InterfaceSummary}; +pub use crate::std_node::{compiler_inductive_fields, compiler_recursive_types}; +pub use crate::std_occurrence_identity::OccurrenceId; +use crate::std_syntax::BinOp::Add; +use crate::std_syntax::BinOp::{And, Div, Eq, Ge, Gt, Le, Lt, Mod, Mul, Ne, NullCoalesce, Or, Sub}; +use crate::std_syntax::LiteralValue::LitStr; +use crate::std_syntax::LiteralValue::{LitBool, LitFloat, LitInt, LitNull}; +pub use crate::std_syntax::{BinOp, LiteralValue}; +pub use crate::std_termination::PositiveDescentAmount; +use crate::std_termination::PositiveDescentAmount::OneStep; +pub use crate::std_termination::{ + positive_descent_amount_from_positive_int, proportional_divisor_from_int_at_least_two, +}; +pub use crate::std_types::{container_param_name, is_kernel_type, kernel_type_set}; +pub use crate::std_types::{NonEmptyStr, SourceSpan}; +pub use crate::v1_compiler_infer_access::AccessCheckResultNode; +pub use crate::v1_compiler_infer_access::{check_index_access_node, check_slice_access_node}; +pub use crate::v1_compiler_infer_cycle::detect_type_cycles_kahn; +use crate::v1_compiler_infer_emit_info::TypeRepr::{EnumRepr, StructRepr}; +pub use crate::v1_compiler_infer_emit_info::{ + add_emit_item_summary, build_enum_field_summaries, build_struct_field_summaries, + close_fn_fields, derive_variant_to_enum, empty_emit_graph_info, empty_type_env, + lookup_emit_type_summary, +}; +pub use crate::v1_compiler_infer_emit_info::{ + EmitGraphInfo, EmitInfoBuildState, TypeRepr, TypeSummary, +}; +use crate::v1_compiler_infer_env::GlobalBareLookupState::{ + GlobalBareAmbiguousBinding, GlobalBareUniqueBinding, +}; +pub use crate::v1_compiler_infer_env::{ + bare_name_miss_diagnostic, binding_declares_name, empty_symbol_index, empty_type_env_cache, + env_with_type_variable_bindings, global_bare_is_ambiguous, + global_bare_strict_ambiguity_candidates, inductive_fields_for, inductive_fields_list_to_map, + is_recursive_type, is_recursive_type_by_name, listed_import_required_bare_call_blocked, + lookup_binding_by_name, lookup_type, lookup_type_by_name, lookup_type_for, + merge_inductive_fields, merge_type_env_cache, merge_type_env_cache_guarded, node_with_children, + node_with_inferred, put_inductive_field, put_inductive_field_cross, qualified_all_but_last, + qualify_borrowed_inferred, qualify_borrowed_type_names, qualify_decl_reference_positions, + str_bindings_from_bindings, symbol_index_insert, symbol_index_insert_decl, + symbol_index_insert_service, symbol_index_lookup, +}; +pub use crate::v1_compiler_infer_env::{ + GlobalBareCandidate, GlobalBareLookupState, GuardedTypeEnvCacheMerge, ServiceCensusEntry, + SymbolIndex, TypeBinding, TypeEnv, TypeEnvCache, TypeEnvCacheMergeConflict, +}; +use crate::v1_compiler_infer_items::ItemKind::{ + DataItem, FnItem, FuncItem, OtherItem, ServiceItem, TypeItem, +}; +pub use crate::v1_compiler_infer_items::{inferred_to_outputs, item_kind}; +pub use crate::v1_compiler_infer_items::{ + ItemInfo, ItemKind, ModuleInterface, ResolvedGraph, TypedGraph, TypedModule, +}; +use crate::v1_compiler_infer_lookup::ConstructorDeclarationLookup::{ + AdmissionBearingDeclarationUnavailable, ExactConstructorDeclaration, + NotAdmissionBearingReference, +}; +use crate::v1_compiler_infer_lookup::DeclarationLookupFailure::DeclarationNotIndexedAtQualifiedName; +use crate::v1_compiler_infer_lookup::DeclaredArgContract::{ + ContractKnown, ContractUnavailable, MethodUnresolved, +}; +pub use crate::v1_compiler_infer_lookup::{ + declared_arg_types_for_method, field_summary_for_type, func_decl_binding_for_call, + func_sig_if_resolved, global_bare_callable_node, lookup_coproduct_common_field_node, + lookup_field_type_node, lookup_func_sig, lookup_in_scope, lookup_structural_method, + map_key_type_in_env, map_value_type_in_env, product_field_result_type, + resolve_known_method_node, resolve_method_receiver_type, resolve_scrutinee_type_node, + set_element_type_in_env, +}; +pub use crate::v1_compiler_infer_lookup::{ + ConstructorDeclarationLookup, DeclarationLookupFailure, DeclaredArgContract, + ExactDeclarationIdentity, KnownMethodResolution, +}; +pub use crate::v1_compiler_infer_method::{ + builtin_kernel_seed_diagnostics, infer_builtin_call_type, resolve_builtin_call_type, +}; +use crate::v1_compiler_infer_patterns::PatternSubject::*; +pub use crate::v1_compiler_infer_patterns::{ + check_match_exhaustiveness, expand_scrut_type_for_variant_lookup, lookup_field_in_variant, + lookup_result_subject, lookup_variant_in_type, pattern_binding_type, + pattern_subject_from_inferred, pattern_subject_from_node, +}; +pub use crate::v1_compiler_infer_patterns::{NodeLookupResult, PatternSubject}; +pub use crate::v1_compiler_infer_resolve::{ + fn_type_param_names, is_user_generic_use_site, peel_nominal_alias_identity, + preserve_nominal_brand_on_resolve, resolve_generic_use_decl, resolve_item_types, resolve_node, +}; +pub use crate::v1_compiler_infer_resolve::{ItemResolveResult, NodeResolveResult}; +pub use crate::v1_compiler_infer_service::{ + check_service_field_access_node, check_service_method_call_node, collect_called_func_names, + collect_typed_service_calls, expand_transitive_services, extract_typed_service_name, + is_typed_service_call_receiver, service_op_entry, +}; +pub use crate::v1_compiler_infer_service::{OpEntry, ServiceMethodResult, UniqueAccum}; +use crate::v1_compiler_infer_sigs::FuncSigLookup::{ + FuncSigAmbiguous, FuncSigResolved, FuncSigUnresolved, +}; +pub use crate::v1_compiler_infer_sigs::{flatten_parent_envs, resolve_func_sigs}; +pub use crate::v1_compiler_infer_sigs::{ + FuncSigLookup, ResolveFuncSigsResult, ResolvedFuncEnv, ResolvedFuncSig, +}; +pub use crate::v1_compiler_infer_types::KernelTypeBuild; +pub use crate::v1_compiler_infer_types::{ + bare_map_node, bare_set_node, callable_inferred, callable_return_type, child_type_node, + emit_map_has, extract_optional_inner_node, for_each_element_type_node, infer_binop_type_node, + infer_literal_node, is_declared_container_alias_spelling, is_fully_resolved, + is_type_expr_annotation, kernel_profile_lookup, make_callable_type, make_container_type, + method_receiver_element_node, node_is_collection, node_is_element_collection, + node_is_keyed_collection, node_is_set_collection, node_type_compatible, node_type_deps, + node_type_equals, node_type_shape, nominal_type_ref, normalize_access_type_node, + prefer_specific_type, resolve_type_variables_from_template, resolved_type, + structural_carrier_template_name, template_return_has_variables, + template_return_is_receiver_self, +}; +pub use crate::v1_compiler_resolve::{ModuleGraph, ResolvedImport, ResolvedModule}; +use crate::v1_rt; +use crate::v1_rt::{VecCompat, VecJoin}; +use crate::v1_std_core::CallSemantics::{ + FunctionValueCallSemantics, LookupCallSemantics, PlainCallSemantics, +}; +use crate::v1_std_core::Cardinality::{CardOptional, Required}; +use crate::v1_std_core::CompilerDiagnostic::{ + AmbiguousReference, BareNoneNotAdmittedByFieldType, CallArgumentDuplicate, + CallArgumentNameUnknown, CallNamedArgOnFunctionValue, CallPositionalDeficit, + CallPositionalSurplus, ConstructorCallAdmissionRefused, FieldNotFound, + FrontierOccurrenceBudgetExceeded, InternalError, MethodExistenceFrontierAdmitted, + MethodExistenceUndecided, MethodNotFound, MissingField, OptionalCastNotEliminated, + ReceiverTypeUnestablished, SoleConstructorViolation, TypeMismatch, UnresolvedType, + VariantCollision, +}; +use crate::v1_std_core::Connective::{Arrow, Conj, Disj, NoConnective}; +use crate::v1_std_core::ExprData::{ + ExprBinOp, ExprBlock, ExprCall, ExprCast, ExprError, ExprFieldAccess, ExprForEach, ExprIf, + ExprIndex, ExprLambda, ExprLet, ExprListLit, ExprLiteral, ExprMatch, ExprMethodCall, + ExprRecordLit, ExprReturn, ExprSlice, ExprStringInterp, ExprUnaryOp, ExprVar, NoExprData, +}; +use crate::v1_std_core::ExprErrorKind::{ + CensusHeadsBodyStripped, InternalExprError, ParseRecoveryError, SemanticExprError, +}; +use crate::v1_std_core::FieldAccessStyle::{ + EnumAccessor, OptionalUnwrap, StoredField, TupleFirst, TupleSecond, +}; +use crate::v1_std_core::FieldValueShape::{OptionalValue, PlainValue}; +use crate::v1_std_core::InferredNode::{CompilerError, Resolved, TypeVariable}; +use crate::v1_std_core::MatchPattern::{Bind, VariantPattern, Wildcard}; +use crate::v1_std_core::MethodSemantics::{ + AlgebraMethodSemantics, PlainMethodSemantics, ServiceMethodSemantics, +}; +use crate::v1_std_core::StringPart::{Interpolation, Text}; +use crate::v1_std_core::UnaryOpKind::{Neg, Not}; +use crate::v1_std_core::VarBindingKind::{ + FunctionValueBinding, LocalValueBinding, MatchBoundBinding, VariantValueBinding, +}; +pub use crate::v1_std_core::{ + arg_name_at, arg_value, arm_body, arm_guard, arm_pattern, authored_name_at, binop_left, + binop_right, bool_type, build_newline_index, cast_expr, cast_target, container_expected_arity, + decl_ref_coords_label, default_ident_span, diagnostic_frontier_occurrence_key, + diagnostic_to_span, empty_intern_table, error_type, expr_call_func_at, + expr_has_non_tail_self_call, expr_has_self_call, expr_literal_int_optional, + expr_literal_string_optional, expr_method_name_at, expr_var_name_at, field_access_base, + field_access_field_at, field_access_spine, field_binding_name_at, field_binding_pattern, + field_init_node_name_at, field_init_node_value, field_node_name_at, field_node_type_expr, + find_child_named, find_property_string, float_type, fn_admit_callers, foreach_body, + foreach_collection, foreach_variable_at, generic_param_name_at, has_child_named, has_inferred, + if_condition, if_else_branch, if_then_branch, import_is_all, import_specific_names_at, + index_base, index_expr, int_type, intern, intern_str, is_child_accessor_in_model, + is_compiler_error, is_container_type, is_error_diagnostic, is_property_contraction, + is_tree_size_reducing, lambda_body, lambda_param_names_at, let_binding_name_at, let_body, + let_value, local_transport_node, make_arg_node, make_arm_node, make_error_node, + make_expr_error_node, make_expr_node, make_field_binding_node, make_field_init_node, + make_interp_part_node, make_named_expr_node, make_param_node, make_text_part_node, + make_transport_node, map_children, match_arm_nodes, match_scrutinee, method_arg_nodes, + method_receiver, module_imports, module_items, module_node, no_span, node_name_span, none_type, + param_node_default_value, param_node_name_at, param_node_type_expr, + preserve_outer_optional_cardinality, qualified_last_segment, record_lit_expr_optional, + record_lit_named_field_value_optional, record_lit_type_name_at, resource_use_name_at, + resource_use_resource, return_value, slice_base, slice_end, slice_start, string_type, + type_name_compatible, unaryop_operand, unit_type, with_optional_cardinality, + with_required_cardinality, +}; +pub use crate::v1_std_core::{expr_is_any_literal, expr_literal_symbol_optional}; +pub use crate::v1_std_core::{ + CallSemantics, Cardinality, CompilerDiagnostic, Connective, DeclRefCoords, DeclaredFuncEnv, + DeclaredFuncSig, ErrorNode, ExprData, ExprErrorKind, FieldAccessSpine, FieldAccessStyle, + FieldSummary, FieldValueShape, FrontierOccurrenceKey, InferredNode, InternTable, MatchPattern, + MethodSemantics, NewlineIndex, Node, StringPart, UnaryOpKind, VarBindingKind, +}; +use crate::NonEmptyBTreeSet; +use crate::NonEmptyVec; +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::rc::Rc; + +pub fn is_witness_type_name(name: String) -> bool { + ((name.clone() == "Witness".to_string()) || (name.clone() == "witness".to_string())) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ItemContribution { + pub resolved_item: Rc, + pub resolve_diagnostics: Rc>>, + pub func_sig: Option>, + pub svc_entries: Rc>>, + pub svc_local: Option>, + pub item_info: Rc, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ModuleContext { + pub resolved_items: Rc>>, + pub func_env: Rc, + pub svc_registry: Rc>>>>, + pub locals: Rc>>, + pub variant_locals: Rc>>, + pub item_registry: Rc>>, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct VariantFoldState { + pub locals: Rc>>, + pub collision_errors: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct VariantExportSurface { + pub arm_owners: Rc>>, + pub enum_items: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TypeNameExportFacts { + pub exporter_count: i64, + pub canonical_binding: Option>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct InferScope { + pub type_env: Rc, + pub func_env: Rc, + pub locals: Rc>>, + pub body_locals: Rc>, + pub match_bound_names: Rc>, + pub module_name: String, + pub service_registry: Rc>>>>, + pub item_registry: Rc>>, + pub lambda_param_provenance: Rc>>, + pub caller_decl_name: String, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct InferResult { + pub typed: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BlockInferState { + pub scope: Rc, + pub diag_chunks: Rc>>>>, + pub last_type: Rc, + pub typed_stmts: Rc>>, +} + +pub fn infer_block_stmts( + mut remaining: Rc>>, + mut remaining_count: i64, + mut scope: Rc, + mut typed_stmts: Rc>>, + mut diag_chunks: Rc>>>>, + mut last_type: Rc, + mut expected: Option>, +) -> Rc { + loop { + match remaining.clone().first().cloned() { + None => { + break Rc::new(BlockInferState { + scope: scope.clone(), + diag_chunks: diag_chunks.clone(), + last_type: last_type.clone(), + typed_stmts: typed_stmts.clone(), + }); + } + Some(stmt) => { + let is_last = (remaining_count.clone() == 1); + let stmt_expected = if is_last.clone() { + expected.clone() + } else { + None + }; + let stmt_result = infer_expr(stmt.clone(), scope.clone(), stmt_expected.clone()); + let stmt_typed = stmt_result.typed.clone(); + let stmt_diags = stmt_result.diagnostics.clone(); + let stmt_rt = resolved_type(stmt_typed.clone()); + let next_scope = + scope_after_stmt_node(stmt.clone(), stmt_rt.clone(), scope.clone()); + { + let __tco_0 = Rc::new( + remaining + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + let __tco_1 = (remaining_count - 1); + let __tco_2 = next_scope.clone(); + let __tco_3 = v1_rt::rc_list_push(typed_stmts, stmt_typed.clone()); + let __tco_4 = v1_rt::rc_list_push(diag_chunks, stmt_diags.clone()); + let __tco_5 = stmt_rt.clone(); + remaining = __tco_0; + remaining_count = __tco_1; + scope = __tco_2; + typed_stmts = __tco_3; + diag_chunks = __tco_4; + last_type = __tco_5; + continue; + } + } + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TypedItemResult { + pub item: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ArmInferResult { + pub typed_arm: Rc, + pub diagnostics: Rc>>, + pub body_type: Rc, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PatternScopeResult { + pub scope: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct StringPartInferResult { + pub typed_part: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ArgInferResult { + pub typed_arg: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FieldInferResult { + pub typed_field: Rc, + pub infer_result: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BuildTypeEnvResult { + pub env: Rc, + pub cache: Rc, + pub diagnostics: Rc>>, + pub binding_forks: Rc>>, +} + +pub fn binding_forks_channel_note() -> String { + thread_local! { + static CACHED: String = { + "Out-of-band binding-fork ledger channel (S2a move 2 increment B; lane ruling REVISED 2026-07-11: NOVELTY, not TREE, is the refusal axis). A binding fork is one name reaching a module from two peer imports with DIFFERENT bindings. A PRE-EXISTING fork (present on main) is already resolved there by import-order overlay-wins and every real consumer gets that winner, so refusing it retroactively is a REGRESSION (breaks working resolution, makes this PR pay pre-existing corpus debt), NOT a fail-open being closed. So ALL pre-existing forks - same-tree AND cross-tree - are LEDGERED here, keeping the pre-cut overlay-wins winner (behavior-preserving); NONE ride the diagnostics channel (consumers read diagnostics as compile cleanliness). This is the SANCTIONED declared-interim: loud + typed + counted (the floor prints a partitioned count line per run, cli_run reconcile_with_typed_cache) + dissolution-named (std consolidation / namespace Rule-1 terminal) = the std-consolidation worklist, strictly better than main's SILENT overlay-wins. TREE only labels the dissolution partition (same-tree = homonym/fork within one tree; cross-tree = v1-seed-vs-v2 migration debt). The actual WALL is novelty-refusal - hard-refuse a fork a PR NEWLY introduces - implemented as a separate per-PR gate comparing this ledger against a drift-gated baseline receipt (follow-up work item), NOT an in-run refusal (that would double floor cost by re-resolving main's ledger).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ParentModulesResult { + pub modules: Rc>>, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CycleDetectState { + pub recursive_names: Rc>, + pub global_visited: Rc>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct InferScopeComponents { + pub svc_registry: Rc>>>>, + pub svc_locals: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct LocalContributionState { + pub resolved_items: Rc>>, + pub func_sigs: Rc>>, + pub svc_registry: Rc>>>>, + pub svc_locals: Rc>>, + pub item_registry: Rc>>, + pub diag_chunks: Rc>>>>, +} + +pub fn merge_scope_from_imports( + mut remaining: Rc>>, + mut parent_index: Rc>>, + mut env: Rc, + mut svc_registry: Rc>>>>, + mut svc_locals: Rc>>, +) -> Rc { + loop { + match remaining.clone().first().cloned() { + None => { + break Rc::new(InferScopeComponents { + svc_registry: svc_registry.clone(), + svc_locals: svc_locals.clone(), + }); + } + Some(imp) => match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(typed_parent) => { + let parent_result = typed_parent.items.clone().iter().cloned().fold( + Rc::new(InferScopeComponents { + svc_registry: svc_registry.clone(), + svc_locals: svc_locals.clone(), + }), + |acc: Rc, titem: Rc| { + if ((titem.transport.clone() != None) + && ((titem.children.clone().len() as i64) > 0)) + { + { + let entries = Rc::new({ + let mut __result = Vec::new(); + for c in titem.children.clone().iter().cloned() { + __result.push(Rc::new(OpEntry { + name: authored_name_at( + env.source_indices.clone(), + c.clone(), + ), + outputs: inferred_to_outputs( + c.inferred.clone(), + c.span.clone(), + env.source_indices.clone(), + ), + params: c.params.clone(), + })); + } + __result + }); + let root = namespace_root_from_properties( + titem.properties.clone(), + authored_name_at(env.source_indices.clone(), titem.clone()), + env.source_indices.clone(), + ); + Rc::new(InferScopeComponents { + svc_registry: v1_rt::rc_map_insert( + acc.svc_registry.clone(), + authored_name_at( + env.source_indices.clone(), + titem.clone(), + ), + entries.clone(), + ), + svc_locals: v1_rt::rc_map_insert( + acc.svc_locals.clone(), + root.clone(), + nominal_type_binding(root.clone()), + ), + }) + } + } else { + if (((((titem.body.clone() != None) + && ((titem.params.clone().len() as i64) == 0)) + && (titem.transport.clone() == None)) + && (titem.connective.clone() == Connective::NoConnective)) + && (titem.inferred.clone() != None)) + { + Rc::new(InferScopeComponents { + svc_registry: acc.svc_registry.clone(), + svc_locals: v1_rt::rc_map_insert( + acc.svc_locals.clone(), + authored_name_at( + env.source_indices.clone(), + titem.clone(), + ), + Rc::new(TypeBinding { + name: authored_name_at( + env.source_indices.clone(), + titem.clone(), + ), + resolved: resolved_type(titem.clone()), + provenance: Rc::new( + SubValueRelation::SubValueUnknown, + ), + }), + ), + }) + } else { + acc.clone() + } + } + }, + ); + { + let __tco_0 = Rc::new( + remaining + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + let __tco_1 = parent_result.svc_registry.clone(); + let __tco_2 = parent_result.svc_locals.clone(); + remaining = __tco_0; + svc_registry = __tco_1; + svc_locals = __tco_2; + continue; + } + } + None => { + let __tco_0 = Rc::new( + remaining + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + remaining = __tco_0; + continue; + } + }, + } + } +} + +pub fn nominal_leaf_type(name: String) -> Rc { + nominal_type_ref(name.clone()) +} + +pub fn nominal_type_binding(name: String) -> Rc { + Rc::new(TypeBinding { + name: name.clone(), + resolved: nominal_leaf_type(name.clone()), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FieldRecursionResult { + pub shape: RecursionShape, + pub element_type: String, +} + +pub fn classify_field_recursion( + field_node: Rc, + parent_name: String, + recursive_type_set: Rc>, + source_indices: Rc>>, +) -> Option> { + { + let type_expr = match field_node.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), + _ => field_node_type_expr(field_node.clone()), + }; + let field_type_name = authored_name_at(source_indices.clone(), type_expr.clone()); + if (field_type_name.clone() == parent_name.clone()) { + match field_node.return_cardinality.clone() { + Cardinality::CardOptional => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::OptionalRecursion, + element_type: parent_name.clone(), + })), + _ => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::DirectRecursion, + element_type: parent_name.clone(), + })), + } + } else { + if is_container_type(field_type_name.clone()) { + { + let arity = match container_expected_arity(field_type_name.clone()) { + Some(a) => a.clone(), + None => 0, + }; + let value_index = if (arity.clone() == 2) { 1 } else { 0 }; + let value_type = match type_expr + .children + .clone() + .iter() + .cloned() + .skip(value_index.clone() as usize) + .next() + { + Some(t) => authored_name_at(source_indices.clone(), t.clone()), + None => "".to_string(), + }; + let is_recursive_element = ((value_type.clone() == parent_name.clone()) + || v1_rt::set_contains(&recursive_type_set, value_type.clone())); + if is_recursive_element.clone() { + { + let elem = if (value_type.clone() == parent_name.clone()) { + parent_name.clone() + } else { + value_type.clone() + }; + match field_type_name.clone().as_str() { + "List" => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::ListRecursion, + element_type: elem.clone(), + })), + "Set" => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::SetRecursion, + element_type: elem.clone(), + })), + "Map" => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::MapValueRecursion, + element_type: elem.clone(), + })), + _ => None, + } + } + } else { + None + } + } + } else { + if v1_rt::set_contains(&recursive_type_set, field_type_name.clone()) { + match field_node.return_cardinality.clone() { + Cardinality::CardOptional => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::OptionalRecursion, + element_type: field_type_name.clone(), + })), + _ => Some(Rc::new(FieldRecursionResult { + shape: RecursionShape::DirectRecursion, + element_type: field_type_name.clone(), + })), + } + } else { + None + } + } + } + } +} + +pub fn collect_fields_inductive( + fields: Rc>>, + parent_name: String, + variant_name: String, + recursive_type_set: Rc>, + acc: Rc>>>>, + source_indices: Rc>>, +) -> Rc>>>> { + fields.clone().iter().cloned().fold( + acc.clone(), + |field_acc: Rc>>>>, field_node: Rc| { + match classify_field_recursion( + field_node.clone(), + parent_name.clone(), + recursive_type_set.clone(), + source_indices.clone(), + ) { + Some(result) => put_inductive_field_cross( + field_acc.clone(), + parent_name.clone(), + variant_name.clone(), + authored_name_at(source_indices.clone(), field_node.clone()), + result.shape.clone(), + result.element_type.clone(), + ), + None => field_acc.clone(), + } + }, + ) +} + +pub fn collect_item_inductive_fields( + item: Rc, + recursive_type_set: Rc>, + source_indices: Rc>>, +) -> Rc>>>> { + { + let item_name = authored_name_at(source_indices.clone(), item.clone()); + match item.connective.clone() { + Connective::Disj => item.children.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>>>(), + |variant_acc: Rc>>>>, + variant_node: Rc| { + collect_fields_inductive( + variant_node.children.clone(), + item_name.clone(), + authored_name_at(source_indices.clone(), variant_node.clone()), + recursive_type_set.clone(), + variant_acc, + source_indices.clone(), + ) + }, + ), + Connective::Conj => collect_fields_inductive( + item.children.clone(), + item_name.clone(), + "".to_string(), + recursive_type_set.clone(), + v1_rt::rc_empty_map::>>>(), + source_indices.clone(), + ), + _ => v1_rt::rc_empty_map::>>>(), + } + } +} + +pub fn build_item_inductive_fields( + items: Rc>>, + recursive_type_set: Rc>, + source_indices: Rc>>, +) -> Rc>>>> { + items.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>>>(), + |acc: Rc>>>>, item: Rc| { + merge_inductive_fields( + acc, + collect_item_inductive_fields( + item.clone(), + recursive_type_set.clone(), + source_indices.clone(), + ), + ) + }, + ) +} + +pub fn nominal_ref_node( + name: String, + span: Rc, + ident_span: Option>, +) -> Rc { + Rc::new(Node { + name: name.clone(), + span: span.clone(), + ident_span: ident_span.clone(), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: Some(Rc::new(InferredNode::Resolved { + node: nominal_leaf_type(name.clone()), + })), + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }) +} + +pub fn resolved_callable_type(func_params: Rc>>, ret: Rc) -> Rc { + make_callable_type(func_params.clone(), ret.clone()) +} + +pub fn namespace_root_from_properties( + properties: Rc>>, + name: String, + source_indices: Rc>>, +) -> String { + match Rc::new({ + let mut __result = Vec::new(); + for p in properties.clone().iter().cloned() { + if (field_init_node_name_at(p.clone(), source_indices.clone()) + == "namespace_root".to_string()) + { + __result.push(p); + } + } + __result + }) + .first() + .cloned() + { + Some(ns_prop) => match expr_literal_string_optional(field_init_node_value(ns_prop.clone())) + { + Some(root) => root.clone(), + None => name, + }, + None => name, + } +} + +pub fn namespace_alias_target_path( + item: Rc, + source_indices: Rc>>, +) -> Option { + find_property_string( + item.properties.clone(), + "namespace_alias_target".to_string(), + source_indices.clone(), + ) +} + +pub fn is_namespace_alias_item( + item: Rc, + source_indices: Rc>>, +) -> bool { + match namespace_alias_target_path(item.clone(), source_indices.clone()) { + Some(_) => true, + None => false, + } +} + +pub fn namespace_alias_binding_for_target( + item: Rc, + target_node: Rc, + source_indices: Rc>>, +) -> Rc { + Rc::new(TypeBinding { + name: authored_name_at(source_indices.clone(), item.clone()), + resolved: target_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }) +} + +pub fn expr_span(texpr: Rc) -> Rc { + texpr.span.clone() +} + +pub fn ok_infer(texpr: Rc) -> Rc { + Rc::new(InferResult { + typed: texpr.clone(), + diagnostics: Rc::new(vec![]), + }) +} + +pub fn semantic_expr_error_node(message: String, span: Rc) -> Rc { + make_expr_error_node( + ExprErrorKind::SemanticExprError, + message.clone(), + span.clone(), + ) +} + +pub fn internal_expr_error_node(message: String, span: Rc) -> Rc { + make_expr_error_node( + ExprErrorKind::InternalExprError, + message.clone(), + span.clone(), + ) +} + +pub fn lookup_variant_parent_enum(scope: Rc, name: String) -> Option { + match v1_rt::map_get(&scope.locals.clone(), name.clone()) { + Some(binding) => match lookup_type_for(scope.type_env.clone(), binding.resolved.clone()) { + Some(parent) => { + let is_coproduct = (parent.connective.clone() == Connective::Disj); + if is_coproduct.clone() { + if has_child_named( + parent.clone(), + name.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(authored_name_at( + scope.type_env.clone().source_indices.clone(), + binding.resolved.clone(), + )) + } else { + None + } + } else { + None + } + } + None => None, + }, + None => None, + } +} + +pub fn expected_variant_owner_instantiation( + expected: Option>, + name: String, + scope: Rc, +) -> Option> { + match expected.clone() { + Some(exp) => { + let exp_enum = + expand_scrut_type_for_variant_lookup(exp.clone(), scope.type_env.clone()); + match find_child_named( + exp_enum.clone(), + name.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(_) => Some(exp_enum.clone()), + None => None, + } + } + None => None, + } +} + +pub fn variant_reference_inferred_node( + expected: Option>, + name: String, + owner_name: String, + scope: Rc, + fallback: Rc, +) -> Rc { + match expected.clone() { + Some(exp) => { + if ((exp.return_cardinality.clone() == Cardinality::Required) + && (authored_name_at(scope.type_env.clone().source_indices.clone(), exp.clone()) + == owner_name.clone())) + { + match expected_variant_owner_instantiation( + expected.clone(), + name.clone(), + scope.clone(), + ) { + Some(_) => exp.clone(), + None => fallback, + } + } else { + fallback + } + } + None => fallback, + } +} + +pub fn variant_owner_node(scope: Rc, name: String) -> Option> { + if v1_rt::contains(name.clone(), ".".to_string()) { + match symbol_index_lookup(scope.type_env.clone().symbol_index.clone(), name.clone()) { + Some(resolved) => { + if ((resolved.connective.clone() == Connective::Disj) + && has_child_named( + resolved.clone(), + qualified_last_segment(name.clone()), + scope.type_env.clone().source_indices.clone(), + )) + { + Some(resolved.clone()) + } else { + None + } + } + None => None, + } + } else { + match v1_rt::map_get(&scope.locals.clone(), name.clone()) { + Some(binding) => { + match lookup_type_for(scope.type_env.clone(), binding.resolved.clone()) { + Some(owner) => { + let owner_is_coproduct = (owner.connective.clone() == Connective::Disj); + if owner_is_coproduct.clone() { + if has_child_named( + owner.clone(), + name.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(owner.clone()) + } else { + None + } + } else { + None + } + } + None => None, + } + } + None => None, + } + } +} + +pub fn infer_var_binding_kind(scope: Rc, name: String) -> Rc { + match lookup_variant_parent_enum(scope.clone(), name.clone()) { + Some(parent_enum) => Rc::new(VarBindingKind::VariantValueBinding { + parent_enum: parent_enum.clone(), + }), + None => match v1_rt::map_get(&scope.locals.clone(), name.clone()) { + Some(_) => { + if v1_rt::map_has(&scope.match_bound_names.clone(), name.clone()) { + Rc::new(VarBindingKind::MatchBoundBinding) + } else { + Rc::new(VarBindingKind::LocalValueBinding) + } + } + None => Rc::new(VarBindingKind::FunctionValueBinding), + }, + } +} + +pub fn inference_error( + message: String, + span: Rc, + module_name: String, +) -> Rc { + make_error_node( + Rc::new(CompilerDiagnostic::InternalError { + message: message.clone(), + span: span.clone(), + }), + module_name.clone(), + ) +} + +pub fn ambiguous_reference_refusal( + name: String, + candidates: Rc>, + span: Rc, + scope: Rc, +) -> Rc { + Rc::new(InferResult { + typed: semantic_expr_error_node( + v1_rt::concat( + v1_rt::concat("ambiguous reference '".to_string(), name.clone()), + "'".to_string(), + ), + span.clone(), + ), + diagnostics: Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::AmbiguousReference { + name: name.clone(), + candidates: candidates.clone(), + span: span.clone(), + }), + scope.module_name.clone(), + )]), + }) +} + +pub fn constructor_reference_admission_enforced() -> bool { + true +} + +pub fn constructor_reference_admission_frontier_note() -> String { + thread_local! { + static CACHED: String = { + "Counted v1 seed realization for ConstructorReferenceAdmission (Horn 3, msg_968d6c24): unified infer construction-admission beside sole_constructor record-literal refusal. Dissolves when compiler_frontier_row_04_infer self-emits CargoGreen and v2 infer is the production typecheck path (^migrate_when_closure_self_emits_cargo_green).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn constructor_reference_admission_enforced_now() -> bool { + constructor_reference_admission_enforced() +} + +pub fn decl_ref_coords_equal(a: Rc, b: Rc) -> bool { + ((a.module_path.clone() == b.module_path.clone()) + && (a.decl_name.clone() == b.decl_name.clone())) +} + +pub fn caller_decl_coords(scope: Rc) -> Option> { + if (scope.caller_decl_name.clone() == "".to_string()) { + None + } else { + Some(Rc::new(DeclRefCoords { + module_path: scope.module_name.clone(), + decl_name: scope.caller_decl_name.clone(), + })) + } +} + +pub fn declaration_lookup_failure_label(cause: Rc) -> String { + match (*cause.clone()).clone() { + DeclarationLookupFailure::DeclarationNotIndexedAtQualifiedName { + qualified_name: qn, + .. + } => v1_rt::concat( + v1_rt::concat("no declaration is indexed at '".to_string(), qn.clone()), + "'".to_string(), + ), + } +} + +pub fn constructor_call_admission_diags( + callee_name: String, + scope: Rc, + span: Rc, +) -> Rc>> { + if !constructor_reference_admission_enforced_now() { + Rc::new(vec![]) + } else { + match (*func_decl_binding_for_call(scope.func_env.clone(), scope.type_env.clone(), callee_name.clone())).clone() { + ConstructorDeclarationLookup::ExactConstructorDeclaration { identity, declaration: declaration_node, .. } => match fn_admit_callers(declaration_node.clone(), scope.type_env.clone().source_indices.clone()) { + Some(permitted) => match caller_decl_coords(scope.clone()) { + Some(caller) => if { let mut __found = false; for p in permitted.clone().iter().cloned() { if decl_ref_coords_equal(p.clone(), caller.clone()) { __found = true; break; } } __found } { + Rc::new(vec![]) + } else { + Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::ConstructorCallAdmissionRefused { + constructor_module_path: identity.owner_module_path.clone(), + constructor_decl_name: identity.decl_name.clone(), + caller_module_path: caller.module_path.clone(), + caller_decl_name: caller.decl_name.clone(), + permitted_callers: Rc::new({ let mut __result = Vec::new(); for p in permitted.clone().iter().cloned() { __result.push(decl_ref_coords_label(p.clone())); } __result }), + span: span.clone(), +}), scope.module_name.clone())]) + }, + None => Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::ConstructorCallAdmissionRefused { + constructor_module_path: identity.owner_module_path.clone(), + constructor_decl_name: identity.decl_name.clone(), + caller_module_path: scope.module_name.clone(), + caller_decl_name: "".to_string(), + permitted_callers: Rc::new({ let mut __result = Vec::new(); for p in permitted.clone().iter().cloned() { __result.push(decl_ref_coords_label(p.clone())); } __result }), + span: span.clone(), +}), scope.module_name.clone())]), +}, + None => Rc::new(vec![]), +}, + ConstructorDeclarationLookup::NotAdmissionBearingReference => Rc::new(vec![]), + ConstructorDeclarationLookup::AdmissionBearingDeclarationUnavailable { identity, cause, .. } => Rc::new(vec![inference_error(v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat("constructor reference admission cannot establish the declaration identity of '".to_string(), identity.decl_name.clone()), "' owned by '".to_string()), identity.owner_module_path.clone()), "': ".to_string()), declaration_lookup_failure_label(cause.clone())), " -- refusing rather than reading admission facts off a resolved value node".to_string()), span.clone(), scope.module_name.clone())]), +} + } +} + +pub fn constructor_reference_admission_refusal( + callee_name: String, + span: Rc, + scope: Rc, +) -> Rc { + Rc::new(InferResult { + typed: semantic_expr_error_node( + v1_rt::concat( + v1_rt::concat( + "constructor call admission refused for '".to_string(), + callee_name.clone(), + ), + "'".to_string(), + ), + span.clone(), + ), + diagnostics: constructor_call_admission_diags( + callee_name.clone(), + scope.clone(), + span.clone(), + ), + }) +} + +pub fn constructor_reference_admission_unshadowed( + callee_name: String, + span: Rc, + scope: Rc, +) -> Option> { + if v1_rt::map_has(&scope.body_locals.clone(), callee_name.clone()) { + None + } else { + constructor_reference_admission_early_refusal( + callee_name.clone(), + span.clone(), + scope.clone(), + ) + } +} + +pub fn constructor_reference_admission_early_refusal( + callee_name: String, + span: Rc, + scope: Rc, +) -> Option> { + { + let admission_diags = + constructor_call_admission_diags(callee_name.clone(), scope.clone(), span.clone()); + match admission_diags.clone().first().cloned() { + Some(_) => Some(constructor_reference_admission_refusal( + callee_name.clone(), + span.clone(), + scope.clone(), + )), + None => None, + } + } +} + +pub fn type_mismatch_error( + expected: String, + got: String, + span: Rc, + module_name: String, +) -> Rc { + make_error_node( + Rc::new(CompilerDiagnostic::TypeMismatch { + expected: expected.clone(), + got: got.clone(), + span: span.clone(), + }), + module_name.clone(), + ) +} + +pub fn seed_node_traversal_frontier() -> String { + thread_local! { + static CACHED: String = { + "🟡 dissolve-on: v1_seed_deleted_at_v2_self_host (opened 2026-07-31) — the v1 seed reads and recurses substrate Node storage directly instead of consuming a canonical traversal surface. Recorded as ONE frontier row for the CLASS, because that is the honest grain: the idiom is 16 self-recursive `children |> flat_map` sites on origin/main across 04_emit_info, 04_sigs, 04_infer, 05_emit, 05_emit_rust, compile and complexity (collect_type_names_from_node, named_type_vars_in_node, collect_value_ref_names and siblings), plus 579 direct Node-storage field reads in 04_infer alone. collect_explicit_return_values is the 17th instance and v1.compiler.trait_derive_emit.v1_type_expr_contains_param_name the 18th (codex review 47248), not new classes, and a per-function row would assert separable work that does not exist while 16 identical siblings carried none (codex reviews 45570, 45580, 45666). SIBLING COUNT IS NOT THE JUSTIFICATION and the reviewer is right to reject that reading — precedent is debt, not permission. The justification is that no canonical surface is REACHABLE here: fold_node and node_query are v2 substrate, no v1 seed module imports v2, and v1 COMPILES v2, so routing seed inference through v2's fold inverts the bootstrap; and no shared v1 walker exists to route through, because every v1 collector recurses itself. DESIGN's fold_node line is scoped to the 7 v2 stages. COST OF CLOSING NOW, which is why this is retained rather than accepted: building a v1-local generic traversal for one call site adds another shape without removing any of the existing ones, and migrating all 18 is a seed-wide refactor of the stage that IS the traversal — against a seed whose declared endpoint is deletion. DISSOLVES WHEN the v1 seed is deleted at v2 self-host, at which point every row in this class goes with it; the same trigger compiler_diagnostic_seed_projection_note carries for the hand-Rust arms, because it is the same seed and the same endpoint.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn collect_explicit_return_values(n: Rc) -> Rc>> { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*n.expr_data.clone()).clone() { + ExprData::ExprLambda => Rc::new(vec![]), + ExprData::ExprReturn => v1_rt::concat( + Rc::new(vec![return_value(n.clone())]), + Rc::new({ + let mut __result = Vec::new(); + for c in n.children.clone().iter().cloned() { + __result + .extend((*collect_explicit_return_values(c.clone())).iter().cloned()); + } + __result + }), + ), + _ => Rc::new({ + let mut __result = Vec::new(); + for c in n.children.clone().iter().cloned() { + __result.extend((*collect_explicit_return_values(c.clone())).iter().cloned()); + } + __result + }), + } + }) +} + +pub fn explicit_return_conformance_diags( + declared: Rc, + body_typed: Rc, + scope: Rc, +) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for returned in collect_explicit_return_values(body_typed.clone()) + .iter() + .cloned() + { + __result.extend( + (*declared_type_conformance_diags( + declared.clone(), + resolved_type(returned.clone()), + returned.span.clone(), + scope.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }) +} + +pub fn explicit_return_conformance_note() -> String { + thread_local! { + static CACHED: String = { + "An EARLY return is a second exit from the same declaration and must meet the same declared type as the last expression. The conformance wall first checked only the body's final inferred type, so `fn f(cond: Bool) -> Int { if cond { return \"wrong\" } 1 }` compiled clean — the block's value is the trailing 1, which conforms, and the wrong-typed exit was never compared against anything (codex review 45472, confirmed by execution: exit 0 before, a located TypeMismatch after). The check reuses declared_type_conformance_diags rather than minting a second relation, so the early exit is judged by exactly the ground-kernel-scalar and ground-element-collection discipline the trailing expression is judged by, and it widens with that gate rather than beside it. THE WALK STOPS AT A LAMBDA BOUNDARY, and it did not at first. A `return` inside a nested lambda belongs to the LAMBDA's callable return type, not the enclosing declaration's, so recursing through ExprLambda checked it against the wrong declaration and refused correct code — a fabricated refusal, which §5 forbids exactly as it forbids a fabricated success, and the mirror image of the hole this fn was added to close (codex review 45481, confirmed by execution: a lambda returning String inside a fn declared -> Int refused with expected Primitive(Int) got Primitive(String)). Every callable boundary is a new declaration and its returns are judged against it, not against whatever encloses it. THE WALKER'S OWN DISPOSITION, distinct from the lambda-coverage trigger below and asked for separately (codex review 45580): it is the seed's, not this function's. Self-recursive `children |> flat_map` collection is the v1 seed's only traversal idiom — 16 such sites on origin/main across 04_emit_info, 04_sigs, 04_infer, 05_emit, 05_emit_rust, compile and complexity (collect_type_names_from_node, named_type_vars_in_node, collect_value_ref_names and siblings) — and there is no shared v1 walker to route through, because each collector recurses itself. Nor is there a canonical fold to reach for: fold_node and node_query are v2 substrate, no v1 seed module imports v2, and v1 COMPILES v2, so routing seed inference through v2's fold inverts the bootstrap. DESIGN's fold_node line is scoped to the 7 v2 stages. So this is the 17th instance of a 16-instance idiom, and its trigger is the one every sibling carries: the v1 seed shrinks to zero at v2 self-host and they dissolve together. Generalizing a shared collector for this one call site alone would ADD a 17th shape rather than remove one; the dissolution that is real is the seed's. That reasoning was recorded on where_refinement_receiver_peel_note for the same class and NOT here, which is why it had to be found twice — a disposition stated on one carrier and omitted from its sibling is not stated. Lambda returns are consequently NOT yet judged here — the lambda's own declared return is not threaded to this post-pass — which is a narrowing, stated rather than implied, and it dissolves when the walk carries each callable's declared return rather than only infer_item's.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn declared_return_type_node(item: Rc) -> Rc { + preserve_outer_optional_cardinality(item.clone(), resolved_type(item.clone())) +} + +pub fn conformance_ground_kernel_scalar( + n: Rc, + source_indices: Rc>>, +) -> bool { + { + let plain_shape = ((n.connective.clone() == Connective::NoConnective) + && ((n.children.clone().len() as i64) == 0)); + let required = (n.return_cardinality.clone() == Cardinality::Required); + let kernel_named = is_kernel_type(authored_name_at(source_indices.clone(), n.clone())); + ((plain_shape.clone() && required.clone()) && kernel_named.clone()) + } +} + +pub fn conformance_ground_element_collection( + n: Rc, + source_indices: Rc>>, +) -> bool { + { + let shaped_container = (((n.connective.clone() == Connective::NoConnective) + && node_is_element_collection(n.clone(), source_indices.clone())) + && (node_is_keyed_collection(n.clone(), source_indices.clone()) == false)); + let required = (n.return_cardinality.clone() == Cardinality::Required); + let element_ground = match n.children.clone().first().cloned() { + Some(el) => conformance_ground_kernel_scalar( + child_type_node(el.clone()), + source_indices.clone(), + ), + None => false, + }; + ((shaped_container.clone() && required.clone()) && element_ground.clone()) + } +} + +pub fn conformance_ground_type( + n: Rc, + source_indices: Rc>>, +) -> bool { + (conformance_ground_kernel_scalar(n.clone(), source_indices.clone()) + || conformance_ground_element_collection(n.clone(), source_indices.clone())) +} + +pub fn conformance_unjudged_live_hole_note() -> String { + thread_local! { + static CACHED: String = { + "PROVEN LIVE HOLE, AND THE REASON THE UNJUDGED ADVISORY IS EXCLUDED FROM THIS PR (codex reviews 45647, 45767). The branch now returns [] for the unjudged case, matching origin/main exactly, so this PR neither closes nor worsens the class; it lands with the identity capability instead. The record below is kept because the witness and the five measured attempts are what that lane starts from. The unjudged branch is not merely unmeasured — a program that is simply WRONG reaches emission through it. Executed witness: `type R { x: Int }` `type S { y: String }` `fn wrong_record() -> R { S { y: \"a\" } }` compiles EXIT 0 and EMITS TWO FILES, on this branch and on origin/main alike. Two structurally unrelated named records is not a representation gap; it is the conformance half of #7479. It was briefly reported as a counted advisory here, and that is precisely what was removed: counting it protects nothing, and a number beside a wrong program is the fabricated success DESIGN 5 forbids, one level up. THE FIX WAS ATTEMPTED AND IS NOT LANDED, and the measurements are recorded because they are the real cost of the next attempt rather than a reason to stop looking. Three successive narrowings of a refuse-when-both-sides-are-named-structured rule were each run against the whole corpus: (1) both sides structured and named -> 90 refusals of CORRECT code, dominated by the two-representation optionality class (24 Node(Optional) vs Primitive(Node), plus Coproduct(X) vs Coproduct(Optional)); (2) narrowed to inhabited named RECORDS with kernel scope names excluded -> 15; (3) additionally guarding the raw nodes -> 27, and the population had by then shifted to a NEW class, produced sides that are let-BINDING names (module_emit_scope, scope_after_expr, lookup_item) rather than types. The count moving 90 -> 15 -> 27 rather than monotonically down is the finding: each guard displaces the false-positive population instead of shrinking it, which is the exemption-accumulation this wall refuses elsewhere, and shipping any of the three would red correct code. So the arm is NOT landed, and with no arm to land the residue is left exactly where main leaves it rather than dressed up as partial coverage. The blocking obstacle is named and is not vague: the produced-side node reaching this branch is not reliably a TYPE — it can be a nominal reference, a kernel encoding of cardinality or absence, an anonymous literal, or a let-binding identity — so no predicate over its shape can separate a real mismatch from a representation gap until produced-side type identity is established upstream. A FOURTH attempt isolated the obstacle exactly, and it is the reason the other three moved the population instead of shrinking it: guarding on `both sides are Conj whose authored name RESOLVES via lookup_type_by_name to a record declaration` still refused 14 seed sites, and every one had a LET-BINDING name on the produced side (module_emit_scope, scope_after_expr, lookup_item, service_fallback_transport). lookup_type_by_name resolves those because bindings and types inhabit ONE name environment, so the guard cannot tell a type identity from a binding identity — which is the stated obstacle, now demonstrated rather than inferred. A FIFTH attempt tested the one discriminator that looked left — requiring the resolved declaration to NAME ITSELF, on the theory that a type declares its own name while a binding resolves to a type named differently — and it returned the IDENTICAL 14 sites, because lookup_type_by_name on a binding returns a node carrying the BINDING's name, not its type's. The name environment does not merely conflate the two lookups; the resolved node itself carries no separable type identity. No predicate over the produced node's shape or name can close this class. Dissolve-on: feature:conformance-produced-type-identity — the produced node carries a resolved type identity rather than a shape to be guessed at, at which point the refusal arm is one predicate over two identities and this row deletes. THE PERMISSION IS NOT THIS PATH'S AND THAT WAS MEASURED, NOT ASSERTED: the identical program built against origin/main compiles EXIT 0, emits 2 files and reports ZERO diagnostics, and this branch now does the same, because the unjudged branch returns the same empty list main returns. So the conformance path neither newly permits the emission nor closes it. THE COUNTED-ADVISORY MIDDLE GROUND WAS TRIED AND REJECTED, and the rejection is the useful part of this row: an advisory made the fail-open visible without making it stop, and review held that visibility is not protection when the program is PROVABLY wrong rather than merely unproven (codex reviews 45647, 45695, 45711, 45767, 45777). Agreed on execution — the R/S witness above emitted two files under the advisory. So the class is left at main's behavior and named here with its trigger, and what ships is the method-existence wall, which does refuse and does emit nothing. That is a judgment about sequencing, not a claim that the hole is acceptable: a declared boundary with an executed witness, an owner-facing trigger and a measured cost, and deliberately NOT a success path with a number beside it.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn conformance_expansion_depth_note() -> String { + thread_local! { + static CACHED: String = { + "MEASUREMENT RECEIPT FOR THE NEXT LANE, NOT A DESCRIPTION OF LIVE CODE — the expansion-peeling comparison it records was deleted together with the unjudged advisory it fed (codex review 45767), and this row is kept because the measurement is what the next attempt starts from rather than re-derives. A declared type and a produced type routinely arrive at DIFFERENT EXPANSION DEPTHS: the declaration side is a nominal reference to T while the body side is T's already-expanded body, so comparing them as they arrive reads one type as two. Measured over the whole corpus that was the majority of the unjudged residue — 203 Node, 173 Outcome, 46 Witness, 43 Optional, 38 PipelineStep and a long tail, each a reference and its own body — which is why the frontier first read 3005 and then 1566 once each side was resolved through lookup_type_for and peeled through peel_where_refinement_base, the SAME peel the method wall uses (DESIGN section 3: one authority, two consumers, not a second one minted here). Reporting those as unjudged was not a conservative silence but a WRONG COUNT, and an inflated frontier buries the residue that genuinely cannot be decided under pairs that were never in doubt. THE COMPARISON MUST BE THE STRUCTURAL RELATION, NOT A RENDERED SHAPE STRING, and the first version of this got that wrong in a way worth keeping on the record: it compared node_type_shape output, which collapses every anonymous product to the literal text Product() and every named product to its OUTER NAME ONLY, discarding fields, variants and their types. So two structurally different records compared EQUAL and were stamped proven-conforming — the exact fail-open this wall exists to delete, reintroduced while removing a different one, and by the same mechanism as the earlier 1.0/0.0 seam: a projection that looks like evidence used where a proof was required (codex review 45600). A display projection is for MESSAGES; a judgment must consume the structural relation. That constraint outlives the deleted code and binds whoever rebuilds it: node_type_compatible recurses into container elements and compares canonical template names, so identity is established rather than rendered, but its known imprecision is only safe where a mismatch costs a count rather than a refusal — it reports MISMATCH for the four classes of correct code enumerated in declared_type_conformance_note, so wiring it to a refusal without first establishing produced-side type identity (feature:conformance-produced-type-identity) reds correct code. That is the trap the five measured attempts in conformance_unjudged_live_hole_note fell into.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn declared_type_conformance_diags( + declared: Rc, + produced: Rc, + span: Rc, + scope: Rc, +) -> Rc>> { + { + let si = scope.type_env.clone().source_indices.clone(); + let both_ground = (conformance_ground_type(declared.clone(), si.clone()) + && conformance_ground_type(produced.clone(), si.clone())); + if !both_ground.clone() { + Rc::new(vec![]) + } else { + if node_type_compatible(declared.clone(), produced.clone(), si.clone()) { + Rc::new(vec![]) + } else { + Rc::new(vec![type_mismatch_error( + node_type_shape(declared.clone(), si.clone()), + node_type_shape(produced.clone(), si.clone()), + span.clone(), + scope.module_name.clone(), + )]) + } + } + } +} + +pub fn declared_type_conformance_note() -> String { + thread_local! { + static CACHED: String = { + "WALL (DESIGN §5) — a declaration must CONSTRAIN the value it declares, not merely state an intent beside it. infer_item passed the declared return into body inference as expected but then kept the declaration own inferred return REGARDLESS of what the body produced, and the generic expected handling in infer_expr applies where-refinement checks rather than a general actual-subtype-of-declared judgment. So fn f() -> Int { \"wrong\" } typechecked with ZERO diagnostics and the lie surfaced at the first consumer, field access, or host parser. Three positions are checked against their declaration: a fn body vs its declared return (both the param-carrying and paramless arms) and a data value vs its type annotation. THE SCOPE IS DELIBERATELY NARROW AND THE NARROWING IS THE FINDING. node_type_compatible is the corpus compatibility relation and it is NOT sound as a general declared-versus-produced conformance judgment: measured over the whole tree, four independent classes of CORRECT code reported a mismatch, each a place where the relation compares names across representations it never peels. (1) OPTIONALITY LIVES IN TWO REPRESENTATIONS — a fn declared -> String? carries optionality in item.return_cardinality while its body produces the nominal Optional coproduct, so 4 correct sites in 05_emit_rust.dag read as expected Primitive(String) got Coproduct(Optional). (2) BRAND ALIASES ARE NOT PEELED — Hash is ContentHash is a branded String, so 3 correct sites in dag_collect_support.dag read as expected Primitive(String) got Primitive(Hash); the same class the method wall measured as NonEmptyStr arriving as Product(NonEmptyStr). (3) ANONYMOUS RECORD LITERALS — the corpus writes a typed list as [ { name: ..., .. }, .. ] without repeating the nominal type, so 8+ correct rows in dag/std/algebra.dag read as expected Container(List,Product(AlgebraFieldTemplate)) got Container(List,Product()). (4) CARDINALITY IS NOT ON THE RESOLVED TYPE NODE — resolved_type(n: item) drops the declaration optional marker, which is why the declared side is built through preserve_outer_optional_cardinality, the existing single authority for carrying an outer node cardinality onto an inner type node. Each class was found by RUNNING the wall over the corpus, never by reasoning about it, and the list is not known to be exhaustive — which is precisely why this wall does not chase them with exemptions. Four ad-hoc carve-outs would leave a wall that is neither principled nor trustworthy, and fabricating a refusal is the mirror image of the fabricated success the wall exists to delete. So the predicate is POSITIVE ESTABLISHMENT, the same discipline the method wall uses: judge ONLY when both sides are ground kernel scalars — plain shape, Required cardinality, and a name in std.types kernel_type_set — because then a name difference IS a real difference with no alias, brand, container, coproduct or cardinality representation in between. That admits the whole class the operator named (declaring one primitive and returning another, fn f() -> Int { \"a string\" } and data d: Int = \"a string\") and admits nothing it cannot prove. THE GATE WAS FIRST WRITTEN AS SCALAR-ONLY AND THAT WAS TOO NARROW, which review found before any consumer did: a plain shape excludes a List, so a declared List whose body produced a List was indistinguishable from a conforming declaration and compiled clean, and calling that state UNJUDGED in prose did not model it (codex review 45398). The widening is the SAME argument, not an exception to it — a container of a ground kernel scalar has no alias, brand, coproduct, anonymous-literal or cardinality representation standing between the two sides either, so a difference in the element name is a real difference exactly as a difference in a scalar name is. conformance_ground_type therefore admits a ground kernel scalar OR a Required, non-keyed element collection whose element is one, and the whole dag + src/v2 corpus stays clean under it, which is the same instrument that found the four false-positive classes above. The discriminating control was run against the PRIOR compiler rather than reasoned about: `fn f() -> List { [\"a\", \"b\"] }` with `data d: List = [1, 2]` compiles with exit 0 on the pre-widening binary and refuses with two located mismatches on this one. EVERYTHING STILL WIDER IS UNJUDGED, AND IN THIS PR UNJUDGED IS A SILENCE — a deliberate narrowing, not an oversight. It is worth stating why the opposite was tried first: an unproven declaration returning an empty diagnostic list is byte-for-byte indistinguishable in the output from a proven-conforming one, so the absence of a check reads as the presence of a proof (codex review 45500). Making it a counted DeclaredTypeConformanceUnjudged advisory answered that objection and raised a larger one — an advisory does not stop a wrong program, so a proven-wrong program still emitted with a number beside it (codex reviews 45647, 45695, 45711, 45777). That advisory measured the frontier at 1566 declarations whole-tree and is EXCLUDED here (codex review 45767), because the branch could not be made to refuse safely either — see conformance_unjudged_live_hole_note for the executed witness and the five measured attempts. So this branch returns [] for the unjudged case, which is byte-for-byte what origin/main does, and this PR's contribution to conformance is exactly the REFUSALS it can prove: ground kernel scalars and ground element collections. Nothing about the unjudged class is worse than main; it is simply not addressed here, and it lands with the identity capability rather than beside it. IT WAS FIRST MEASURED AT 3005 AND THAT NUMBER WAS WRONG, which matters because the count is the whole bound: nearly half of it was one type compared against ITSELF at two expansion depths (a declaration naming T versus a body producing T's expanded body), so the frontier was reported almost twice its true size — see conformance_expansion_depth_note. An inflated frontier is not a conservative error; it hides the residue that genuinely cannot be decided underneath pairs that were never in doubt. It fires only where the declared and produced SHAPES DIFFER, because identical shapes have nothing to prove and counting them would bury the signal under declarations nobody doubts — the residue that matters is exactly the set where a mismatch could hide. Each numbered class above is a promotion trigger, and each promotion should be visible as a drop in that count. Keyed collections are deliberately not admitted yet — the key and value axes need their own corpus measurement, and guessing that the element argument transfers is precisely the move this note refuses elsewhere. Dissolve-on: a peeling conformance relation that grounds brand aliases to their base, reconciles the two optionality representations, and grounds an anonymous literal against its expected nominal type — at which point the ground-kernel-scalar gate widens class by class and finally deletes. Not covered here and each its own lane: direct-call argument types inside compiler modules (the v2. / v1.compiler. exemption), default field values, generic record instantiation, and post-substitution generic field access.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn rejects_string_for_optional_coproduct_field( + expected: Rc, + got: Rc, + source_indices: Rc>>, + env: Rc, +) -> bool { + { + let expected_resolved = + match lookup_type_for(env.clone(), with_required_cardinality(expected.clone())) { + Some(resolved) => resolved.clone(), + None => with_required_cardinality(expected.clone()), + }; + let expected_is_optional_coproduct = ((expected.return_cardinality.clone() + == Cardinality::CardOptional) + && (expected_resolved.connective.clone() == Connective::Disj)); + let got_is_string = ((node_type_shape(got.clone(), source_indices.clone()) + == "Primitive(String)".to_string()) + || (authored_name_at(source_indices.clone(), got.clone()) == "String".to_string())); + (expected_is_optional_coproduct.clone() && got_is_string.clone()) + } +} + +pub fn bare_none_construction_wall_note() -> String { + thread_local! { + static CACHED: String = { + "CONSTRUCTION WALL (DESIGN 4b): the bare name `None` carries absence and NOTHING else, so a construction position whose declared field type cannot carry absence must refuse it rather than adopt whichever `None` variant happens to be in scope. MEASURED HOLE this closes, on the pre-wall binary: with `type Diags = None | Some { n: Int }` in scope, `Holder { n: None }` for `n: Int` and `ListHolder { xs: None }` for `xs: List` compiled with ZERO blocking diagnostics and emitted `n: Rc::new(Diags::None)` / `xs: Rc::new(Diags::None)` — a Rust program the declared types refute, produced silently. WHY THIS SLICE AND NOT THE GENERAL CONFORMANCE RULE: conformance_unjudged_live_hole_note records five successive attempts at a general named-vs-named refusal, each of which red correct code because the produced side carries no separable type identity. A bare `None` reference needs no produced-side identity — it is a SYNTACTIC form whose only meaning is absence — so admissibility is decided entirely from the DECLARED side, which is exactly why this class is decidable where the general one is not. ADMISSION is deliberately two-armed and nothing else: optional cardinality (the `T?` carrier), or a coproduct that declares a `None` variant at its own level (std.cache_interface AuthScope, v2.std.diagnostic Diagnostics — the two live carriers). A qualified `Owner.None` is not a bare reference and is not judged here. COVERAGE BOUNDARY, stated rather than left to be found: the wall fires only where the field s declared type is known at this site; a field whose declared type does not resolve is not judged, which is the check s precision frontier and not a failure arm.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn field_declared_type_is_identified(ft: Rc, scope: Rc) -> bool { + { + let required = match lookup_type_for( + scope.type_env.clone(), + with_required_cardinality(ft.clone()), + ) { + Some(resolved) => resolved.clone(), + None => with_required_cardinality(ft.clone()), + }; + (authored_name_at( + scope.type_env.clone().source_indices.clone(), + required.clone(), + ) != "".to_string()) + } +} + +pub fn field_type_admits_bare_none(ft: Rc, scope: Rc) -> bool { + { + let required = match lookup_type_for( + scope.type_env.clone(), + with_required_cardinality(ft.clone()), + ) { + Some(resolved) => resolved.clone(), + None => with_required_cardinality(ft.clone()), + }; + let expanded = + expand_scrut_type_for_variant_lookup(required.clone(), scope.type_env.clone()); + let declares_none_variant = ((expanded.connective.clone() == Connective::Disj) + && has_child_named( + expanded.clone(), + "None".to_string(), + scope.type_env.clone().source_indices.clone(), + )); + ((ft.return_cardinality.clone() == Cardinality::CardOptional) + || declares_none_variant.clone()) + } +} + +pub fn expr_is_bare_none_reference(texpr: Rc, scope: Rc) -> bool { + match (*texpr.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + (expr_var_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()) + == "None".to_string()) + } + _ => false, + } +} + +pub fn bare_none_field_construction_diags( + fi: Rc, + fi_name: String, + field_declared_type: Option>, + type_name_for_message: String, + scope: Rc, +) -> Rc>> { + match field_declared_type.clone() { + None => Rc::new(vec![]), + Some(ft) => { + let value_expr = field_init_node_value(fi.clone()); + if ((expr_is_bare_none_reference(value_expr.clone(), scope.clone()) + && field_declared_type_is_identified(ft.clone(), scope.clone())) + && (field_type_admits_bare_none(ft.clone(), scope.clone()) == false)) + { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::BareNoneNotAdmittedByFieldType { + field: fi_name.clone(), + type_name: type_name_for_message.clone(), + declared_type: node_type_shape( + ft.clone(), + scope.type_env.clone().source_indices.clone(), + ), + span: value_expr.span.clone(), + }), + scope.module_name.clone(), + )]) + } else { + Rc::new(vec![]) + } + } + } +} + +pub fn field_type_is_optional_coproduct(ft: Rc, env: Rc) -> bool { + { + let inner = match lookup_type_for(env.clone(), with_required_cardinality(ft.clone())) { + Some(resolved) => resolved.clone(), + None => with_required_cardinality(ft.clone()), + }; + ((ft.return_cardinality.clone() == Cardinality::CardOptional) + && (inner.connective.clone() == Connective::Disj)) + } +} + +pub fn record_lit_expected_fields( + type_name: Option, + scope: Rc, +) -> Rc>> { + match type_name.clone() { + Some(tn) => match lookup_type_by_name(scope.type_env.clone(), tn.clone()) { + Some(direct) => direct.children.clone(), + None => match variant_owner_node(scope.clone(), tn.clone()) { + Some(parent) => match Rc::new({ + let mut __result = Vec::new(); + for v in parent.children.clone().iter().cloned() { + if (authored_name_at( + scope.type_env.clone().source_indices.clone(), + v.clone(), + ) == tn.clone()) + { + __result.push(v); + } + } + __result + }) + .first() + .cloned() + { + Some(variant) => variant.children.clone(), + None => Rc::new(vec![]), + }, + None => Rc::new(vec![]), + }, + }, + None => Rc::new(vec![]), + } +} + +pub fn record_lit_expanded_from_expected( + type_name: Option, + expected: Option>, + scope: Rc, +) -> Option> { + match type_name.clone() { + Some(tn) => match expected.clone() { + Some(exp) => { + if (((authored_name_at( + scope.type_env.clone().source_indices.clone(), + exp.clone(), + ) == tn.clone()) + && (exp.connective.clone() == Connective::Conj)) + && ((exp.children.clone().len() as i64) > 0)) + { + Some(exp.clone()) + } else { + match exp.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: expanded, .. }) => { + if (authored_name_at( + scope.type_env.clone().source_indices.clone(), + expanded.clone(), + ) == tn.clone()) + { + Some(expanded.clone()) + } else { + None + } + } + _ => { + let rt = resolved_type(exp.clone()); + if (authored_name_at( + scope.type_env.clone().source_indices.clone(), + rt.clone(), + ) == tn.clone()) + { + Some(rt.clone()) + } else { + None + } + } + } + } + } + None => None, + }, + None => None, + } +} + +pub fn record_lit_expected_coproduct( + expected: Option>, + scope: Rc, +) -> Option> { + match expected.clone() { + Some(exp) => { + let resolved = match lookup_type_for(scope.type_env.clone(), exp.clone()) { + Some(r) => r.clone(), + None => exp.clone(), + }; + let nominal = if node_is_element_collection( + resolved.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + match resolved.children.clone().first().cloned() { + Some(elem) => { + let elem_ty = child_type_node(elem.clone()); + match lookup_type_for(scope.type_env.clone(), elem_ty.clone()) { + Some(r) => Some(r.clone()), + None => Some(elem_ty.clone()), + } + } + None => None, + } + } else { + Some(resolved.clone()) + }; + match nominal.clone() { + Some(n) => { + if (n.connective.clone() == Connective::Disj) { + Some(n.clone()) + } else { + None + } + } + None => None, + } + } + None => None, + } +} + +pub fn record_lit_parent_enum_from_expected( + type_name: String, + expected: Option>, + scope: Rc, +) -> Option { + match record_lit_variant_from_expected(Some(type_name.clone()), expected.clone(), scope.clone()) + { + Some(_) => match record_lit_expected_coproduct(expected.clone(), scope.clone()) { + Some(coproduct) => Some(authored_name_at( + scope.type_env.clone().source_indices.clone(), + coproduct.clone(), + )), + None => None, + }, + None => None, + } +} + +pub fn record_lit_variant_from_expected( + type_name: Option, + expected: Option>, + scope: Rc, +) -> Option> { + match type_name.clone() { + Some(tn) => match record_lit_expected_coproduct(expected.clone(), scope.clone()) { + Some(coproduct) => Rc::new({ + let mut __result = Vec::new(); + for v in coproduct.children.clone().iter().cloned() { + if (authored_name_at(scope.type_env.clone().source_indices.clone(), v.clone()) + == qualified_last_segment(tn.clone())) + { + __result.push(v); + } + } + __result + }) + .first() + .cloned(), + None => None, + }, + None => None, + } +} + +pub fn record_lit_fields_from_expected( + type_name: Option, + expected: Option>, + scope: Rc, +) -> Option>>> { + match record_lit_expanded_from_expected(type_name.clone(), expected.clone(), scope.clone()) { + Some(expanded) => { + if ((expanded.connective.clone() == Connective::Conj) + && ((expanded.children.clone().len() as i64) > 0)) + { + Some(expanded.children.clone()) + } else { + None + } + } + None => None, + } +} + + +pub fn field_declared_type_node(sf: Rc) -> Rc { + match sf.inferred.as_deref() { + Some(InferredNode::Resolved { node: rt }) => { + preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + } + _ => field_node_type_expr(sf.clone()), + } +} + +pub fn record_lit_instantiated_fields( + type_name: Option, + expected: Option>, + scope: Rc, +) -> Option>>> { + match type_name.clone() { + Some(tn) => match expected.clone() { + Some(exp) => { + if (type_name_compatible( + authored_name_at(scope.type_env.clone().source_indices.clone(), exp.clone()), + tn.clone(), + ) == false) + { + None + } else { + if ((exp.children.clone().len() as i64) == 0) { + None + } else { + match lookup_type_for(scope.type_env.clone(), exp.clone()) { + Some(decl) => { + if ((decl.params.clone().len() as i64) + != (exp.children.clone().len() as i64)) + { + None + } else { + { + let subst = Rc::new(decl.params.clone().iter().cloned().enumerate().map(|(i, v)| (i as i64, v)).collect::>()).iter().cloned().fold(v1_rt::rc_empty_map::>(), |acc: Rc>>, pair: (i64, Rc)| { + let slot = authored_name_at(scope.type_env.clone().source_indices.clone(), pair.1.clone()); +match exp.children.clone().iter().cloned().skip(pair.0.clone() as usize).next() { + Some(arg) => v1_rt::rc_map_insert(acc.clone(), slot.clone(), resolved_type(arg.clone())), + None => acc.clone(), +} +}); + let template_fields = decl.children.clone(); + Some(Rc::new({ + let mut __result = Vec::new(); + for sf in template_fields.clone().iter().cloned() { + __result.push(Rc::new(Node { + name: sf.name.clone(), + span: sf.span.clone(), + ident_span: sf.ident_span.clone(), + children: sf.children.clone(), + connective: sf.connective.clone(), + params: sf.params.clone(), + inferred: Some(Rc::new( + InferredNode::Resolved { + node: substitute_generics( + field_declared_type_node(sf.clone()), + subst.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + ), + }, + )), + return_cardinality: sf + .return_cardinality + .clone(), + uses: sf.uses.clone(), + body: sf.body.clone(), + transport: sf.transport.clone(), + properties: sf.properties.clone(), + type_annotation: sf.type_annotation.clone(), + is_self_recursive: sf.is_self_recursive.clone(), + has_non_tail_self_call: sf + .has_non_tail_self_call + .clone(), + match_pattern: sf.match_pattern.clone(), + expr_data: sf.expr_data.clone(), + ident: None, + })); + } + __result + })) + } + } + } + None => None, + } + } + } + } + None => None, + }, + None => None, + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct KernelListTyDiag { + pub ty: Rc, + pub miss_diags: Rc>>, +} + +pub fn list_kernel_ty_from_element(element: Rc) -> Rc { + { + let b = make_container_type("List".to_string(), element.clone()); + Rc::new(KernelListTyDiag { + ty: b.ty.clone(), + miss_diags: b.diagnostics.clone(), + }) + } +} + +pub fn set_kernel_ty_from_element(element: Rc) -> Rc { + { + let b = make_container_type("Set".to_string(), element.clone()); + Rc::new(KernelListTyDiag { + ty: b.ty.clone(), + miss_diags: b.diagnostics.clone(), + }) + } +} + +pub fn set_builtin_receiver_is_set(receiver_arg: Rc, scope: Rc) -> bool { + match arg_value(receiver_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: receiver_type, + .. + }) => node_is_set_collection( + receiver_type.clone(), + scope.type_env.clone().source_indices.clone(), + ), + _ => false, + } +} + +pub fn set_union_other_operand_is_resolved_non_set( + other_arg: Rc, + scope: Rc, +) -> bool { + match arg_value(other_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: other_type, .. + }) => !node_is_set_collection( + other_type.clone(), + scope.type_env.clone().source_indices.clone(), + ), + _ => false, + } +} + +pub fn set_element_type_from_receiver( + receiver_type: Rc, + scope: Rc, +) -> Option> { + match set_element_type_in_env(receiver_type.clone(), scope.type_env.clone()) { + Some(elem_slot) => Some(child_type_node(elem_slot.clone())), + None => None, + } +} + +pub fn set_element_type_is_concrete(elem: Rc) -> bool { + match elem.inferred.clone() { + Some(inf) => !is_type_variable(inf.clone()), + None => true, + } +} + +pub fn set_element_types_mismatch( + recv_elem: Rc, + operand_elem: Rc, + source_indices: Rc>>, +) -> bool { + ((set_element_type_is_concrete(recv_elem.clone()) + && set_element_type_is_concrete(operand_elem.clone())) + && !node_type_compatible( + recv_elem.clone(), + operand_elem.clone(), + source_indices.clone(), + )) +} + +pub fn type_node_is_callable(n: Rc) -> bool { + ((n.params.clone().len() as i64) > 0) +} + +pub fn module_skips_direct_call_arg_check(module_name: String) -> bool { + ((v1_rt::string_length(&module_name) >= 3) + && (v1_rt::substring(&module_name, 0, 3) == "v2.".to_string())) +} + +pub fn brand_grounds_transparently_to( + name: String, + other: Rc, + type_env: Rc, + source_indices: Rc>>, +) -> bool { + match lookup_type_by_name(type_env.clone(), name.clone()) { + Some(resolved) => { + ((((resolved.connective.clone() == Connective::NoConnective) + && ((resolved.children.clone().len() as i64) == 0)) + && (resolved.inferred.clone() != None)) + && match resolved.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: target, .. }) => { + let target_name = authored_name_at(source_indices.clone(), target.clone()); + let other_name = authored_name_at(source_indices.clone(), other.clone()); + ((is_kernel_type(target_name.clone()) + && (target_name.clone() == other_name.clone())) + || (qualified_last_segment(target_name.clone()) + == qualified_last_segment(other_name.clone()))) + } + _ => false, + }) + } + None => false, + } +} + +pub fn nominal_call_arg_brand_mismatch( + formal: Rc, + actual: Rc, + type_env: Rc, + source_indices: Rc>>, +) -> bool { + { + let formal_name = authored_name_at(source_indices.clone(), formal.clone()); + let actual_name = authored_name_at(source_indices.clone(), actual.clone()); + ((((((((((formal.connective.clone() != Connective::Arrow) + && (actual.connective.clone() != Connective::Arrow)) + && (formal_name.clone() != "".to_string())) + && (actual_name.clone() != "".to_string())) + && (qualified_last_segment(formal_name.clone()) + != qualified_last_segment(actual_name.clone()))) + && (structural_carrier_template_name(formal.clone(), source_indices.clone()) + == structural_carrier_template_name(actual.clone(), source_indices.clone()))) + && !is_declared_container_alias_spelling(formal_name.clone())) + && !is_declared_container_alias_spelling(actual_name.clone())) + && !brand_grounds_transparently_to( + formal_name.clone(), + actual.clone(), + type_env.clone(), + source_indices.clone(), + )) + && !brand_grounds_transparently_to( + actual_name.clone(), + formal.clone(), + type_env.clone(), + source_indices.clone(), + )) + } +} + +pub fn is_where_refinement_type(ty: Rc) -> bool { + (((ty.connective.clone() == Connective::Conj) && (ty.type_annotation.clone() != None)) + && ((ty.children.clone().len() as i64) == 1)) +} + +pub fn where_refinement_chain(ty: Rc, type_env: Rc) -> Rc>> { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + if is_where_refinement_type(ty.clone()) { + match ty.children.clone().first().cloned() { + Some(base) => { + let base_resolved = match lookup_type_for(type_env.clone(), base.clone()) { + Some(resolved) => resolved.clone(), + None => base.clone(), + }; + v1_rt::concat( + Rc::new(vec![ty.clone()]), + where_refinement_chain(base_resolved.clone(), type_env.clone()), + ) + } + None => Rc::new(vec![ty.clone()]), + } + } else { + Rc::new(vec![ty.clone()]) + } + }) +} + +pub fn type_expr_where_refinement_predicates(ty: Rc) -> Rc>> { + if is_where_refinement_type(ty.clone()) { + match ty.type_annotation.clone() { + Some(annot) => match annot.connective.clone() { + Connective::Conj => annot.children.clone(), + _ => Rc::new(vec![annot.clone()]), + }, + None => Rc::new(vec![]), + } + } else { + Rc::new(vec![]) + } +} + +pub fn type_where_refinement_predicates_transitive( + ty: Rc, + type_env: Rc, +) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for link in where_refinement_chain(ty.clone(), type_env.clone()) + .iter() + .cloned() + { + __result.extend( + (*type_expr_where_refinement_predicates(link.clone())) + .iter() + .cloned(), + ); + } + __result + }) +} + +pub fn peel_where_refinement_base(ty: Rc, type_env: Rc) -> Rc { + match where_refinement_chain(ty.clone(), type_env.clone()) + .last() + .cloned() + { + Some(ground) => ground.clone(), + None => ty.clone(), + } +} + +pub fn where_predicate_name_at( + pred: Rc, + source_indices: Rc>>, +) -> String { + field_init_node_name_at(pred.clone(), source_indices.clone()) +} + +pub fn where_predicate_named_int_arg( + pred: Rc, + field: String, + source_indices: Rc>>, +) -> Option { + match record_lit_named_field_value_optional( + field_init_node_value(pred.clone()), + field.clone(), + source_indices.clone(), + ) { + Some(field_expr) => expr_literal_int_optional(field_expr.clone()), + None => None, + } +} + +pub fn where_predicate_canonical_name(pred_name: String) -> String { + if (pred_name.clone() == "brand".to_string()) { + "Brand".to_string() + } else { + pred_name.clone() + } +} + +pub fn where_predicate_optional_int_args_match( + left: Rc, + right: Rc, + source_indices: Rc>>, +) -> bool { + { + let min_ok = where_predicate_int_bound_args_equivalent( + left.clone(), + right.clone(), + "min".to_string(), + source_indices.clone(), + ); + let max_ok = where_predicate_int_bound_args_equivalent( + left.clone(), + right.clone(), + "max".to_string(), + source_indices.clone(), + ); + (min_ok.clone() && max_ok.clone()) + } +} + +pub fn where_predicate_int_bound_args_equivalent( + left: Rc, + right: Rc, + field: String, + source_indices: Rc>>, +) -> bool { + match record_lit_named_field_value_optional( + field_init_node_value(left.clone()), + field.clone(), + source_indices.clone(), + ) { + None => match record_lit_named_field_value_optional( + field_init_node_value(right.clone()), + field.clone(), + source_indices.clone(), + ) { + None => true, + Some(_) => false, + }, + Some(left_expr) => match record_lit_named_field_value_optional( + field_init_node_value(right.clone()), + field.clone(), + source_indices.clone(), + ) { + None => false, + Some(right_expr) => match expr_literal_int_optional(left_expr.clone()) { + Some(a) => match expr_literal_int_optional(right_expr.clone()) { + Some(b) => (a.clone() == b.clone()), + None => false, + }, + None => false, + }, + }, + } +} + +pub fn where_predicate_literal_string_args_match(left: Rc, right: Rc) -> bool { + match expr_literal_string_optional(field_init_node_value(left.clone())) { + Some(a) => match expr_literal_string_optional(field_init_node_value(right.clone())) { + Some(b) => (a.clone() == b.clone()), + None => false, + }, + None => match expr_literal_string_optional(field_init_node_value(right.clone())) { + Some(_) => false, + None => true, + }, + } +} + +pub fn where_refinement_predicates_equivalent( + formal_pred: Rc, + actual_pred: Rc, + source_indices: Rc>>, +) -> bool { + { + let formal_name = where_predicate_canonical_name(where_predicate_name_at( + formal_pred.clone(), + source_indices.clone(), + )); + let actual_name = where_predicate_canonical_name(where_predicate_name_at( + actual_pred.clone(), + source_indices.clone(), + )); + if (formal_name.clone() != actual_name.clone()) { + false + } else { + if (formal_name.clone() == "range".to_string()) { + where_predicate_optional_int_args_match( + formal_pred.clone(), + actual_pred.clone(), + source_indices.clone(), + ) + } else { + if (((((formal_name.clone() == "Brand".to_string()) + || (formal_name.clone() == "Pattern".to_string())) + || (formal_name.clone() == "Format".to_string())) + || (formal_name.clone() == "ContentEncoding".to_string())) + || (formal_name.clone() == "Domain".to_string())) + { + where_predicate_literal_string_args_match( + formal_pred.clone(), + actual_pred.clone(), + ) + } else { + true + } + } + } + } +} + +pub fn where_refinement_min_length_implication_note() -> String { + thread_local! { + static CACHED: String = { + "THE FRAGMENT IS TWO PARTIAL FUNCTIONS, NOT AN IMPLICATION ENGINE, and the asymmetry between them is the entire soundness argument. Predicate implication in general is undecidable, so this decides exactly one relation and refuses outside it: a value whose refinement GUARANTEES a minimum length satisfies a formal position whose refinement DEMANDS a minimum length AND NOTHING ELSE. Provider and demander are separate partial functions over the same closed predicate vocabulary because a predicate can inhabit one side and not the other, and collapsing them into one min-length table is a FAIL-OPEN that the obvious framing walks straight into: model lower_hex_64 as min-length 64 on both sides and a formal lower_hex_64 is then satisfied by an actual lower_hex_128, since 128 >= 64 — but those predicates demand DIFFERENT EXACT LENGTHS and a 128-digit string is not a valid sha256 hex. lower_hex_N therefore appears as a PROVIDER only (it guarantees exactly N lower-hex digits, hence at least N characters) and never as a demander (it demands an exact length and a charset, neither of which a length lower bound establishes). non_empty is the only predicate in the live vocabulary that is a pure length lower bound, so it is the only demander, and it is a provider too because it demands what it guarantees. Everything outside both tables answers Absent and the caller falls through to the pre-existing name-equality path unchanged, so this widens what the wall can DECIDE and narrows nothing it already decided. oci_other_digest_algorithm and oci_other_digest_encoded are deliberately NOT providers even though their grammars happen to exclude the empty string: that fact lives in oci_digest_algorithm_wire_holds / oci_encoded_digest_syntax_valid as a consequence of a syntax walk, not as a declared constant this table could cite, and asserting a bound the predicate does not state is the fabrication DESIGN §5 forbids. The four lower_hex_N bounds ARE declared constants — each is content_hash_validate_lower_hex_length(text, expected_hex_digits: N), whose body is text.length() == N — so the number in this table is the number in the predicate, cited rather than restated. WHY THIS IS A WALL AND NOT A WIDENING: the two corpus sites it closes (std.content_hash serialize_content_hash, `s.digest as NonEmptyStr` over Fnv1a64StructuralDigestHex and `d.hex as NonEmptyStr` over Sha1DigestHex) were carrying WhereRefinementUnenforced advisories for REFUSED evidence, not absent evidence — the value's own declared type already proved the property and where_refinement_predicates_equivalent could not see it because it compares predicate NAMES for equality, and lower_hex_40 != non_empty. WHAT IS NOT STRUCTURAL, STATED AT ITS HONEST RUNG (§4b) BECAUSE A TABLE PAIR WHOSE SOUNDNESS LIVES IN PROSE DECAYS SILENTLY: nothing prevents a predicate from being enrolled in BOTH tables, and membership in both is NOT the fail-open — non_empty is deliberately in both and is sound there, because it demands exactly what it guarantees. The real enrollment condition is narrower: a predicate may take a REQUIRED row only if its entire semantics is a length lower bound and nothing else. lower_hex_64 in both tables would be unsound not because it appears twice but because it demands an exact length and a charset that a lower bound does not establish. That condition is enforced by nobody: these are two hand-written name-keyed partial functions, so a future demander row asserting more than length would fail open and no check would fire. The decided relation guaranteed >= required is mechanically enforced; the authoring discipline that populates the demander table is DILIGENCE, rung MITIGATABLE, and it is contained only by the vocabulary being closed and small. Next-rung trigger is the same dissolve-on below: once the bounds are fields on WhereRefinementPredicateKind's own declaration, a predicate states its guarantee and its demand once and the mis-enrollment has no place to be written. Dissolve-on: feature:where-refinement-predicate-coproduct — when WhereRefinementPredicateKind replaces the string classifiers, the guaranteed and required bounds become fields on the predicate's own declaration rather than two tables a reader must keep in lockstep with where_refinement_is_string_literal_predicate and decidable_where_string_predicate_holds.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn where_predicate_guaranteed_min_length(pred_name: String) -> Option { + if (pred_name.clone() == "non_empty".to_string()) { + Some(1) + } else { + if (pred_name.clone() == "lower_hex_16".to_string()) { + Some(16) + } else { + if (pred_name.clone() == "lower_hex_40".to_string()) { + Some(40) + } else { + if (pred_name.clone() == "lower_hex_64".to_string()) { + Some(64) + } else { + if (pred_name.clone() == "lower_hex_128".to_string()) { + Some(128) + } else { + None + } + } + } + } + } +} + +pub fn where_predicate_required_min_length(pred_name: String) -> Option { + if (pred_name.clone() == "non_empty".to_string()) { + Some(1) + } else { + None + } +} + +pub fn where_refinement_predicate_min_length_implies( + formal_pred: Rc, + actual_pred: Rc, + source_indices: Rc>>, +) -> bool { + match where_predicate_required_min_length(where_predicate_canonical_name( + where_predicate_name_at(formal_pred.clone(), source_indices.clone()), + )) { + Some(required) => { + match where_predicate_guaranteed_min_length(where_predicate_canonical_name( + where_predicate_name_at(actual_pred.clone(), source_indices.clone()), + )) { + Some(guaranteed) => (guaranteed.clone() >= required.clone()), + None => false, + } + } + None => false, + } +} + +pub fn where_refinement_predicate_satisfied_by( + formal_pred: Rc, + actual_pred: Rc, + source_indices: Rc>>, +) -> bool { + (where_refinement_predicates_equivalent( + formal_pred.clone(), + actual_pred.clone(), + source_indices.clone(), + ) || where_refinement_predicate_min_length_implies( + formal_pred.clone(), + actual_pred.clone(), + source_indices.clone(), + )) +} + +pub fn where_refinement_predicates_covered( + formal_preds: Rc>>, + actual_preds: Rc>>, + source_indices: Rc>>, +) -> bool { + { + let mut __all = true; + for fp in formal_preds.clone().iter().cloned() { + if !({ + let mut __found = false; + for ap in actual_preds.clone().iter().cloned() { + if where_refinement_predicate_satisfied_by( + fp.clone(), + ap.clone(), + source_indices.clone(), + ) { + __found = true; + break; + } + } + __found + }) { + __all = false; + break; + } + } + __all + } +} + +pub fn decidable_where_int_predicate_holds( + pred_name: String, + pred: Rc, + value: i64, + source_indices: Rc>>, +) -> Option { + if (pred_name.clone() == "gt_zero".to_string()) { + Some((value.clone() > 0)) + } else { + if (pred_name.clone() == "range".to_string()) { + { + let passes_min = match record_lit_named_field_value_optional( + field_init_node_value(pred.clone()), + "min".to_string(), + source_indices.clone(), + ) { + None => Some(true), + Some(field_expr) => match expr_literal_int_optional(field_expr.clone()) { + Some(lo) => Some((value.clone() >= lo.clone())), + None => None, + }, + }; + let passes_max = match record_lit_named_field_value_optional( + field_init_node_value(pred.clone()), + "max".to_string(), + source_indices.clone(), + ) { + None => Some(true), + Some(field_expr) => match expr_literal_int_optional(field_expr.clone()) { + Some(hi) => Some((value.clone() <= hi.clone())), + None => None, + }, + }; + match passes_min.clone() { + Some(min_ok) => match passes_max.clone() { + Some(max_ok) => Some((min_ok.clone() && max_ok.clone())), + None => None, + }, + None => None, + } + } + } else { + None + } + } +} + +pub fn where_refinement_predicate_kind_scaffold_note() -> String { + thread_local! { + static CACHED: String = { + "owner: v1.compiler.infer. lane: where_refinement_diags_for_predicate dispatch. interim: predicate kind routed via where_refinement_is_*_literal_predicate / where_refinement_is_deferred_predicate closed string sets — must stay in lockstep with decidable_*_predicate_holds and where_refinement_predicates_equivalent. bound: vocabulary changes require updating all classifier fns + eval + equivalence arms in one commit. dissolve-on: feature:where-refinement-predicate-coproduct (WhereRefinementPredicateKind coproduct replacing string classifiers).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn where_refinement_is_int_literal_predicate(pred_name: String) -> bool { + ((pred_name.clone() == "gt_zero".to_string()) || (pred_name.clone() == "range".to_string())) +} + +pub fn where_refinement_is_string_literal_predicate(pred_name: String) -> bool { + (((((((pred_name.clone() == "non_empty".to_string()) + || (pred_name.clone() == "lower_hex_64".to_string())) + || (pred_name.clone() == "lower_hex_40".to_string())) + || (pred_name.clone() == "lower_hex_128".to_string())) + || (pred_name.clone() == "lower_hex_16".to_string())) + || (pred_name.clone() == "oci_other_digest_algorithm".to_string())) + || (pred_name.clone() == "oci_other_digest_encoded".to_string())) +} + +pub fn where_refinement_is_deferred_predicate(pred_name: String) -> bool { + ((((((((pred_name.clone() == "brand".to_string()) + || (pred_name.clone() == "Brand".to_string())) + || (pred_name.clone() == "unicode_scalar".to_string())) + || (pred_name.clone() == "is_text_readable".to_string())) + || (pred_name.clone() == "Pattern".to_string())) + || (pred_name.clone() == "Format".to_string())) + || (pred_name.clone() == "ContentEncoding".to_string())) + || (pred_name.clone() == "Domain".to_string())) +} + +pub fn decidable_where_string_predicate_holds(pred_name: String, value: String) -> Option { + if (pred_name.clone() == "non_empty".to_string()) { + Some((v1_rt::string_length(&value) > 0)) + } else { + if (pred_name.clone() == "lower_hex_64".to_string()) { + Some(content_hash_validate_lower_hex_length(value.clone(), 64)) + } else { + if (pred_name.clone() == "lower_hex_40".to_string()) { + Some(content_hash_validate_lower_hex_length(value.clone(), 40)) + } else { + if (pred_name.clone() == "lower_hex_128".to_string()) { + Some(content_hash_validate_lower_hex_length(value.clone(), 128)) + } else { + if (pred_name.clone() == "lower_hex_16".to_string()) { + Some(content_hash_validate_lower_hex_length(value.clone(), 16)) + } else { + if (pred_name.clone() == "oci_other_digest_algorithm".to_string()) { + Some(oci_other_digest_algorithm(value.clone())) + } else { + if (pred_name.clone() == "oci_other_digest_encoded".to_string()) { + Some(oci_other_digest_encoded(value.clone())) + } else { + None + } + } + } + } + } + } + } +} + +pub fn where_predicate_range_non_literal_bound_reason( + pred: Rc, + source_indices: Rc>>, +) -> Option { + match record_lit_named_field_value_optional( + field_init_node_value(pred.clone()), + "min".to_string(), + source_indices.clone(), + ) { + Some(min_expr) => match expr_literal_int_optional(min_expr.clone()) { + Some(_) => match record_lit_named_field_value_optional( + field_init_node_value(pred.clone()), + "max".to_string(), + source_indices.clone(), + ) { + Some(max_expr) => match expr_literal_int_optional(max_expr.clone()) { + Some(_) => None, + None => Some("predicate argument is not an int literal".to_string()), + }, + None => None, + }, + None => Some("predicate argument is not an int literal".to_string()), + }, + None => match record_lit_named_field_value_optional( + field_init_node_value(pred.clone()), + "max".to_string(), + source_indices.clone(), + ) { + Some(max_expr) => match expr_literal_int_optional(max_expr.clone()) { + Some(_) => None, + None => Some("predicate argument is not an int literal".to_string()), + }, + None => None, + }, + } +} + +pub fn where_refinement_unenforced_error( + predicate: String, + formal: Rc, + reason: String, + span: Rc, + module_name: String, + source_indices: Rc>>, +) -> Rc { + make_error_node( + Rc::new(CompilerDiagnostic::WhereRefinementUnenforced { + predicate: predicate.clone(), + formal_type: node_type_shape(formal.clone(), source_indices.clone()), + reason: reason.clone(), + span: span.clone(), + }), + module_name.clone(), + ) +} + +pub fn where_refinement_diags_for_predicate( + pred: Rc, + formal: Rc, + value_expr: Rc, + span: Rc, + module_name: String, + source_indices: Rc>>, +) -> Rc>> { + { + let pname = field_init_node_name_at(pred.clone(), source_indices.clone()); + let refinement_refusal = Rc::new(vec![type_mismatch_error( + node_type_shape(formal.clone(), source_indices.clone()), + node_type_shape(resolved_type(value_expr.clone()), source_indices.clone()), + span.clone(), + module_name.clone(), + )]); + if where_refinement_is_int_literal_predicate(pname.clone()) { + match expr_literal_int_optional(value_expr.clone()) { + Some(v) => match decidable_where_int_predicate_holds( + pname.clone(), + pred.clone(), + v.clone(), + source_indices.clone(), + ) { + Some(holds) => { + if !holds.clone() { + refinement_refusal + } else { + Rc::new(vec![]) + } + } + None => { + if (pname.clone() == "range".to_string()) { + match where_predicate_range_non_literal_bound_reason( + pred.clone(), + source_indices.clone(), + ) { + Some(reason) => Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + reason.clone(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]), + None => Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "int predicate not implemented".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]), + } + } else { + Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "int predicate not implemented".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]) + } + } + }, + None => { + if expr_is_any_literal(value_expr.clone()) { + refinement_refusal + } else { + Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "non-literal value at refined position".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]) + } + } + } + } else { + if where_refinement_is_string_literal_predicate(pname.clone()) { + { + let string_literal_value = + match expr_literal_string_optional(value_expr.clone()) { + Some(v) => Some(v.clone()), + None => expr_literal_symbol_optional(value_expr.clone()), + }; + match string_literal_value.clone() { + Some(v) => { + match decidable_where_string_predicate_holds(pname.clone(), v.clone()) { + Some(holds) => { + if !holds.clone() { + refinement_refusal + } else { + Rc::new(vec![]) + } + } + None => Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "string predicate not implemented".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]), + } + } + None => { + if expr_is_any_literal(value_expr.clone()) { + refinement_refusal + } else { + Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "non-literal value at refined position".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]) + } + } + } + } + } else { + if where_refinement_is_deferred_predicate(pname.clone()) { + Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "predicate deferred at compile time".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]) + } else { + Rc::new(vec![where_refinement_unenforced_error( + pname.clone(), + formal.clone(), + "predicate not enforced at compile time".to_string(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )]) + } + } + } + } +} + +pub fn where_refinement_value_under_cast(mut value_expr: Rc) -> Rc { + loop { + match (*value_expr.expr_data.clone()).clone() { + ExprData::ExprCast => { + let __tco_0 = cast_expr(value_expr); + value_expr = __tco_0; + continue; + } + _ => { + break value_expr.clone(); + } + } + } +} + +pub fn where_refinement_peel_cost_note() -> String { + thread_local! { + static CACHED: String = { + "Cost shape (bare-minimum-cost, DESIGN 6): peel_nominal_alias_identity runs only on the refusal path (predicates present AND not covered), inside the final else of where_refinement_mismatch_diags. That fn runs on EVERY infer_expr with an expected type; 97% of calls find zero predicates, and an eager peel at fn entry was 6.5s of discarded resolve_node_bounded work per host_effect_realize entry compile (typecheck-perf investigation, 2026-07-31). formal_checked is consumed only by where_refinement_diags_for_predicate, so the sink is behavior-identical: peel is pure and its NodeResolveResult diagnostics were already discarded.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn where_refinement_mismatch_diags( + formal: Rc, + value_expr: Rc, + span: Rc, + module_name: String, + type_env: Rc, +) -> Rc>> { + { + let source_indices = type_env.source_indices.clone(); + let formal_resolved = match lookup_type_for(type_env.clone(), formal.clone()) { + Some(resolved) => resolved.clone(), + None => formal.clone(), + }; + let preds = + type_where_refinement_predicates_transitive(formal_resolved.clone(), type_env.clone()); + if ((preds.clone().len() as i64) == 0) { + Rc::new(vec![]) + } else { + { + let value_for_refinement = where_refinement_value_under_cast(value_expr.clone()); + let actual_raw = resolved_type(value_for_refinement.clone()); + let actual_resolved = match lookup_type_for(type_env.clone(), actual_raw.clone()) { + Some(resolved) => resolved.clone(), + None => actual_raw.clone(), + }; + let actual_preds = type_where_refinement_predicates_transitive( + actual_resolved.clone(), + type_env.clone(), + ); + if where_refinement_predicates_covered( + preds.clone(), + actual_preds.clone(), + source_indices.clone(), + ) { + Rc::new(vec![]) + } else { + { + let formal_checked = peel_nominal_alias_identity( + formal_resolved.clone(), + type_env.clone(), + module_name.clone(), + ); + Rc::new({ + let mut __result = Vec::new(); + for pred in preds.clone().iter().cloned() { + __result.extend( + (*where_refinement_diags_for_predicate( + pred.clone(), + formal_checked.clone(), + value_for_refinement.clone(), + span.clone(), + module_name.clone(), + source_indices.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }) + } + } + } + } + } +} + +pub fn with_expected_where_refinement_diags( + result: Rc, + expected: Option>, + scope: Rc, +) -> Rc { + match expected.clone() { + Some(expected_ty) => match (*result.typed.clone().expr_data.clone()).clone() { + ExprData::ExprCast => result.clone(), + _ => Rc::new(InferResult { + typed: result.typed.clone(), + diagnostics: v1_rt::concat( + result.diagnostics.clone(), + where_refinement_mismatch_diags( + expected_ty.clone(), + result.typed.clone(), + result.typed.clone().span.clone(), + scope.module_name.clone(), + scope.type_env.clone(), + ), + ), + }), + }, + None => result.clone(), + } +} + +pub fn infer_expr( + texpr: Rc, + scope: Rc, + expected: Option>, +) -> Rc { + with_expected_where_refinement_diags( + infer_expr_body(texpr.clone(), scope.clone(), expected.clone()), + expected.clone(), + scope.clone(), + ) +} + +pub fn kernel_value_declared_type_mismatch( + formal: Rc, + actual: Rc, + type_env: Rc, + source_indices: Rc>>, +) -> bool { + if (((formal.connective.clone() == Connective::Arrow) + || (actual.connective.clone() == Connective::Arrow)) + || ((actual.children.clone().len() as i64) > 0)) + { + false + } else { + { + let formal_base = peel_where_refinement_base(formal.clone(), type_env.clone()); + let actual_name = authored_name_at(source_indices.clone(), actual.clone()); + if ((is_kernel_type(actual_name.clone()) == false) + || (actual_name.clone() == "Unit".to_string())) + { + false + } else { + { + let formal_name = authored_name_at(source_indices.clone(), formal_base.clone()); + if (((formal_name.clone() == "".to_string()) + || (qualified_last_segment(formal_name.clone()) + == qualified_last_segment(actual_name.clone()))) + || dag_can_cast(actual_name.clone(), formal_name.clone())) + { + false + } else { + if (structural_carrier_template_name( + formal_base.clone(), + source_indices.clone(), + ) == structural_carrier_template_name( + actual.clone(), + source_indices.clone(), + )) { + false + } else { + if is_kernel_type(formal_name.clone()) { + true + } else { + match lookup_type_by_name(type_env.clone(), formal_name.clone()) { + Some(decl) => { + let decl_is_refinement_over_actual = + (((decl.connective.clone() == Connective::Conj) + && ((decl.children.clone().len() as i64) == 1)) + && ((decl.type_annotation.clone() != None) + || match decl.children.clone().first().cloned() + { + Some(refinement_child) => { + (authored_name_at( + source_indices.clone(), + refinement_child.clone(), + ) == actual_name.clone()) + } + None => false, + })); + ((((decl.connective.clone() == Connective::Conj) + || (decl.connective.clone() == Connective::Disj)) + && ((decl.children.clone().len() as i64) > 0)) + && (decl_is_refinement_over_actual.clone() == false)) + } + None => false, + } + } + } + } + } + } + } + } +} + +pub fn application_type_name_identity( + type_name: String, + type_env: Rc, + module_name: String, + source_indices: Rc>>, +) -> String { + match lookup_type_by_name(type_env.clone(), type_name.clone()) { + Some(decl) => match decl.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: target, .. }) => authored_name_at( + source_indices.clone(), + peel_nominal_alias_identity(target.clone(), type_env.clone(), module_name.clone()), + ), + _ => authored_name_at( + source_indices.clone(), + peel_nominal_alias_identity(decl.clone(), type_env.clone(), module_name.clone()), + ), + }, + None => type_name.clone(), + } +} + +pub fn structured_application_structural_type_name( + type_name: String, + scope: Rc, +) -> String { + application_type_name_identity( + type_name.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + scope.type_env.clone().source_indices.clone(), + ) +} + +pub fn structured_application_record_lit_nominal_name( + lit_name: String, + scope: Rc, +) -> String { + structured_application_structural_type_name(lit_name.clone(), scope.clone()) +} + +pub fn structured_application_lit_is_declared_optional_variant( + formal: Rc, + lit_name: String, + scope: Rc, +) -> bool { + { + let source_indices = scope.type_env.clone().source_indices.clone(); + let formal_resolved = match lookup_type_for( + scope.type_env.clone(), + with_required_cardinality(formal.clone()), + ) { + Some(resolved) => resolved.clone(), + None => with_required_cardinality(formal.clone()), + }; + if ((formal.return_cardinality.clone() == Cardinality::CardOptional) + && ((lit_name.clone() == "Present".to_string()) + || (lit_name.clone() == "Absent".to_string()))) + { + true + } else { + has_child_named( + formal_resolved.clone(), + lit_name.clone(), + source_indices.clone(), + ) + } + } +} + +pub fn application_type_names_compatible( + formal_name: String, + lit_name: String, + type_env: Rc, + module_name: String, + source_indices: Rc>>, +) -> bool { + if ((formal_name.clone() == "".to_string()) || (lit_name.clone() == "".to_string())) { + (formal_name.clone() == lit_name.clone()) + } else { + if (formal_name.clone() == lit_name.clone()) { + true + } else { + { + let formal_identity = application_type_name_identity( + formal_name.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ); + let lit_identity = application_type_name_identity( + lit_name.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ); + if (formal_identity.clone() == lit_identity.clone()) { + true + } else { + if dag_can_cast(lit_name.clone(), formal_name.clone()) { + true + } else { + if (type_name_transparently_aliases_to( + lit_name.clone(), + formal_name.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ) || type_name_transparently_aliases_to( + formal_name.clone(), + lit_name.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + )) { + true + } else { + match lookup_type_by_name(type_env.clone(), formal_name.clone()) { + Some(formal_decl) => brand_grounds_transparently_to( + lit_name.clone(), + formal_decl.clone(), + type_env.clone(), + source_indices.clone(), + ), + None => false, + } + } + } + } + } + } + } +} + +pub fn type_name_transparently_aliases_to( + mut alias_name: String, + mut target_name: String, + mut type_env: Rc, + mut module_name: String, + mut source_indices: Rc>>, +) -> bool { + loop { + match lookup_type_by_name(type_env.clone(), alias_name.clone()) { + Some(decl) => { + let peeled = peel_nominal_alias_identity( + decl.clone(), + type_env.clone(), + module_name.clone(), + ); + let peeled_name = authored_name_at(source_indices.clone(), peeled.clone()); + if (peeled_name.clone() == alias_name.clone()) { + break false; + } else { + if (peeled_name.clone() == target_name.clone()) { + break true; + } else { + { + let __tco_0 = peeled_name.clone(); + alias_name = __tco_0; + continue; + } + } + } + } + None => { + break false; + } + } + } +} + +pub fn structured_application_site_type_mismatch( + formal: Rc, + actual_expr: Rc, + scope: Rc, +) -> bool { + match (*actual_expr.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => { + structured_application_site_type_mismatch_with_peeled( + formal.clone(), + peel_nominal_alias_identity( + formal.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ), + actual_expr.clone(), + scope.clone(), + ) + } + _ => false, + } +} + +pub fn structured_application_site_type_mismatch_with_peeled( + formal: Rc, + formal_peeled: Rc, + actual_expr: Rc, + scope: Rc, +) -> bool { + match (*actual_expr.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => { + let source_indices = scope.type_env.clone().source_indices.clone(); + if type_node_is_callable(formal_peeled.clone()) { + false + } else { + { + let formal_name = + authored_name_at(source_indices.clone(), formal_peeled.clone()); + if (formal_name.clone() == "".to_string()) { + false + } else { + { + let formal_structural = structured_application_structural_type_name( + formal_name.clone(), + scope.clone(), + ); + match record_lit_type_name_at( + actual_expr.clone(), + source_indices.clone(), + ) { + Some(lit_name) => { + if application_type_names_compatible( + formal_name.clone(), + lit_name.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + source_indices.clone(), + ) { + false + } else { + { + let lit_nominal = + structured_application_record_lit_nominal_name( + lit_name.clone(), + scope.clone(), + ); + if ((lit_name.clone() == "".to_string()) || structured_application_lit_is_declared_optional_variant(formal.clone(), lit_name.clone(), scope.clone())) { + false + } else { + if match record_lit_alias_struct_expansion(lit_name.clone(), scope.clone()) { + Some(expansion) => { + let expanded_name = authored_name_at(source_indices.clone(), expansion.resolved.clone()); +((expanded_name.clone() == formal_structural.clone()) || application_type_names_compatible(formal_structural.clone(), expanded_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) +}, + None => false, +} { + false + } else { + if brand_grounds_transparently_to(lit_name.clone(), formal_peeled.clone(), scope.type_env.clone(), source_indices.clone()) { + false + } else { + if ((((formal_structural.clone() == lit_nominal.clone()) || (formal_structural.clone() == lit_name.clone())) || application_type_names_compatible(formal_structural.clone(), lit_nominal.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) || application_type_names_compatible(formal_structural.clone(), lit_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) { + false + } else { + { + let formal_decl = match lookup_type_for(scope.type_env.clone(), with_required_cardinality(formal_peeled.clone())) { + Some(resolved) => Some(resolved.clone()), + None => lookup_type_by_name(scope.type_env.clone(), formal_name.clone()), +}; +match formal_decl.clone() { + Some(decl) => match decl.connective.clone() { + Connective::Disj => if has_child_named(decl.clone(), lit_name.clone(), source_indices.clone()) { + false + } else { + match variant_owner_node(scope.clone(), lit_name.clone()) { + Some(owner) => { + let owner_name = authored_name_at(source_indices.clone(), owner.clone()); +!application_type_names_compatible(formal_name.clone(), owner_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone()) +}, + None => true, +} + }, + Connective::Conj => { + let decl_name = structured_application_structural_type_name(authored_name_at(source_indices.clone(), decl.clone()), scope.clone()); +(!application_type_names_compatible(decl_name.clone(), lit_nominal.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone()) && !application_type_names_compatible(decl_name.clone(), lit_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) +}, + _ => false, +}, + None => if is_kernel_type(formal_name.clone()) { + match lookup_type_by_name(scope.type_env.clone(), lit_name.clone()) { + Some(lit_decl) => ((lit_decl.connective.clone() == Connective::Conj) || (lit_decl.connective.clone() == Connective::Disj)), + None => match variant_owner_node(scope.clone(), lit_name.clone()) { + Some(_) => true, + None => false, +}, +} + } else { + if ((lookup_type_by_name(scope.type_env.clone(), lit_name.clone()) != None) && (lookup_type_by_name(scope.type_env.clone(), formal_name.clone()) != None)) { + true + } else { + false + } + }, +} +} + } + } + } + } + } + } + } + None => false, + } + } + } + } + } + } + _ => false, + } +} + +pub fn direct_call_structured_record_literal_resolved_type_mismatch( + formal: Rc, + actual_expr: Rc, + type_env: Rc, + module_name: String, + source_indices: Rc>>, +) -> bool { + match (*actual_expr.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => { + let formal_peeled = + peel_nominal_alias_identity(formal.clone(), type_env.clone(), module_name.clone()); + let formal_name = authored_name_at(source_indices.clone(), formal_peeled.clone()); + match record_lit_type_name_at(actual_expr.clone(), source_indices.clone()) { + Some(lit_name) => { + if application_type_names_compatible( + formal_name.clone(), + lit_name.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ) { + false + } else { + { + let actual_raw = resolved_type(actual_expr.clone()); + let actual = peel_nominal_alias_identity( + actual_raw.clone(), + type_env.clone(), + module_name.clone(), + ); + direct_call_arg_type_mismatch( + formal.clone(), + actual.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ) + } + } + } + None => { + let actual_raw = resolved_type(actual_expr.clone()); + let actual = peel_nominal_alias_identity( + actual_raw.clone(), + type_env.clone(), + module_name.clone(), + ); + direct_call_arg_type_mismatch( + formal.clone(), + actual.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ) + } + } + } + _ => false, + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CallFormalApplication { + pub index: i64, + pub param_name: String, + pub formal_subst: Rc, + pub formal: Rc, + pub matched_arg: Option>, +} + +pub fn call_application_plan_note() -> String { + thread_local! { + static CACHED: String = { + "Cost shape (DESIGN §6 bare-minimum-cost) and single authority (§3). direct_call_arg_mismatch_diags and direct_call_structured_application_mismatch_diags were line-for-line duplicates of the same per-formal prologue: param_node_type_expr, substitute_generics, peel_nominal_alias_identity, authored_name_at, and the named-then-positional actual search. Both run over the SAME value_params, typed_args and call_subst at the one direct-call seam, so every formal was canonicalized twice per call. peel_nominal_alias_identity is resolve_node_bounded, an unmemoized recursive rebuild allocating a fresh Node per level, and it measured as the ENTIRE cost of the conformance seam: on gunbc.host_effect_realize the two timed peels inside direct_call_arg_mismatch_diags accounted for that function to within instrument overhead (62719ms + 62804ms against 125438ms over 330 calls), while the timer around direct_call_arg_type_mismatch never entered the top fourteen operations and substitute_generics already short-circuits an empty substitution. That module holds 63% of all corpus type inference. Building the binding ONCE and passing it to both consumers is the deduplication, not a cache: no map is introduced, so nothing here becomes an order-exposing operation in the v2.std.determinism denominator. Behavior is identical because every recomputed term is a pure function of arguments both callers already share.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn build_call_application_plan( + value_params: Rc>>, + typed_args: Rc>>, + call_subst: Rc>>, + type_env: Rc, + module_name: String, +) -> Rc>> { + { + let source_indices = type_env.source_indices.clone(); + Rc::new({ + let mut __result = Vec::new(); + for pair in Rc::new( + value_params + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.push({ + let formal_raw = param_node_type_expr(pair.1.clone()); + let formal_subst = substitute_generics( + formal_raw.clone(), + call_subst.clone(), + source_indices.clone(), + ); + let param_name = authored_name_at(source_indices.clone(), pair.1.clone()); + Rc::new(CallFormalApplication { + index: pair.0.clone(), + param_name: param_name.clone(), + formal_subst: formal_subst.clone(), + formal: peel_nominal_alias_identity( + formal_subst.clone(), + type_env.clone(), + module_name.clone(), + ), + matched_arg: match Rc::new({ + let mut __result = Vec::new(); + for ta in typed_args.clone().iter().cloned() { + if arg_has_name( + ta.clone(), + param_name.clone(), + source_indices.clone(), + ) { + __result.push(ta); + } + } + __result + }) + .first() + .cloned() + { + Some(named_ta) => Some(named_ta.clone()), + None => typed_args + .clone() + .iter() + .cloned() + .skip(pair.0.clone() as usize) + .next(), + }, + }) + }); + } + __result + }) + } +} + +pub fn direct_call_structured_application_mismatch_diags( + plan: Rc>>, + scope: Rc, +) -> Rc>> { + { + let type_env = scope.type_env.clone(); + let module_name = scope.module_name.clone(); + let source_indices = type_env.source_indices.clone(); + Rc::new({ + let mut __result = Vec::new(); + for app in plan.clone().iter().cloned() { + __result.extend( + (*{ + let formal_subst = app.formal_subst.clone(); + let formal = app.formal.clone(); + match app.matched_arg.clone() { + Some(ta) => { + let actual_expr = arg_value(ta.clone()); + if (structured_application_site_type_mismatch_with_peeled( + formal_subst.clone(), + formal.clone(), + actual_expr.clone(), + scope.clone(), + ) + || direct_call_structured_record_literal_resolved_type_mismatch( + formal.clone(), + actual_expr.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + )) + { + { + let actual_raw = resolved_type(actual_expr.clone()); + let actual = peel_nominal_alias_identity( + actual_raw.clone(), + type_env.clone(), + module_name.clone(), + ); + Rc::new(vec![type_mismatch_error( + node_type_shape(formal.clone(), source_indices.clone()), + node_type_shape(actual.clone(), source_indices.clone()), + actual_expr.span.clone(), + module_name.clone(), + )]) + } + } else { + Rc::new(vec![]) + } + } + None => Rc::new(vec![]), + } + }) + .iter() + .cloned(), + ); + } + __result + }) + } +} + +pub fn container_element_nominal_brand_mismatch( + formal: Rc, + actual: Rc, + type_env: Rc, + module_name: String, + source_indices: Rc>>, +) -> bool { + if ((node_is_element_collection(formal.clone(), source_indices.clone()) + && node_is_element_collection(actual.clone(), source_indices.clone())) + && (authored_name_at(source_indices.clone(), formal.clone()) + == authored_name_at(source_indices.clone(), actual.clone()))) + { + match formal.children.clone().first().cloned() { + Some(formal_ch) => match actual.children.clone().first().cloned() { + Some(actual_ch) => { + let formal_el = peel_nominal_alias_identity( + child_type_node(formal_ch.clone()), + type_env.clone(), + module_name.clone(), + ); + let actual_el = peel_nominal_alias_identity( + child_type_node(actual_ch.clone()), + type_env.clone(), + module_name.clone(), + ); + nominal_call_arg_brand_mismatch( + formal_el.clone(), + actual_el.clone(), + type_env.clone(), + source_indices.clone(), + ) + } + None => false, + }, + None => false, + } + } else { + false + } +} + +pub fn direct_call_arg_type_mismatch( + formal: Rc, + actual: Rc, + type_env: Rc, + module_name: String, + source_indices: Rc>>, +) -> bool { + if (type_node_is_callable(formal.clone()) || type_node_is_callable(actual.clone())) { + false + } else { + ((nominal_call_arg_brand_mismatch( + formal.clone(), + actual.clone(), + type_env.clone(), + source_indices.clone(), + ) || container_element_nominal_brand_mismatch( + formal.clone(), + actual.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + )) || kernel_value_declared_type_mismatch( + formal.clone(), + actual.clone(), + type_env.clone(), + source_indices.clone(), + )) + } +} + +pub fn borrowed_callable_call_type( + gnode: Rc, + typed_args: Rc>>, + scope: Rc, +) -> Rc { + { + let source_indices = scope.type_env.clone().source_indices.clone(); + let base = callable_inferred(gnode.clone()); + let tp_names = fn_type_param_names(gnode.clone(), source_indices.clone()); + if ((tp_names.clone().len() as i64) == 0) { + base + } else { + { + let value_params = Rc::new({ + let mut __result = Vec::new(); + for p in gnode.params.clone().iter().cloned() { + if !param_is_generic_decl(p.clone(), source_indices.clone()) { + __result.push(p); + } + } + __result + }); + let subst = Rc::new( + value_params + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, pair: (i64, Rc)| { + let formal_raw = param_node_type_expr(pair.1.clone()); + let param_name = authored_name_at(source_indices.clone(), pair.1.clone()); + let matched_arg = match Rc::new({ + let mut __result = Vec::new(); + for ta in typed_args.clone().iter().cloned() { + if arg_has_name( + ta.clone(), + param_name.clone(), + source_indices.clone(), + ) { + __result.push(ta); + } + } + __result + }) + .first() + .cloned() + { + Some(named_ta) => Some(named_ta.clone()), + None => typed_args + .clone() + .iter() + .cloned() + .skip(pair.0.clone() as usize) + .next(), + }; + match matched_arg.clone() { + Some(ta) => unify_generics( + formal_raw.clone(), + resolved_type(arg_value(ta.clone())), + tp_names.clone(), + source_indices.clone(), + acc.clone(), + ), + None => acc.clone(), + } + }, + ); + substitute_generics(base, subst.clone(), source_indices.clone()) + } + } + } +} + +pub fn is_anonymous_bound_name(name: String) -> bool { + (name.clone() == "_".to_string()) +} + +pub fn call_arg_label_matches_param(param_name: String, arg_label: String) -> bool { + (((param_name.clone() == arg_label.clone()) || (param_name.clone() == "_".to_string())) + || (((v1_rt::string_length(¶m_name) >= 1) + && (v1_rt::substring(¶m_name, 0, 1) == "_".to_string())) + && (v1_rt::substring(¶m_name, 1, v1_rt::string_length(¶m_name)) + == arg_label.clone()))) +} + +pub fn param_binds_positionally( + p: Rc, + source_indices: Rc>>, +) -> bool { + match p.children.clone().first().cloned() { + Some(type_expr) => { + (authored_name_at(source_indices.clone(), type_expr.clone()) + != authored_name_at(source_indices.clone(), p.clone())) + } + None => false, + } +} + +pub fn call_arg_bound_param_at_binding_key_note() -> String { + thread_local! { + static CACHED: String = { + "Runtime (v1_interpreter.rs call_function_inner) keys `bindings` differently per argument form: a NAMED actual is inserted under its own literal caller label (`bindings.insert(ctx.sym(name), ...)` — the raw label, never resolved through the underscore idiom to a declared name), while a POSITIONAL actual is inserted under the declared name it fills by running positional index (`bindings.insert(ctx.sym(¶m_names[positional_idx]), ...)`). Two named actuals therefore collide only when they carry the SAME literal label, and a positional-then-named collision (`one(1, a: 2)`) only when the named label equals the positional slot's declared name (found by review 48724). Resolving a named actual's key through declared_names via call_arg_label_matches_param (the prior form of this function) is a DIFFERENT and wrong key: filter-then-first picks whichever declared param the caller-label test hits first in declaration order, and an underscore-named param (`_: Edge`) matches ANY label unconditionally, so a later exact-named actual (`child:` against declared `child`) could be shadowed into colliding with an unrelated earlier underscore-idiom actual (`e:` against declared `_`) even though the runtime keys them apart as \"e\" and \"child\" — the false positive measured live at src/v2/std/cardinality.dag's termination_proof_fold_step(acc:, e:, child:) call against fn termination_proof_fold_step(acc, _: Edge, child), which compiled clean before this correction and fails at this wall after it without the fix.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CallArgBoundParamAccum { + pub bound: Option, + pub pos: i64, +} + +pub fn call_arg_bound_param_at( + idx: i64, + typed_args: Rc>>, + source_indices: Rc>>, + positionally_eligible_names: Rc>, +) -> Option { + Rc::new( + typed_args + .clone() + .iter() + .cloned() + .take((idx.clone() + 1) as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + Rc::new(CallArgBoundParamAccum { + bound: None, + pos: 0, + }), + |acc: Rc, ta: Rc| match arg_name_at( + ta.clone(), + source_indices.clone(), + ) { + Some(label) => Rc::new(CallArgBoundParamAccum { + bound: Some(label.clone()), + pos: acc.pos.clone(), + }), + None => Rc::new(CallArgBoundParamAccum { + bound: positionally_eligible_names + .clone() + .iter() + .cloned() + .skip(acc.pos.clone() as usize) + .next(), + pos: (acc.pos.clone() + 1), + }), + }, + ) + .bound + .clone() +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CallShapeArityScan { + pub positional_slot: i64, + pub required_count: i64, + pub supplied_count: i64, + pub deficit_param: Option>, +} + +pub fn scan_call_shape_arity( + sig_params: Rc>>, + typed_args: Rc>>, + positional_args: Rc>>, + source_indices: Rc>>, +) -> Rc { + sig_params.clone().iter().cloned().fold( + Rc::new(CallShapeArityScan { + positional_slot: 0, + required_count: 0, + supplied_count: 0, + deficit_param: None, + }), + |st: Rc, param: Rc| { + if (st.deficit_param.clone() != None) { + st.clone() + } else { + if param_is_generic_decl(param.clone(), source_indices.clone()) { + st.clone() + } else { + if (param_node_default_value(param.clone()) != None) { + st.clone() + } else { + { + let param_name = + authored_name_at(source_indices.clone(), param.clone()); + let named_supplied = { + let mut __found = false; + for ta in typed_args.clone().iter().cloned() { + if match arg_name_at(ta.clone(), source_indices.clone()) { + Some(label) => call_arg_label_matches_param( + param_name.clone(), + label.clone(), + ), + None => false, + } { + __found = true; + break; + } + } + __found + }; + let next_required = (st.required_count.clone() + 1); + if named_supplied.clone() { + Rc::new(CallShapeArityScan { + positional_slot: st.positional_slot.clone(), + required_count: next_required.clone(), + supplied_count: (st.supplied_count.clone() + 1), + deficit_param: None, + }) + } else { + if param_binds_positionally(param.clone(), source_indices.clone()) { + if (st.positional_slot.clone() + < (positional_args.clone().len() as i64)) + { + Rc::new(CallShapeArityScan { + positional_slot: (st.positional_slot.clone() + 1), + required_count: next_required.clone(), + supplied_count: (st.supplied_count.clone() + 1), + deficit_param: None, + }) + } else { + Rc::new(CallShapeArityScan { + positional_slot: st.positional_slot.clone(), + required_count: next_required.clone(), + supplied_count: st.supplied_count.clone(), + deficit_param: Some(param.clone()), + }) + } + } else { + Rc::new(CallShapeArityScan { + positional_slot: st.positional_slot.clone(), + required_count: next_required.clone(), + supplied_count: st.supplied_count.clone(), + deficit_param: Some(param.clone()), + }) + } + } + } + } + } + } + }, + ) +} + +pub fn direct_call_shape_diags( + func_name: String, + sig_params: Rc>>, + typed_args: Rc>>, + type_env: Rc, + module_name: String, + call_span: Rc, +) -> Rc>> { + { + let source_indices = type_env.source_indices.clone(); + let declared_names = Rc::new({ + let mut __result = Vec::new(); + for p in sig_params.clone().iter().cloned() { + __result.push(authored_name_at(source_indices.clone(), p.clone())); + } + __result + }); + let positionally_eligible_names = Rc::new({ + let mut __result = Vec::new(); + for p in Rc::new({ + let mut __result = Vec::new(); + for p in sig_params.clone().iter().cloned() { + if param_binds_positionally(p.clone(), source_indices.clone()) { + __result.push(p); + } + } + __result + }) + .iter() + .cloned() + { + __result.push(authored_name_at(source_indices.clone(), p.clone())); + } + __result + }); + let unknown_label_diags = Rc::new({ + let mut __result = Vec::new(); + for ta in typed_args.clone().iter().cloned() { + __result.extend( + (*match arg_name_at(ta.clone(), source_indices.clone()) { + Some(label) => { + if { + let mut __found = false; + for pn in declared_names.clone().iter().cloned() { + if call_arg_label_matches_param(pn.clone(), label.clone()) { + __found = true; + break; + } + } + __found + } { + Rc::new(vec![]) + } else { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::CallArgumentNameUnknown { + callee: func_name.clone(), + argument: label.clone(), + declared: declared_names.clone(), + span: ta.span.clone(), + }), + module_name.clone(), + )]) + } + } + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let positional_capacity = (Rc::new({ + let mut __result = Vec::new(); + for p in sig_params.clone().iter().cloned() { + if param_binds_positionally(p.clone(), source_indices.clone()) { + __result.push(p); + } + } + __result + }) + .len() as i64); + let positional_args = Rc::new({ + let mut __result = Vec::new(); + for ta in typed_args.clone().iter().cloned() { + if (arg_name_at(ta.clone(), source_indices.clone()) == None) { + __result.push(ta); + } + } + __result + }); + let surplus_diags = + if ((positional_args.clone().len() as i64) > positional_capacity.clone()) { + match positional_args + .clone() + .iter() + .cloned() + .skip(positional_capacity.clone() as usize) + .next() + { + Some(overflow) => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::CallPositionalSurplus { + callee: func_name.clone(), + supplied: (positional_args.clone().len() as i64), + capacity: positional_capacity.clone(), + span: overflow.span.clone(), + }), + module_name.clone(), + )]), + None => Rc::new(vec![]), + } + } else { + Rc::new(vec![]) + }; + let duplicate_label_diags = Rc::new({ + let mut __result = Vec::new(); + for pair in Rc::new( + typed_args + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.extend( + (*{ + let current_bound = call_arg_bound_param_at( + pair.0.clone(), + typed_args.clone(), + source_indices.clone(), + positionally_eligible_names.clone(), + ); + match current_bound.clone() { + Some(bound_name) => { + let earlier_dup = { + let mut __found = false; + for other in Rc::new( + typed_args + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + if ((other.0.clone() < pair.0.clone()) + && (call_arg_bound_param_at( + other.0.clone(), + typed_args.clone(), + source_indices.clone(), + positionally_eligible_names.clone(), + ) + .as_deref() + == current_bound.clone().as_deref())) + { + __found = true; + break; + } + } + __found + }; + if (earlier_dup.clone() + && !is_anonymous_bound_name(bound_name.clone())) + { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::CallArgumentDuplicate { + callee: func_name.clone(), + argument: bound_name.clone(), + span: pair.1.clone().span.clone(), + }), + module_name.clone(), + )]) + } else { + Rc::new(vec![]) + } + } + None => Rc::new(vec![]), + } + }) + .iter() + .cloned(), + ); + } + __result + }); + let arity_scan = scan_call_shape_arity( + sig_params.clone(), + typed_args.clone(), + positional_args.clone(), + source_indices.clone(), + ); + let deficit_diags = match arity_scan.deficit_param.clone() { + Some(missing_param) => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::CallPositionalDeficit { + callee: func_name.clone(), + parameter: authored_name_at(source_indices.clone(), missing_param.clone()), + supplied: arity_scan.supplied_count.clone(), + required: arity_scan.required_count.clone(), + span: call_span.clone(), + }), + module_name.clone(), + )]), + None => Rc::new(vec![]), + }; + v1_rt::concat( + v1_rt::concat(unknown_label_diags.clone(), surplus_diags.clone()), + v1_rt::concat(duplicate_label_diags.clone(), deficit_diags.clone()), + ) + } +} + +pub fn function_value_call_named_arg_diags( + func_name: String, + typed_args: Rc>>, + type_env: Rc, + module_name: String, + body_locals: Rc>, + locals: Rc>>, +) -> Rc>> { + match v1_rt::map_get(&body_locals, func_name.clone()) { + None => Rc::new(vec![]), + Some(_) => { + let named_diags = Rc::new({ + let mut __result = Vec::new(); + for ta in typed_args.clone().iter().cloned() { + __result.extend( + (*match arg_name_at(ta.clone(), type_env.source_indices.clone()) { + Some(label) => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::CallNamedArgOnFunctionValue { + callee: func_name.clone(), + argument: label.clone(), + span: ta.span.clone(), + }), + module_name.clone(), + )]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let arity_diags = match v1_rt::map_get(&locals, func_name.clone()) { + Some(binding) => { + let param_count = (binding.resolved.clone().params.clone().len() as i64); + if (param_count.clone() > 0) { + { + let supplied = (typed_args.clone().len() as i64); + if (supplied.clone() > param_count.clone()) { + match typed_args + .clone() + .iter() + .cloned() + .skip(param_count.clone() as usize) + .next() + { + Some(overflow) => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::CallPositionalSurplus { + callee: func_name.clone(), + supplied: supplied.clone(), + capacity: param_count.clone(), + span: overflow.span.clone(), + }), + module_name.clone(), + )]), + None => Rc::new(vec![]), + } + } else { + Rc::new(vec![]) + } + } + } else { + Rc::new(vec![]) + } + } + None => Rc::new(vec![]), + }; + v1_rt::concat(named_diags.clone(), arity_diags.clone()) + } + } +} + +pub fn function_value_named_application_wall_note() -> String { + thread_local! { + static CACHED: String = { + "WALL (DESIGN §5) — RUNG (§4b): mitigatable minimum for the class named actuals on function-value application. Reason: coverage path (5) — record-field fn value invoked as cfg.callback(a:) via ExprMethodCall — is compile-clean Accepted today and bypasses both this wall and #7519; executing probe function_value_field_method_known_hole_probe (ct_function_value_field_method_known_hole_probe_test) pins that hole and flips to a permanent regression control when the method-call label wall lands. The direct-call label wall (direct_call_shape_wall_note, gunbc#7519) runs only when a module fn sig resolves at the ExprCall seam. Function-value calls route through body_locals shadowing (call_locals_shadow_note): a let-bound or parameter callee skips sig lookup, so named actuals were silently accepted while the emitter's order_typed_call_args cannot reorder them (lookup_func_sig_in_scope returns Absent) and labels are not validated against any declared parameter authority. This wall refuses every named actual when the callee is a body-scope binding — the function-value path — until declaration-identity join can validate labels against the underlying fn. Positional calls on function values stay allowed. Named actuals on direct module/builtin calls (sig resolved) remain on the sibling wall. COVERAGE ACROSS CALLEE PATHS (§4b rung honesty — class rung is the minimum in-scope path, specimens measured by execution): (1) ExprCall bare name in body_locals (fn param, let, match binder, lambda param) — THIS WALL; structurally guaranteed for named actuals on that path. (2) ExprCall bare name with module fn sig resolved — sibling direct_call_shape_wall_note (#7519). (3) Module-level data binding with typed fn value called by bare name (data cb: fn(...) = ...) — NOT body_locals; routes #7519 when lookup resolves (specimen: CallArgumentNameUnknown on cb(a:, b:)). (4) Generic HO param where the arrow is a type variable (agree: F) — body_locals; same wall as (1). (5) Record field holding fn value invoked as cfg.callback(a:) — UNCOVERED HOLE: parser make_call_expr maps ExprFieldAccess callee to ExprMethodCall, not ExprCall; neither this wall nor #7519 runs; specimen compiles clean with named actuals; executing probe function_value_field_method_known_hole_probe. Dissolve-on: method-call / ExprMethodCall argument-label wall (direct_call_shape_wall_note unwalled class (3)). (6) Immediate apply f()(a:) on a call result — syntax parses (make_call_expr default → ExprCall name \"\"); NOT body_locals, sig does not resolve; neither wall fires on named args; specimen fails InternalError before Accepted (non-identifier ExprCall callee not modeled) — unwritable as Accepted today, not a live compile-clean named-arg hole.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn direct_call_shape_wall_note() -> String { + thread_local! { + static CACHED: String = { + "WALL (DESIGN §5) — the compile seam now refuses the four direct-call shape states the interpreter refuses at runtime, so the two authorities agree instead of one refusing and the other absorbing. The runtime authority is v1_interpreter.rs call_function_inner: a caller label naming no declared parameter raises CallContractMismatch (accepting label x against a declared x, _x, or _ — the deliberately-unused-parameter idiom, mirrored here in call_arg_label_matches_param); a positional argument beyond the positional parameter list raises CallContractMismatch too; a required parameter omitted without a declared default raises CallContractMismatch too (param_node_default_value legitimately fills omissions that carry a default — only non-default params count as required); and a second actual binding under one already-bound parameter key raises CallContractMismatch too ('argument supplied more than once'). Before this wall the compile seam was SILENT on all four, and the divergence was three-way on the first two (measured live, 2026-07-31, the probe-2 receipt in the guarantee-lane census): `sub(a: 10, bb: 3)` against `fn sub(a: Int, b: Int)` compiled with zero diagnostics, the interpreter refused it loudly, and the Rust emitter silently REORDERED it positionally — order_typed_call_args's name-match-else-positional arm bound bb's value to b, so the emitted realization computed an answer the interpreter refuses: two realizations of one program disagreeing silently, the exact state the guarantee ladder calls silent wrongness. The mechanism of the compile silence was the same absorbing fallback one seam over: direct_call_arg_mismatch_diags walks PARAMS and falls back positionally (`typed_args |> skip(pair.first) |> first`) when no arg carries the param's name, so a mislabeled arg is absorbed into a position and only its TYPE is ever judged — the label itself was never a checked fact. This wall checks application shape at the direct-call seam via direct_call_shape_diags: every labeled actual must name a declared parameter (modulo the underscore idiom); unlabeled actuals must fit within the positional capacity; every required parameter (no default) must be supplied by name or positional slot — scan_call_shape_arity mirrors call_function_inner's binding walk, including the same positional-capacity predicate (a param binds positionally iff its type-expr child's authored name differs from its own); and no two actuals may resolve to the same declared parameter — call_arg_bound_param_at (binding-key discipline documented at call_arg_bound_param_at_binding_key_note) resolves each actual, named or positional, to the parameter it fills, mirroring exactly how call_function_inner keys `bindings`. WHY THIS CHECK IS NOT UNDER module_skips_direct_call_arg_check: that exemption exists for the TYPE judgment, whose false-positive classes are representation gaps (brand aliases, optionality's two forms, anonymous literals, expansion depth — the conformance wall's four measured classes). A LABEL has no representation: it is a surface string matched against a declared surface string, the same exact-membership judgment the interpreter performs, so the exemption's reason does not reach it and the wall runs over every module including the compiler's own sources. All four diagnostics BLOCK (CallArgumentNameUnknown, CallPositionalSurplus, CallPositionalDeficit, CallArgumentDuplicate — is_error_diagnostic and is_interpreter_blocking_diagnostic default arms), so a refused program never reaches emit — which retires the emission path's silent reorder for Accepted programs at this seam without touching order_typed_call_args: its positional arm remains the legitimate binding rule for unlabeled args, and the states it could absorb are no longer writable in an Accepted program. DELIBERATELY NOT WALLED, with its trigger: method/pipe-seam argument labels — this wall covers the direct-call seam (the sig != none branch); the method-call path binds its arguments through its own inference arms and is the method wall's territory. The subject grain of the climb, stated per the ladder's rung-honesty rule: the classes 'unknown argument label', 'positional surplus', 'missing required argument', and 'a caller label or slot is bound more than once' each move from mitigatable (runtime refusal on the interpretation path; silent wrong output or deferred NoSuchVariable on the emission path) to structurally guaranteed at the direct-call seam — no Accepted program contains one — while the method-pipe path stays at its measured rung, named here rather than implied climbed. DEFICIT REQUIRED-GRAIN RULING (measured 2026-08-05, option b): the only writable shape where scan_call_shape_arity's required set (skip param_is_generic_decl, else require when not positionally supplied) diverges from call_function_inner's is_value_param (`type_expr authored name != param name`) is a param spelled `x: x<...>` — the param name equals the applied-type constructor with a non-leaf type-expr — corpus census `grep -rPno '\\b([a-z_][a-z0-9_]*): \\1<'` over dag/ src/v1/ src/v2/: 0 sites; params with no type-expr child are unwritable from authored surface. This seam refuses that shape as CallPositionalDeficit; the interpreter does not — compile is authoritative here because a non-positional param with no default and no supplied binding cannot be bound; matching the looser runtime predicate would copy an interpreter deficit for symmetry, not prevent silent wrongness. THE CENSUS RECEIPT, run before landing rather than promised after (2026-07-31): the label/surplus wall refused 28 live sites across the [src/v1, dag] regen closure and the dag + src/v2 compile-clean closure, and every one was the same defect — a parameter renamed at its declaration while call sites kept the old label, absorbed positionally ever since: to_string(i:) against the renamed value (8 sites, src/v1/compile.dag), arm_body(arm:) against n, is_import_slot_node(p:) against n, fold_list(init:) against this corpus's declared empty (17 sites, one file), and floor_discovery_walk_failure_refusal_reason(path:) against path_opt. All were relabeled to the declared authority in the same change. The fold_list rows carry the sharpest lesson about WHY compile must hold this fact even where runtime does not: those 17 sites never failed live because the interpreter grounds fold_list natively (label-blind), while call_function_inner would refuse the same label on the user-fn path — so the program's meaning depended on WHICH dispatch tier happened to serve the call, and the label's truth was untested precisely where it was wrong. The wall pins the label to the one declared authority regardless of tier, which is what keeps the call sites correct when the native grounding dissolves into the declared surface (the primitive-realization-single-authority trigger). MEASURED BLIND SPOT, stated rather than implied covered: 3 more to_string(i:) sites in src/v1/dag_collect.dag never reached the wall because their callee resolves NO sig at this seam (no import, global-bare miss) — the sig == none fallthrough routes to the method bridge and this wall never sees the call. They were found by grep on the fossil's shape and fixed with the rest, but the CLASS stays open: a call whose callee sig does not resolve is judged by nothing here, and that fallthrough closes with resolution coverage (the namespace lane), not with a wider label check. (Corrected 2026-08-05: the duplicate-label class LANDED in the order this note originally specified — v1_interpreter.rs call_function_inner now refuses a second binding under one caller label (CallContractMismatch, 'argument supplied more than once') before this seam was given its mirror, CallArgumentDuplicate. The class 'a caller label is supplied more than once' therefore climbs from mitigatable (silent last-write-wins) to structurally guaranteed at the direct-call seam, alongside the other three; a whole-tree census at landing found zero live duplicate-label call sites, so the wall adds no new refusal to any existing corpus form.) (Corrected 2026-08-05, cursor review 48724: an interim version of the duplicate-label mirror keyed CallArgumentDuplicate on exact caller-label string equality, which overclaimed. The runtime authority (call_function_inner) keys `bindings` by resolved PARAMETER symbol, not by caller-label string, and populates that key from a positional bind exactly as it does from a named one — so a positional bind of the sole parameter followed by a same-parameter named actual (`one(1, a: 2)` against `fn one(a: Int)`) collides and refuses at runtime, a state the label-string-only compile check could not see (`Absent => false` for positional predecessors) and so compiled clean, reaching emit. CallArgumentDuplicate is now keyed the same way the runtime is: call_arg_bound_param_at resolves each actual — named or positional — to the declared parameter it fills (positional actuals against the interpreter's own filtered param_binds_positionally list, in running positional order; named actuals through call_arg_label_matches_param, the same underscore-idiom equality unknown-label matching already uses) and the wall refuses a second actual resolving to the same parameter, never comparing raw caller-label strings against each other. The measured false-negative this closes and its discriminating fixture: call_duplicate_mixed_red_source, a single-parameter positional-then-named collision that a label-string-only check could not distinguish from the corpus's positional-only and named-only green controls.) (Corrected 2026-08-05, live cardinality.dag false positive: the prior correction's 'resolves a NAMED actual through call_arg_label_matches_param to a declared parameter' also overclaimed. The runtime keys a named actual under its own LITERAL caller label, never resolved through the underscore idiom to a declared name; only a positional actual is keyed by resolved declared name. Resolving named actuals through declared_names let an underscore-named param (matching ANY label unconditionally) shadow an unrelated later exact-named actual into a false collision — measured live at termination_proof_fold_step(acc: acc, e: e, child: child) against fn termination_proof_fold_step(acc, _: Edge, child), which this wall wrongly refused on 'child' until call_arg_bound_param_at's named branch was corrected to bind directly to the caller's literal label.) (Corrected 2026-08-05, #7848 merge: this note previously described only the label/surplus/deficit trio or only the duplicate-label mirror depending on branch; merging the two PRs' parallel work on this same wall found no consistency defect between the two additions — both diagnostics BLOCK, both use the same declared-parameter binding discipline as their keying authority, and both honor the underscore idiom identically, so the merge is a union of coverage, not a reconciliation of conflicting semantics.) (Corrected 2026-08-05, review from parent session loyal-ant-382: the duplicate-binding key, as landed, keyed EVERY anonymous ('_') parameter under the same literal string regardless of position, so a signature with two or more anonymous parameters bound positionally (or a mix of positional and record-field/method-value invocation of the same signature) false-refused CallArgumentDuplicate on its second anonymous actual — a live specimen, provider_readiness_independence_claim in dag/gunbc/provider_readiness_claim_evidence.dag, carries exactly this shape. The class 'a caller label or slot is bound more than once' does NOT climb to structurally guaranteed for anonymous parameters and never claimed to on a correct reading — 'more than once' presupposes the binding is READ twice, and an anonymous parameter's body cannot read it at all, so two anonymous parameters filled at two positions are two distinct, unreadable slots, not one key bound twice. call_arg_bound_param_at's duplicate check (this file) now excludes a resolved binding of exactly '_' from the collision check via the top-level `is_anonymous_bound_name` function (the earlier-duplicate scan still runs unconditionally; its result is combined with `!is_anonymous_bound_name(name: bound_name)` in the final `if`) — an anonymous parameter can never collide with another anonymous parameter under this authority, named or positional. `is_anonymous_bound_name` is a top-level function rather than an inline comparison for the same reason `call_arg_label_matches_param` already is one in this file: 'what counts as anonymous' is a single fact the whole module should ask one authority for, not a `== '_'` literal repeated ad hoc at each call site that cares — the existing pattern, not a new one. The runtime mirror (v1_interpreter.rs call_function_inner) excludes '_' from its collision check the same way, but — unlike an outright exclusion from binding — still INSERTS the value under the '_' key on every anonymous bind: the insert is what the required-argument check (`param_supplied_at_call`, reading `bindings.contains_key`) depends on to see an anonymous parameter as filled, so removing the insert entirely (the fix's first, corrected draft) turned every anonymous-but-positionally-supplied parameter into a false CallPositionalDeficit/'missing required argument' one layer downstream of the duplicate check it was fixing. Harmless repeated overwrite under one dead key, never read by the body, is the correct shape here — not 'never bound' literally, but 'never checked for collision, and immaterial which write wins.' The two required regression fixtures: a call binding two-or-more anonymous parameters positionally (direct and via a stored function value) stays ACCEPTED; the existing named/mixed duplicate fixtures (call_duplicate_mixed_red_source, the cardinality.dag underscore-shadow control) stay RED, because those collide on a NAMED, readable label, not an anonymous one.)".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn direct_call_arg_mismatch_diags( + plan: Rc>>, + type_env: Rc, + module_name: String, +) -> Rc>> { + { + let source_indices = type_env.source_indices.clone(); + Rc::new({ + let mut __result = Vec::new(); + for app in plan.clone().iter().cloned() { + __result.extend( + (*{ + let formal = app.formal.clone(); + match app.matched_arg.clone() { + Some(ta) => { + let actual_expr = arg_value(ta.clone()); + if match (*actual_expr.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => true, + _ => false, + } { + Rc::new(vec![]) + } else { + { + let actual_raw = resolved_type(actual_expr.clone()); + let actual = peel_nominal_alias_identity( + actual_raw.clone(), + type_env.clone(), + module_name.clone(), + ); + if direct_call_arg_type_mismatch( + formal.clone(), + actual.clone(), + type_env.clone(), + module_name.clone(), + source_indices.clone(), + ) { + Rc::new(vec![type_mismatch_error( + node_type_shape( + formal.clone(), + source_indices.clone(), + ), + node_type_shape( + actual.clone(), + source_indices.clone(), + ), + actual_expr.span.clone(), + module_name.clone(), + )]) + } else { + Rc::new(vec![]) + } + } + } + } + None => Rc::new(vec![]), + } + }) + .iter() + .cloned(), + ); + } + __result + }) + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Tier2bBt { + pub bt: Rc, + pub kernel_diags: Rc>>, +} + +pub fn infer_tier2b_builtin_with_kernel_diags( + func_name: String, + typed_args: Rc>>, + scope: Rc, + span: Rc, +) -> Rc { + if ((func_name.clone() == "lookup".to_string()) || (func_name.clone() == "map_get".to_string())) + { + Rc::new(Tier2bBt { + bt: match typed_args.clone().first().cloned() { + Some(receiver_arg) => match arg_value(receiver_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: receiver_type, + .. + }) => { + match map_value_type_in_env(receiver_type.clone(), scope.type_env.clone()) { + Some(value_type) => with_optional_cardinality(value_type.clone()), + None => resolve_builtin_call_type(func_name.clone()), + } + } + _ => resolve_builtin_call_type(func_name.clone()), + }, + None => resolve_builtin_call_type(func_name.clone()), + }, + kernel_diags: Rc::new(vec![]), + }) + } else { + if ((func_name.clone() == "map_keys".to_string()) + || (func_name.clone() == "sorted_map_keys".to_string())) + { + match typed_args.clone().first().cloned() { + Some(receiver_arg) => match arg_value(receiver_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: receiver_type, + .. + }) => { + match map_key_type_in_env(receiver_type.clone(), scope.type_env.clone()) { + Some(key_type) => { + let lk = list_kernel_ty_from_element(key_type.clone()); + Rc::new(Tier2bBt { + bt: lk.ty.clone(), + kernel_diags: lk.miss_diags.clone(), + }) + } + None => Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }), + } + } + _ => Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }), + }, + None => Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }), + } + } else { + if (func_name.clone() == "map_values".to_string()) { + match typed_args.clone().first().cloned() { + Some(receiver_arg) => match arg_value(receiver_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: receiver_type, + .. + }) => match map_value_type_in_env( + receiver_type.clone(), + scope.type_env.clone(), + ) { + Some(value_type) => { + let lv = list_kernel_ty_from_element(value_type.clone()); + Rc::new(Tier2bBt { + bt: lv.ty.clone(), + kernel_diags: lv.miss_diags.clone(), + }) + } + None => Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }), + }, + _ => Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }), + }, + None => Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }), + } + } else { + if (((func_name.clone() == "set_insert".to_string()) + || (func_name.clone() == "set_union".to_string())) + || (func_name.clone() == "set_contains".to_string())) + { + { + let operand_elem = if ((func_name.clone() == "set_insert".to_string()) + || (func_name.clone() == "set_contains".to_string())) + { + match typed_args.clone().iter().cloned().skip(1 as usize).next() { + Some(insert_arg) => match arg_value(insert_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { node: elem, .. }) => { + Some(elem.clone()) + } + _ => None, + }, + None => None, + } + } else { + match typed_args.clone().iter().cloned().skip(1 as usize).next() { + Some(other_arg) => match arg_value(other_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: other_type, .. + }) => match set_element_type_in_env( + other_type.clone(), + scope.type_env.clone(), + ) { + Some(elem_slot) => Some(child_type_node(elem_slot.clone())), + None => None, + }, + _ => None, + }, + None => None, + } + }; + let recv_is_set = match typed_args.clone().first().cloned() { + Some(receiver_arg) => { + set_builtin_receiver_is_set(receiver_arg.clone(), scope.clone()) + } + None => false, + }; + let union_other_bad = if (func_name.clone() == "set_union".to_string()) { + match typed_args.clone().iter().cloned().skip(1 as usize).next() { + Some(other_arg) => set_union_other_operand_is_resolved_non_set( + other_arg.clone(), + scope.clone(), + ), + None => false, + } + } else { + false + }; + let recv_elem = match typed_args.clone().first().cloned() { + Some(receiver_arg) => match arg_value(receiver_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: receiver_type, + .. + }) => set_element_type_from_receiver( + receiver_type.clone(), + scope.clone(), + ), + _ => None, + }, + None => None, + }; + let elem_mismatch = match recv_elem.clone() { + Some(re) => match operand_elem.clone() { + Some(oe) => set_element_types_mismatch( + re.clone(), + oe.clone(), + scope.type_env.clone().source_indices.clone(), + ), + None => false, + }, + None => false, + }; + let wrong_receiver_diags = if recv_is_set.clone() { + Rc::new(vec![]) + } else { + Rc::new(vec![inference_error( + v1_rt::concat( + func_name.clone(), + " receiver must be a Set".to_string(), + ), + span.clone(), + scope.module_name.clone(), + )]) + }; + let wrong_union_other_diags = if union_other_bad.clone() { + Rc::new(vec![inference_error( + "set_union second operand must be a Set".to_string(), + span.clone(), + scope.module_name.clone(), + )]) + } else { + Rc::new(vec![]) + }; + let mismatch_diags = if elem_mismatch.clone() { + Rc::new(vec![inference_error( + v1_rt::concat( + func_name.clone(), + " incompatible set element types".to_string(), + ), + span.clone(), + scope.module_name.clone(), + )]) + } else { + Rc::new(vec![]) + }; + let result_bt = if (func_name.clone() == "set_contains".to_string()) { + if (recv_is_set.clone() && !elem_mismatch.clone()) { + bool_type() + } else { + resolve_builtin_call_type(func_name.clone()) + } + } else { + match typed_args.clone().first().cloned() { + Some(receiver_arg) => { + if ((recv_is_set.clone() && !elem_mismatch.clone()) + && !union_other_bad.clone()) + { + match arg_value(receiver_arg.clone()) + .inferred + .clone() + .as_deref() + .cloned() + { + Some(InferredNode::Resolved { + node: receiver_type, + .. + }) => match recv_elem.clone() { + Some(_) => receiver_type.clone(), + None => match operand_elem.clone() { + Some(element) => { + set_kernel_ty_from_element(element.clone()) + .ty + .clone() + } + None => { + resolve_builtin_call_type(func_name.clone()) + } + }, + }, + _ => resolve_builtin_call_type(func_name.clone()), + } + } else { + resolve_builtin_call_type(func_name.clone()) + } + } + None => resolve_builtin_call_type(func_name.clone()), + } + }; + let build_diags = if (func_name.clone() == "set_contains".to_string()) { + Rc::new(vec![]) + } else { + match operand_elem.clone() { + Some(element) => { + if ((recv_is_set.clone() && !elem_mismatch.clone()) + && !union_other_bad.clone()) + { + set_kernel_ty_from_element(element.clone()) + .miss_diags + .clone() + } else { + Rc::new(vec![]) + } + } + None => Rc::new(vec![]), + } + }; + Rc::new(Tier2bBt { + bt: result_bt.clone(), + kernel_diags: v1_rt::concat( + wrong_receiver_diags.clone(), + v1_rt::concat( + wrong_union_other_diags.clone(), + v1_rt::concat(mismatch_diags.clone(), build_diags.clone()), + ), + ), + }) + } + } else { + Rc::new(Tier2bBt { + bt: resolve_builtin_call_type(func_name.clone()), + kernel_diags: Rc::new(vec![]), + }) + } + } + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct MethodPipeFallback { + pub result_ty: Rc, + pub kernel_diags: Rc>>, +} + +pub fn method_existence_decision( + recv_rt: Rc, + method_name: String, + scope: Rc, + span: Rc, +) -> Rc { + { + let recv_shape = node_type_shape( + recv_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let recv_surface_established = (kernel_profile_lookup(authored_name_at( + scope.type_env.clone().source_indices.clone(), + recv_rt.clone(), + )) != None); + if recv_surface_established.clone() { + Rc::new(MethodPipeFallback { + result_ty: error_type(), + kernel_diags: Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::MethodNotFound { + method: method_name.clone(), + receiver_type: recv_shape.clone(), + span: span.clone(), + }), + scope.module_name.clone(), + )]), + }) + } else { + { + let peeled = peel_where_refinement_base(recv_rt.clone(), scope.type_env.clone()); + let peeled_lookup = lookup_structural_method( + peeled.clone(), + method_name.clone(), + scope.type_env.clone().source_indices.clone(), + ); + match peeled_lookup.resolution.clone() { + Some(mfr) => Rc::new(MethodPipeFallback { + result_ty: mfr.result_type.clone(), + kernel_diags: peeled_lookup.kernel_diagnostics.clone(), + }), + None => { + let peeled_shape = node_type_shape( + peeled.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let peeled_surface_established = (kernel_profile_lookup(authored_name_at( + scope.type_env.clone().source_indices.clone(), + peeled.clone(), + )) != None); + if peeled_surface_established.clone() { + Rc::new(MethodPipeFallback { + result_ty: error_type(), + kernel_diags: Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::MethodNotFound { + method: method_name.clone(), + receiver_type: peeled_shape.clone(), + span: span.clone(), + }), + scope.module_name.clone(), + )]), + }) + } else { + match unresolved_method_frontier_trigger( + scope.module_name.clone(), + method_name.clone(), + recv_shape.clone(), + ) { + Some(trigger) => { + if (authored_name_at( + scope.type_env.clone().source_indices.clone(), + recv_rt.clone(), + ) == "".to_string()) + { + Rc::new(MethodPipeFallback { + result_ty: error_type(), + kernel_diags: Rc::new(vec![make_error_node( + Rc::new( + CompilerDiagnostic::ReceiverTypeUnestablished { + method: method_name.clone(), + span: span.clone(), + }, + ), + scope.module_name.clone(), + )]), + }) + } else { + Rc::new(MethodPipeFallback { + result_ty: error_type(), + kernel_diags: Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::MethodExistenceFrontierAdmitted { + method: method_name.clone(), + receiver_type: recv_shape.clone(), + trigger: dissolution_description(trigger.clone()), + span: span.clone(), +}), scope.module_name.clone())]), +}) + } + } + None => Rc::new(MethodPipeFallback { + result_ty: error_type(), + kernel_diags: Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::MethodExistenceUndecided { + method: method_name.clone(), + receiver_type: recv_shape.clone(), + span: span.clone(), + }), + scope.module_name.clone(), + )]), + }), + } + } + } + } + } + } + } +} + +pub fn method_pipe_map_keys_values_fallback( + recv_rt: Rc, + method_name: String, + scope: Rc, + span: Rc, +) -> Rc { + if ((method_name.clone() == "map_keys".to_string()) + || (method_name.clone() == "sorted_map_keys".to_string())) + { + match map_key_type_in_env(recv_rt.clone(), scope.type_env.clone()) { + Some(key_type) => { + let lk = list_kernel_ty_from_element(key_type.clone()); + Rc::new(MethodPipeFallback { + result_ty: lk.ty.clone(), + kernel_diags: lk.miss_diags.clone(), + }) + } + None => method_existence_decision( + recv_rt.clone(), + method_name.clone(), + scope.clone(), + span.clone(), + ), + } + } else { + if (method_name.clone() == "map_values".to_string()) { + match map_value_type_in_env(recv_rt.clone(), scope.type_env.clone()) { + Some(value_type) => { + let lv = list_kernel_ty_from_element(value_type.clone()); + Rc::new(MethodPipeFallback { + result_ty: lv.ty.clone(), + kernel_diags: lv.miss_diags.clone(), + }) + } + None => method_existence_decision( + recv_rt.clone(), + method_name.clone(), + scope.clone(), + span.clone(), + ), + } + } else { + method_existence_decision( + recv_rt.clone(), + method_name.clone(), + scope.clone(), + span.clone(), + ) + } + } +} + +pub fn method_existence_wall_note() -> String { + thread_local! { + static CACHED: String = { + "WALL (DESIGN §5) — an unresolved method REFUSES; it never inherits the receiver type. The deleted else-arm returned recv_rt with an EMPTY diagnostic list, so an unknown method on List became another List: a success-shaped answer that survived a whole collection pipeline, stamped PlainMethodSemantics as if it had resolved. Nothing refused until InterpError::Unimplemented { what: \"method 'filter_map'\" } — whole-tree compile reported ZERO blocking errors while live dispatch returned HTTP 500 (#7479). THE DECIDABILITY PREDICATE IS THE LOAD-BEARING PART. It is PER-RECEIVER, not per-name: refuse exactly when kernel_profile_lookup returns a profile for the receiver canonical container kind, because tier0 (lookup_structural_method) has already consulted that profile algebra templates and missed — so reaching this arm with a kernel-profiled receiver PROVES the method is absent from that receiver complete declared surface. This is the same authority tier0 reads, not a second relation minted here (§3). A NAME-GRAIN PREDICATE WAS TRIED AND IS WRONG, and the receipt is worth keeping because it is subtle: gating on membership in a declared method-name roster admits any rostered name on ANY receiver, so List |> starts_with(..) and List |> to_upper() compiled clean while the diagnostic claimed the receiver was under-resolved — a fail-open with a message that also LIED about its cause, since Container(List,Primitive(Int)) is fully resolved (codex review 45327, confirmed by execution). Per-receiver closes both: those two now REFUSE. THE ONE MEASURED OBSTACLE TO PER-RECEIVER WAS A REAL §3 FORK, AND IT IS FIXED HERE RATHER THAN WORKED AROUND: free_monoid_scalar_templates omitted count while the interpreter dispatches it natively on strings (the length/count/size arm), so String |> count reached this arm and was admitted only by the fail-open — a hollow green. count is now declared on the String profile, matching the runtime, so it resolves at tier0 and never reaches here. WHAT STAYS UNDECIDED, and why refusing there would fabricate: a receiver with NO kernel profile has no complete declared surface to prove absence against. THE LARGEST MEASURED CLASS WAS NOT UNDECIDABLE AT ALL AND IS NOW DECIDED — a where-refinement alias arrived as Product(NonEmptyStr) only because resolve_method_receiver_type short-circuits on Conj and never peeled to the String base; peeling it (where_refinement_receiver_peel_note) moved 12 corpus sites out of this residue in both directions at once, resolving the correct .length() calls AND making a bogus method on a branded string a hard MethodNotFound. What remains genuinely has no surface: a lambda parameter whose type never propagates so the receiver has no authored name at all (the LexMatchThunk { apply: fn(s) } idiom in src/v2/compiler/01_tokenize.dag and the StoreObjectFold lambdas in extdeps/git/object_store.dag), a coproduct payload bound by pattern destructuring arriving typed Primitive(ok) (a correct labels |> list_push(label)), a bare type variable, and an Optional whose cardinality is dropped before lookup so the inner product is what arrives. Refusing those would red correct code, which is the mirror image of the fabricated success this wall deletes. A RECEIVER WITH NO AUTHORED NAME AT ALL is not weak evidence about the method — it is no evidence about anything, because the receiver's own type was never established upstream. That is a different judgment failure from 'this receiver has a surface and the method is not on it', so it carries its own diagnostic, ReceiverTypeUnestablished, whose message names that cause instead of implying the method is missing. THE DIAGNOSTIC NAMES THE CAUSE; THE ROSTER BOUNDS THE ADMISSION, and separating those two was a correction. The class was first admitted on the CAUSE alone — any anonymous receiver, non-blocking — on the reasoning that the wall cannot tell an existing method from a nonexistent one when the receiver has no type, so refusing would refuse both. That reasoning is sound about DECIDABILITY and wrong about ADMISSION: it made every future anonymous-receiver call green, including one whose method does not exist, so the exception was unbounded exactly where existence is unknown (codex review 45459). Counting a diagnostic does not stop invalid code reaching the live system. Admission is now gated on the same declared roster as every other unestablished shape, keyed (module, method, Primitive()), so the seven measured occurrences are admitted and a new one anywhere else REFUSES as MethodExistenceUndecided. That is a ratchet that can only shrink, and blocking a new instance of a known deficit is the factory model rather than an inconvenience. Everything that has a name but no surface stays in the same shape-keyed roster. MethodExistenceUndecided carries what is left as a typed, located, COUNTED non-blocking diagnostic (the is_error_diagnostic partition, UnlistedImportUse precedent) so the frequency stays observable and prioritizable rather than zeroed by construction — and it now means exactly ONE thing, receiver surface not established, rather than doubling as a name-grain escape. Both arms return error_type, never recv_rt, so one located refusal does not cascade downstream. AND THE WALL IS REACHED FROM EVERY ARM, WHICH IT WAS NOT AT FIRST: the decision lived inline in the final else of method_pipe_map_keys_values_fallback, so an unresolved map_keys, sorted_map_keys or map_values whose receiver is not a keyed collection took an EARLIER branch and returned recv_rt with an empty diagnostic list — the identical success-shaped fallback this wall exists to delete, preserved in the two special cases that ran before it (codex review 45430). A wall reachable only from the default arm is not a wall, and prose about the default arm cannot see the two arms in front of it. The decision is now method_existence_decision, held once and called from all three, with the control run against the prior binary rather than reasoned about: List |> map_keys and |> map_values compile with exit 0 on the pre-routing binary and produce two located MethodNotFound refusals on this one. Positive controls: map/filter/fold/flat_map resolve at tier0 and service ops at tier1, neither reaching this arm. THE UPSTREAM DEFECTS ARE NAMED BY THE MEASUREMENT, one fixed here and the rest left as promotion triggers that would each let the wall decide a further non-kernel receiver: (1) FIXED — a where-refinement alias resolving to a Product shape instead of peeling to its declared base before method lookup; (2) a lambda parameter receiver whose type never propagates from the declared fn type it is bound under; (3) a coproduct payload binding typed as the VARIANT name rather than the field type; (4) an optional receiver whose cardinality is dropped so the inner product reaches lookup in place of Optional own surface. Each is carried as a row in unresolved_method_frontier, keyed on the receiver shape that is the evidence for it, except (2) which is the ReceiverTypeUnestablished cause class above. THE INSTRUMENT WAS WRONG BEFORE THE WALL WAS, and that is the most transferable thing here: this wall was measured with `gunbc run --entry dag/tools/generated_artifact_gate.dag`, which reaches only that gate's import closure, and it reported CLEAN while twelve real sites sat outside it — they surfaced from CI instead. The whole-corpus instrument is `gunbc compile --source-root dag --source-root src/v2 --target dag`, the same compile-clean gate CI runs, and it resolves 1629 sources against 2740 indexed modules. A narrow instrument reporting clean is indistinguishable from a wall that works, which is the §5 specification-without-execution trap wearing the shape of a green run. A FOURTH SHAPE was then found and NOT fixed: a brand alias can also arrive as a plain qualified LEAF (Primitive(std.types.NonEmptyStr)) rather than the refinement Conj the peel walks. Three head-resolution strategies were implemented and measured against it — lookup_type_for on the node, lookup_type_by_name on the qualified name, and on its last segment — none recovered the refinement, so the machinery was DELETED rather than shipped unproven and the site is a declared row. Unproven machinery that decides nothing is worse than a declared row that admits what it cannot decide. Dissolve-on: primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete surface, the count-style forks are unwritable rather than hand-reconciled, and MethodExistenceUndecided is deleted.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn where_refinement_receiver_peel_note() -> String { + thread_local! { + static CACHED: String = { + "A where-refinement type is a Conj carrying its base as its single child and its predicates in type_annotation, and resolve_method_receiver_type SHORT-CIRCUITS on connective == Conj — it treats any product as already-structural and returns it untouched. So NonEmptyStr, declared `String where non_empty`, reached method lookup as Product(NonEmptyStr) and String's algebra profile was never consulted: `.length()` on a branded string had no surface to resolve against and no surface to prove absence against either, which put 12 correct corpus sites (8 in extdeps.filesystem.linux, 4 across gunbc.design) in the wall's undecided residue. This peel is the fix, and the FIRST version of it was a §3 violation that this note asserted its way past — worth recording, because the note is where the defect actually lived. It hand-rolled a second recursive walker over the Conj/annotation/single-child shape and then CLAIMED, in this sentence, that the refinement chain had one traversal authority and the peel was its second consumer. Both walkers independently encoded the shape test, the lookup_type_for base resolution and the recursion, so they could drift apart silently; the prose asserted the property instead of the code establishing it (codex review 45410). WHY THESE READ NODE STORAGE DIRECTLY, since it is asked and the answer is not a per-function one: they are 2 of the 589 direct Node-storage reads in this file (579 of them on origin/main), which is the v1 seed's pervasive and only idiom — the seed IS the traversal, the stage that walks the tree so that later stages need not. There is no canonical query or fold surface reachable from here: fold_node and node_query live in src/v2/std, no v1 seed module imports v2 at all, and v1 COMPILES v2, so routing v1 inference through v2's fold inverts the bootstrap rather than tidying it. DESIGN's fold_node line is scoped to the 7 v2 stages and is a DRY example within v2, not a rule binding the seed. So the disposition here is the SEED'S disposition, the same trigger the hand-Rust receipt carries — the v1 seed shrinks to zero at v2 self-host and these dissolve with it — and attaching a separate per-function trigger to 2 reads while 587 identical reads beside them carry none would be a fabricated bound, describing separable work that does not exist (codex review 45570). The repair is the extraction the claim described: where_refinement_chain is the one walk, it yields the refinement chain from the surface alias down to its ground base, and it has exactly two consumers — type_where_refinement_predicates_transitive flat_maps the immediate predicates over the chain, and peel_where_refinement_base takes its last link. The shape test itself is is_where_refinement_type, held once. Now there is one traversal authority, and it is one because the code says so. It runs only where the wall was already about to refuse or admit, so no previously-resolving call changes meaning; tier0 keeps first claim on the unpeeled receiver, which is what preserves a method declared on the brand itself. The consequence that matters is not that 12 sites went green — it is that they became DECIDABLE IN BOTH DIRECTIONS: once the peeled receiver is kernel-profiled, a method genuinely absent from String now refuses as MethodNotFound instead of resting in the frontier. Widening what the wall can decide is the only move that shrinks the frontier without either fabricating a success or fabricating a refusal.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UnresolvedMethodFrontierRow { + pub module_name: String, + pub method: String, + pub receiver_shape: String, + pub occurrences: i64, + pub cause: String, + pub dissolution: Rc, +} + +pub fn unresolved_method_frontier() -> Rc>> { + Rc::new(vec![Rc::new(UnresolvedMethodFrontierRow { + module_name: "v2.compiler.tokenize".to_string(), + method: "apply".to_string(), + occurrences: 7, + receiver_shape: "Primitive()".to_string(), + cause: "receiver is a lambda parameter whose type is never inferred, so it arrives with NO authored name at all. The call is a product FIELD holding a callable — the LexMatchThunk { apply: fn(s) } idiom — not a method at all.".to_string(), + dissolution: unbound_dissolution("lambda-parameter receiver typing, so the receiver resolves to its declared product and apply is found as a field".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "extdeps.git.object_store".to_string(), + method: "map".to_string(), + occurrences: 2, + receiver_shape: "Primitive()".to_string(), + cause: "receiver is `tree.entries` where `tree` is the parameter of a lambda stored in a StoreObjectFold record field, so the field's declared fn type never reaches the lambda's parameter and the projection off it has no established type.".to_string(), + dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "extdeps.git.object_store".to_string(), + method: "flat_map".to_string(), + occurrences: 1, + receiver_shape: "Primitive()".to_string(), + cause: "same StoreObjectFold lambda-parameter shape as the `map` row above; listed separately because the key names one method on one receiver shape, never a module-wide pass.".to_string(), + dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "extdeps.mercurial".to_string(), + method: "any".to_string(), + occurrences: 3, + receiver_shape: "Primitive()".to_string(), + cause: "receiver is an untyped parameter of a lambda stored in a fold record field, the same shape as the object_store rows.".to_string(), + dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "gunbc.scm_compatibility.mercurial".to_string(), + method: "map".to_string(), + occurrences: 3, + receiver_shape: "Primitive()".to_string(), + cause: "receiver is `missing_changesets`, an untyped parameter of the `partial:` lambda in a MercurialRepositoryCompletenessFold record field.".to_string(), + dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "extdeps.dns.domain_name".to_string(), + method: "list_push".to_string(), + occurrences: 1, + receiver_shape: "Primitive(ok)".to_string(), + cause: "receiver is a coproduct payload bound by pattern destructuring, which arrives typed as the VARIANT name rather than the field type.".to_string(), + dissolution: unbound_dissolution("coproduct payload binding typed as the field type, at which point the receiver is List and DECIDABLE".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "v1.compiler.trace".to_string(), + method: "map".to_string(), + occurrences: 1, + receiver_shape: "Product(SpanMapping)".to_string(), + cause: "receiver is an Optional produced by `|> last`, and the optional functor is being mapped over. It arrives as the INNER product because the optional cardinality is dropped before method lookup, so Optional's own surface is never consulted.".to_string(), + dissolution: unbound_dissolution("reconciling the two optionality representations (cardinality-marked node vs the nominal Optional coproduct) so an optional receiver keeps its optional surface at method lookup".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "gunbc.source_integration_landing_spine".to_string(), + method: "map".to_string(), + occurrences: 1, + receiver_shape: "Node(Optional)".to_string(), + cause: "same optional-functor class as the v1.compiler.trace row, in its OTHER surface form: here the Optional survives as a named node rather than collapsing to its inner product, and neither form carries a method surface. Two shapes for one concept is itself the defect the trigger names.".to_string(), + dissolution: unbound_dissolution("reconciling the two optionality representations so an optional receiver keeps its optional surface at method lookup".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "test.claim.sccache_local_content_verified_on_read".to_string(), + method: "contains".to_string(), + occurrences: 1, + receiver_shape: "Primitive(std.types.NonEmptyStr)".to_string(), + cause: "the brand-alias class in its LEAF form. The receiver is a coproduct variant payload whose declared type is NonEmptyStr, and it arrives not as the refinement Conj the peel walks but as a plain leaf carrying the QUALIFIED name std.types.NonEmptyStr — so there is no refinement chain to descend and no kernel profile under that name. Three head-resolution strategies were tried against this site and measured: resolving the leaf through lookup_type_for, through lookup_type_by_name on the qualified name, and on its last segment. NONE of them recovered the refinement, so the machinery was deleted rather than shipped unproven, and the site is declared here instead. Why the peel reaches the Conj form but not this one is not yet understood, and saying so is more useful than a fourth guess.".to_string(), + dissolution: unbound_dissolution("one representation for a brand alias at method lookup — the same reconciliation the conformance wall's class (2) names — so the leaf and Conj forms stop being two shapes for one concept".to_string()), +}), Rc::new(UnresolvedMethodFrontierRow { + module_name: "v2.std.compilers.target_model".to_string(), + method: "lookup".to_string(), + occurrences: 1, + receiver_shape: "Primitive(T)".to_string(), + cause: "receiver is a bare type variable. This one is genuinely undecidable at this seam rather than a resolution defect: nothing establishes what T offers.".to_string(), + dissolution: unbound_dissolution("primitive-realization-single-authority, giving every receiver a complete declared method surface".to_string()), +})]) +} + +pub fn frontier_diag_matches_row( + d: Rc, + method: String, + receiver_shape: String, +) -> bool { + match diagnostic_frontier_occurrence_key(d.clone()) { + Some(key) => { + ((key.method.clone() == method.clone()) + && (key.receiver_shape.clone() == receiver_shape.clone())) + } + None => false, + } +} + +pub fn frontier_row_observed( + diagnostics: Rc>>, + method: String, + receiver_shape: String, +) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for e in diagnostics.clone().iter().cloned() { + if frontier_diag_matches_row( + e.diagnostic.clone(), + method.clone(), + receiver_shape.clone(), + ) { + __result.push(e); + } + } + __result + }) +} + +pub fn frontier_row_budget_span( + observed: Rc>>, + module_span: Rc, +) -> Rc { + match observed.clone().first().cloned() { + Some(witness) => diagnostic_to_span(witness.diagnostic.clone()), + None => module_span, + } +} + +pub fn frontier_row_budget_diags( + row: Rc, + diagnostics: Rc>>, + module_name: String, + module_span: Rc, +) -> Rc>> { + if ((frontier_row_observed( + diagnostics.clone(), + row.method.clone(), + row.receiver_shape.clone(), + ) + .len() as i64) + == row.occurrences.clone()) + { + Rc::new(vec![]) + } else { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::FrontierOccurrenceBudgetExceeded { + method: row.method.clone(), + receiver_type: row.receiver_shape.clone(), + declared: row.occurrences.clone(), + observed: (frontier_row_observed( + diagnostics.clone(), + row.method.clone(), + row.receiver_shape.clone(), + ) + .len() as i64), + span: frontier_row_budget_span( + frontier_row_observed( + diagnostics.clone(), + row.method.clone(), + row.receiver_shape.clone(), + ), + module_span.clone(), + ), + }), + module_name.clone(), + )]) + } +} + +pub fn frontier_occurrence_budget_diags( + module_name: String, + module_span: Rc, + diagnostics: Rc>>, +) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for r in Rc::new({ + let mut __result = Vec::new(); + for r in unresolved_method_frontier().iter().cloned() { + if (r.module_name.clone() == module_name.clone()) { + __result.push(r); + } + } + __result + }) + .iter() + .cloned() + { + __result.extend( + (*frontier_row_budget_diags( + r.clone(), + diagnostics.clone(), + module_name.clone(), + module_span.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }) +} + +pub fn frontier_occurrence_budget_note() -> String { + thread_local! { + static CACHED: String = { + "THE COUNT IS WHAT MAKES THE FRONTIER A RATCHET INSTEAD OF AN EXEMPTION. Keying admission on (module, method, receiver_shape) bounds WHERE an unresolved call may live but not HOW MANY may live there, so a second call in the same module, on the same method, failing to resolve the same way, inherited the admission — and that is not hypothetical: the measured rows are not all singletons (v2.compiler.tokenize admits seven `apply` calls, extdeps.mercurial three `any`, gunbc.scm_compatibility.mercurial three `map`), so a row admitting seven would silently admit an eighth (codex review 45464). Each row therefore declares its MEASURED occurrence count and this fold refuses the excess, located on the first offending call. THE COMPARISON IS EQUALITY, AND IT WAS FIRST WRITTEN AS A CEILING, WHICH DID NOT RATCHET. `observed > declared` was justified here on the reasoning that a narrower compile closure sees fewer occurrences of a module's rows, so equality would red a partial build. That reasoning is WRONG about this check: it runs per MODULE, and every occurrence of a module's rows is present whenever that module is typechecked at all — a closure that omits the module never runs its rows, so there is no partial-visibility case to protect. What the ceiling actually did was let seven shrink to six while the declared seven stood, so a seventh call could return silently: a static limit, not a ratchet, and the note claimed the ratchet anyway (codex review 45491). Equality closes it in the only way that works — fixing a call reds until the declared count is lowered, which removes the headroom a reintroduction would have slipped into. Both directions are asserted in the witness, because the under-count half is the half that makes it a ratchet and it is the one an author is tempted to relax. WHY NOT A STABLE PER-OCCURRENCE KEY, which would close this exactly: std.occurrence_identity is the corpus authority for occurrence identity and its own scope law forbids filename, SourceSpan, authored name, structural Node equality and content hash as identity inputs, allocating OccurrenceId inside one graph-scoped allocator instead. An allocator-assigned integer cannot appear as a literal in a declared row, because it is not stable across compiles — so a per-occurrence key is not merely unimplemented here, it is unavailable from the authority that owns the concept. The count is the strongest bound the substrate currently supports. Dissolve-on: a content-addressed occurrence identity stable across edits (the namespace lane's containment addressing), at which point rows key on the occurrence itself and the count field deletes.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn frontier_occurrence_budget_checked( + module_name: String, + module_span: Rc, + diagnostics: Rc>>, +) -> Rc>> { + v1_rt::concat( + diagnostics.clone(), + frontier_occurrence_budget_diags( + module_name.clone(), + module_span.clone(), + diagnostics.clone(), + ), + ) +} + +pub fn unresolved_method_frontier_trigger( + module_name: String, + method: String, + receiver_shape: String, +) -> Option> { + match Rc::new({ + let mut __result = Vec::new(); + for r in unresolved_method_frontier().iter().cloned() { + if (((r.module_name.clone() == module_name.clone()) + && (r.method.clone() == method.clone())) + && (r.receiver_shape.clone() == receiver_shape.clone())) + { + __result.push(r); + } + } + __result + }) + .first() + .cloned() + { + Some(row) => Some(row.dissolution.clone()), + None => None, + } +} + +pub fn unresolved_method_frontier_note() -> String { + thread_local! { + static CACHED: String = { + "The declared frontier for method calls whose receiver establishes NO method surface even after where-refinement peeling (DESIGN §7: a declared row with a reason and a migration trigger, countable and prioritizable, never a silent escape hatch). WHY A ROSTER AT ALL: MethodExistenceUndecided BLOCKS. Leaving the undecided class non-blocking meant emittable_graph still emitted code containing a method whose existence was never established — the same fail-open the wall claims to close, correctly refused twice in review (codex reviews 45357 and 45383). Blocking it outright was not available either: the residue is CORRECT, WORKING code, seven sites of it the v2 tokenizer own LexMatchThunk { apply: fn(s) } idiom, so a blanket refusal would refuse the compiler v2 is migrating to — fabricating a refusal, which §5 forbids exactly as it forbids fabricating a success. THE KEY IS (module, method, receiver_shape), AND THE THIRD COMPONENT IS THE CORRECTION. A (module, method) key was shipped first and was wrong on two counts, one found by review and one by execution, which is worth recording because they are the same defect seen from two sides. Review found it as a fail-open: any NEW apply call in v2.compiler.tokenize would inherit the pass even on a fully resolved receiver, so the note claim that no new fail-open can enter was false (codex review 45398). Execution found it as an UNDERCOUNT: the roster was measured over the v1 self-compile closure alone, and the first whole-corpus run reded seven sites in three modules the roster had never seen. Both dissolve into the same fix — the frontier admits a receiver whose surface could not be established, so the SHAPE of that receiver is the evidence, and keying on it means a new call refuses unless it reproduces the exact unestablished shape the row was measured on. The residue after that is 13 sites in four shapes: Primitive() with no authored name (a lambda parameter whose type never propagates, 10 sites), Primitive(T) (a bare type variable), Primitive(ok) (a coproduct payload typed as its variant name), and a Product that is really an Optional whose cardinality was dropped. Every one is an upstream receiver-resolution defect, not a method-existence fact, which is exactly why the wall cannot decide them and why each row names the resolution fix rather than a permanent exemption. Admitted rows still emit MethodExistenceFrontierAdmitted, counted and carrying its own trigger, so the frequency stays observable rather than zeroed by construction (§5). THE RESIDUAL WIDENING, STATED RATHER THAN CLAIMED AWAY: a second unresolved call to the same method, in the same module, on a receiver that fails to resolve in the same way, is still admitted. That is narrower than the module-wide pass it replaces and it is not zero. Closing it entirely needs an occurrence identity stable across edits — content-addressed, not line-anchored — which is the same containment/content-hash authority the namespace lane is landing; until then the honest bound is this key, and the peel above is the mechanism that actually SHRINKS the frontier rather than administering it.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn categorized_error( + message: String, + span: Rc, + module_name: String, + category: String, +) -> Rc { + make_error_node( + Rc::new(CompilerDiagnostic::InternalError { + message: message.clone(), + span: span.clone(), + }), + module_name.clone(), + ) +} + +pub fn validate_cast( + source_inferred: Option>, + target_name: String, + span: Rc, + source_indices: Rc>>, + module_name: String, +) -> Option> { + match source_inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: src_node, .. }) => { + let source_name = authored_name_at(source_indices.clone(), src_node.clone()); + if (source_name.clone() == target_name.clone()) { + None + } else { + if !is_dag_cast_domain_type(source_name.clone()) { + None + } else { + if !is_dag_cast_domain_type(target_name.clone()) { + None + } else { + if dag_can_cast(source_name.clone(), target_name.clone()) { + None + } else { + { + let msg = v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + "invalid cast: ".to_string(), + source_name.clone(), + ), + " as ".to_string(), + ), + target_name.clone(), + ); + let diag = Rc::new(CompilerDiagnostic::InternalError { + message: msg.clone(), + span: span.clone(), + }); + Some(make_error_node(diag.clone(), module_name.clone())) + } + } + } + } + } + } + _ => None, + } +} + +pub fn optional_cast_diags( + source_inferred: Option>, + target_type: Rc, + span: Rc, + source_indices: Rc>>, + module_name: String, +) -> Rc>> { + match source_inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: src_node, .. }) => { + let source_name = authored_name_at(source_indices.clone(), src_node.clone()); + let source_is_optional = ((src_node.return_cardinality.clone() + == Cardinality::CardOptional) + || (qualified_last_segment(source_name.clone()) == "Optional".to_string())); + let target_is_optional = + (target_type.return_cardinality.clone() == Cardinality::CardOptional); + if (source_is_optional.clone() && !target_is_optional.clone()) { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::OptionalCastNotEliminated { + source_type: v1_rt::concat(source_name.clone(), "?".to_string()), + target_type: authored_name_at(source_indices.clone(), target_type.clone()), + span: span.clone(), + }), + module_name.clone(), + )]) + } else { + Rc::new(vec![]) + } + } + _ => Rc::new(vec![]), + } +} + +pub fn type_variable_node(id: String) -> Rc { + Rc::new(Node { + name: "".to_string(), + span: no_span(), + ident_span: None, + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: Some(Rc::new(InferredNode::TypeVariable { id: id.clone() })), + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }) +} + +pub fn is_type_variable(inferred: Rc) -> bool { + match (*inferred.clone()).clone() { + InferredNode::TypeVariable { id: _, .. } => true, + _ => false, + } +} + +pub fn inferred_or_error( + result: Option>, + fallback_message: String, + fallback_span: Rc, +) -> Rc { + match result.clone() { + Some(inferred) => inferred.clone(), + None => Rc::new(InferredNode::CompilerError { + message: fallback_message.clone(), + span: fallback_span.clone(), + }), + } +} + +pub fn resolve_pattern_subject( + scope: Rc, + scrutinee_subject: Rc, +) -> Rc { + match (*scrutinee_subject.clone()).clone() { + PatternSubject::PatternResolved { + node: scrutinee_type, + .. + } => pattern_subject_from_node(preserve_outer_optional_cardinality( + scrutinee_type.clone(), + resolve_scrutinee_type_node(scope.type_env.clone(), scrutinee_type.clone()), + )), + PatternSubject::PatternDynamic { + span: dynamic_span, .. + } => Rc::new(PatternSubject::PatternDynamic { + span: dynamic_span.clone(), + }), + PatternSubject::PatternLookupBlocked => Rc::new(PatternSubject::PatternLookupBlocked), + } +} + +pub fn annotate_pattern_parent_enums( + pattern: Rc, + scrutinee_subject: Rc, + scope: Rc, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*pattern.clone()).clone() { + MatchPattern::VariantPattern { + name: variant_name, + field_bindings: bindings, + .. + } => { + let resolved_scrut = + resolve_pattern_subject(scope.clone(), scrutinee_subject.clone()); + let inferred_parent = match (*resolved_scrut.clone()).clone() { + PatternSubject::PatternResolved { + node: resolved_scrut_node, + .. + } => { + let scrutinee_name = authored_name_at( + scope.type_env.clone().source_indices.clone(), + resolved_scrut_node.clone(), + ); + let optional_cardinality_subject = + ((resolved_scrut_node.return_cardinality.clone() + == Cardinality::CardOptional) + && (scrutinee_name.clone() != "Optional".to_string())); + let optional_coproduct_subject = ((scrutinee_name.clone() + == "Optional".to_string()) + && ((variant_name.clone() == "Present".to_string()) + || (variant_name.clone() == "Absent".to_string()))); + let witness_container_subject = + (is_witness_type_name(scrutinee_name.clone()) + && ((variant_name.clone() == "Holds".to_string()) + || (variant_name.clone() == "Violates".to_string()))); + if ((optional_cardinality_subject.clone() + || optional_coproduct_subject.clone()) + && ((variant_name.clone() == "Present".to_string()) + || (variant_name.clone() == "Absent".to_string()))) + { + Some("Optional".to_string()) + } else { + if witness_container_subject.clone() { + Some("Witness".to_string()) + } else { + { + let is_coproduct = (resolved_scrut_node.connective.clone() + == Connective::Disj); + if is_coproduct.clone() { + Some(scrutinee_name.clone()) + } else { + None + } + } + } + } + } + PatternSubject::PatternDynamic { span: _, .. } => None, + PatternSubject::PatternLookupBlocked => None, + }; + let annotated_variant_name = variant_name.clone(); + let variant_lookup = lookup_variant_in_type( + resolved_scrut.clone(), + variant_name.clone(), + scope.module_name.clone(), + scope.type_env.clone(), + (bindings.clone().len() as i64), + ); + let variant_subject = lookup_result_subject(variant_lookup.clone()); + let annotated_bindings = Rc::new({ + let mut __result = Vec::new(); + for binding in bindings.clone().iter().cloned() { + __result.push({ + let field_lookup = lookup_field_in_variant( + variant_subject.clone(), + field_binding_name_at( + binding.clone(), + scope.type_env.clone().source_indices.clone(), + ), + scope.module_name.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let field_subject = lookup_result_subject(field_lookup.clone()); + make_field_binding_node( + field_binding_name_at( + binding.clone(), + scope.type_env.clone().source_indices.clone(), + ), + annotate_pattern_parent_enums( + field_binding_pattern(binding.clone()), + field_subject.clone(), + scope.clone(), + ), + binding.span.clone(), + node_name_span(binding.clone()), + ) + }); + } + __result + }); + match inferred_parent.clone() { + Some(parent_name) => Rc::new(MatchPattern::VariantPattern { + name: annotated_variant_name.clone(), + parent_enum: Some(parent_name.clone()), + field_bindings: annotated_bindings.clone(), + }), + None => Rc::new(MatchPattern::VariantPattern { + name: variant_name.clone(), + parent_enum: None, + field_bindings: annotated_bindings.clone(), + }), + } + } + _ => pattern.clone(), + } + }) +} + +pub fn build_params_scope(scope: Rc, params: Rc>>) -> Rc { + { + let new_locals = params.clone().iter().cloned().fold( + scope.locals.clone(), + |acc: Rc>>, p: Rc| { + v1_rt::rc_map_insert( + acc, + param_node_name_at(p.clone(), scope.type_env.clone().source_indices.clone()), + Rc::new(TypeBinding { + name: param_node_name_at( + p.clone(), + scope.type_env.clone().source_indices.clone(), + ), + resolved: param_node_type_expr(p.clone()), + provenance: Rc::new(SubValueRelation::PreservedValue), + }), + ) + }, + ); + let new_body_locals = params.clone().iter().cloned().fold( + scope.body_locals.clone(), + |acc: Rc>, p: Rc| { + v1_rt::rc_map_insert( + acc, + param_node_name_at(p.clone(), scope.type_env.clone().source_indices.clone()), + true, + ) + }, + ); + Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: new_locals.clone(), + body_locals: new_body_locals.clone(), + match_bound_names: scope.match_bound_names.clone(), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: scope.caller_decl_name.clone(), + lambda_param_provenance: v1_rt::rc_empty_map::>(), + }) + } +} + +pub fn extend_scope( + scope: Rc, + name: String, + resolved: Rc, + provenance: Rc, +) -> Rc { + Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: v1_rt::rc_map_insert( + scope.locals.clone(), + name.clone(), + Rc::new(TypeBinding { + name: name.clone(), + resolved: resolved.clone(), + provenance: provenance.clone(), + }), + ), + body_locals: v1_rt::rc_map_insert(scope.body_locals.clone(), name.clone(), true), + match_bound_names: scope.match_bound_names.clone(), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: scope.caller_decl_name.clone(), + lambda_param_provenance: scope.lambda_param_provenance.clone(), + }) +} + +pub fn extend_scope_match_bound( + scope: Rc, + name: String, + resolved: Rc, + provenance: Rc, +) -> Rc { + Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: v1_rt::rc_map_insert( + scope.locals.clone(), + name.clone(), + Rc::new(TypeBinding { + name: name.clone(), + resolved: resolved.clone(), + provenance: provenance.clone(), + }), + ), + body_locals: v1_rt::rc_map_insert(scope.body_locals.clone(), name.clone(), true), + match_bound_names: v1_rt::rc_map_insert( + scope.match_bound_names.clone(), + name.clone(), + true, + ), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: scope.caller_decl_name.clone(), + lambda_param_provenance: scope.lambda_param_provenance.clone(), + }) +} + +pub fn extend_scope_with_params(scope: Rc, params: Rc>) -> Rc { + { + let new_locals = params.clone().iter().cloned().fold( + scope.locals.clone(), + |acc: Rc>>, p: String| { + v1_rt::rc_map_insert( + acc, + p.clone(), + Rc::new(TypeBinding { + name: p.clone(), + resolved: type_variable_node("lambda_param".to_string()), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + }, + ); + let new_body_locals = params.clone().iter().cloned().fold( + scope.body_locals.clone(), + |acc: Rc>, p: String| v1_rt::rc_map_insert(acc, p.clone(), true), + ); + Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: new_locals.clone(), + body_locals: new_body_locals.clone(), + match_bound_names: scope.match_bound_names.clone(), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: scope.caller_decl_name.clone(), + lambda_param_provenance: scope.lambda_param_provenance.clone(), + }) + } +} + +pub fn scope_after_stmt_node( + stmt: Rc, + stmt_type: Rc, + scope: Rc, +) -> Rc { + match (*stmt.expr_data.clone()).clone() { + ExprData::ExprLet => { + if ((stmt.children.clone().len() as i64) <= 1) { + { + let val = match stmt.children.clone().first().cloned() { + Some(v) => v.clone(), + None => stmt.clone(), + }; + extend_scope( + scope.clone(), + let_binding_name_at( + stmt.clone(), + scope.type_env.clone().source_indices.clone(), + ), + stmt_type.clone(), + classify_binding_provenance(val.clone(), scope.clone()), + ) + } + } else { + scope.clone() + } + } + _ => scope.clone(), + } +} + +pub fn derive_field_provenance( + scope: Rc, + scrutinee_provenance: Rc, + scrutinee_subject: Rc, + variant_name: String, + field_name: String, +) -> Rc { + match (*scrutinee_provenance.clone()).clone() { + SubValueRelation::SubValueUnknown => Rc::new(SubValueRelation::SubValueUnknown), + _ => { + let scrut_type_name = match (*scrutinee_subject.clone()).clone() { + PatternSubject::PatternResolved { node: n, .. } => authored_name_at( + scope.type_env.clone().source_indices.clone(), + resolved_type(n.clone()), + ), + _ => "".to_string(), + }; + if (scrut_type_name.clone() == "".to_string()) { + Rc::new(SubValueRelation::SubValueUnknown) + } else { + { + let ind_fields = + inductive_fields_for(scope.type_env.clone(), scrut_type_name.clone()); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in ind_fields.clone().iter().cloned() { + if ((f.variant_name.clone() == variant_name.clone()) + && (f.field_name.clone() == field_name.clone())) + { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => { + compose_sub_value(scrutinee_provenance.clone(), ind_field.clone()) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + } + } + } +} + +pub fn extend_scope_with_pattern_node( + scope: Rc, + pattern: Rc, + scrutinee_subject: Rc, + scrutinee_provenance: Rc, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*pattern.clone()).clone() { + MatchPattern::Bind { + declaration: declaration, + .. + } => Rc::new(PatternScopeResult { + scope: extend_scope_match_bound( + scope.clone(), + declaration.name.clone(), + pattern_binding_type(scrutinee_subject.clone()), + scrutinee_provenance.clone(), + ), + diagnostics: Rc::new(vec![]), + }), + MatchPattern::Wildcard => Rc::new(PatternScopeResult { + scope: scope.clone(), + diagnostics: Rc::new(vec![]), + }), + MatchPattern::LitPattern { value: _, .. } => Rc::new(PatternScopeResult { + scope: scope.clone(), + diagnostics: Rc::new(vec![]), + }), + MatchPattern::VariantPattern { + name: vname, + field_bindings: bindings, + .. + } => { + let resolved_scrut = + resolve_pattern_subject(scope.clone(), scrutinee_subject.clone()); + let variant_lookup = lookup_variant_in_type( + resolved_scrut.clone(), + vname.clone(), + scope.module_name.clone(), + scope.type_env.clone(), + (bindings.clone().len() as i64), + ); + let variant_subject = lookup_result_subject(variant_lookup.clone()); + let variant_diags = variant_lookup.diagnostics.clone(); + bindings.clone().iter().cloned().fold( + Rc::new(PatternScopeResult { + scope: scope.clone(), + diagnostics: variant_diags.clone(), + }), + |acc: Rc, fb: Rc| { + let field_name = field_binding_name_at( + fb.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let field_lookup = lookup_field_in_variant( + variant_subject.clone(), + field_name.clone(), + scope.module_name.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let field_subject = lookup_result_subject(field_lookup.clone()); + let field_type = pattern_binding_type(field_subject.clone()); + let field_provenance = derive_field_provenance( + scope.clone(), + scrutinee_provenance.clone(), + scrutinee_subject.clone(), + vname.clone(), + field_name.clone(), + ); + let fb_pattern = field_binding_pattern(fb.clone()); + match (*fb_pattern.clone()).clone() { + MatchPattern::Bind { + declaration: declaration, + .. + } => Rc::new(PatternScopeResult { + scope: extend_scope_match_bound( + acc.scope.clone(), + declaration.name.clone(), + field_type.clone(), + field_provenance.clone(), + ), + diagnostics: v1_rt::concat( + acc.diagnostics.clone(), + field_lookup.diagnostics.clone(), + ), + }), + _ => { + let nested = extend_scope_with_pattern_node( + acc.scope.clone(), + fb_pattern.clone(), + field_subject.clone(), + field_provenance.clone(), + ); + Rc::new(PatternScopeResult { + scope: nested.scope.clone(), + diagnostics: v1_rt::concat( + acc.diagnostics.clone(), + v1_rt::concat( + field_lookup.diagnostics.clone(), + nested.diagnostics.clone(), + ), + ), + }) + } + } + }, + ) + } + } + }) +} + +pub fn method_name_is(opt: Option, expected: String) -> bool { + if (opt.clone() == None) { + false + } else { + (opt.clone().unwrap() == expected.clone()) + } +} + +pub fn arg_has_name( + arg: Rc, + name: String, + source_indices: Rc>>, +) -> bool { + { + let n = arg_name_at(arg.clone(), source_indices.clone()); + if (n.clone() == None) { + false + } else { + (n.clone().unwrap() == name.clone()) + } + } +} + +pub fn extract_fold_init_info( + method_name: Option, + method_args: Rc>>, + min_args: i64, + scope: Rc, + expected: Option>, +) -> Option> { + { + let is_fold = method_name_is(method_name.clone(), "fold".to_string()); + if (is_fold.clone() && ((method_args.clone().len() as i64) >= min_args.clone())) { + { + let init_arg = match Rc::new({ + let mut __result = Vec::new(); + for a in method_args.clone().iter().cloned() { + if arg_has_name( + a.clone(), + "init".to_string(), + scope.type_env.clone().source_indices.clone(), + ) { + __result.push(a); + } + } + __result + }) + .first() + .cloned() + { + Some(a) => Some(a.clone()), + None => method_args.clone().first().cloned(), + }; + match init_arg.clone() { + Some(ia) => { + let init_result = + infer_expr(arg_value(ia.clone()), scope.clone(), expected.clone()); + Some(Rc::new(ArgInferResult { + typed_arg: make_arg_node( + arg_name_at( + ia.clone(), + scope.type_env.clone().source_indices.clone(), + ), + init_result.typed.clone(), + ia.span.clone(), + ia.span.clone(), + ), + diagnostics: init_result.diagnostics.clone(), + })) + } + None => None, + } + } + } else { + None + } + } +} + +pub fn derive_element_provenance( + coll_expr: Rc, + elem_type: Rc, + scope: Rc, +) -> Rc { + { + let coll_prov = classify_binding_provenance(coll_expr.clone(), scope.clone()); + match (*coll_prov.clone()).clone() { + SubValueRelation::SubValueUnknown => Rc::new(SubValueRelation::SubValueUnknown), + _ => { + if (authored_name_at( + scope.type_env.clone().source_indices.clone(), + elem_type.clone(), + ) == "".to_string()) + { + Rc::new(SubValueRelation::SubValueUnknown) + } else { + { + let ind_fields = inductive_fields_for( + scope.type_env.clone(), + authored_name_at( + scope.type_env.clone().source_indices.clone(), + elem_type.clone(), + ), + ); + let list_field = Rc::new({ + let mut __result = Vec::new(); + for f in ind_fields.clone().iter().cloned() { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, + } { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match list_field.clone() { + Some(f) => { + Rc::new(SubValueRelation::IteratedSubValue { field: f.clone() }) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + } + } + } + } +} + +pub fn infer_method_args_with_fold( + method_name: Option, + method_args: Rc>>, + fold_info: Option>, + fold_acc_type: Rc, + element_type: Rc, + elem_provenance: Rc, + arg_contract: Rc, + scope: Rc, +) -> Rc>> { + { + let is_fold = method_name_is(method_name.clone(), "fold".to_string()); + Rc::new({ + let mut __result = Vec::new(); + for idx_pair in Rc::new( + method_args + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.push({ + let a = idx_pair.1.clone(); +let idx = idx_pair.0.clone(); +let is_init_arg = (arg_has_name(a.clone(), "init".to_string(), scope.type_env.clone().source_indices.clone()) || ((arg_name_at(a.clone(), scope.type_env.clone().source_indices.clone()) == None) && (idx.clone() == 0))); +if ((is_fold.clone() && (fold_info.clone() != None)) && is_init_arg.clone()) { + match fold_info.clone() { + Some(fi) => fi.clone(), + None => infer_arg_with_element_type(a.clone(), element_type.clone(), scope.clone()), +} + } else { + if (is_fold.clone() && (fold_info.clone() != None)) { + { + let fold_params = Rc::new(vec![make_param_node("acc".to_string(), fold_acc_type.clone(), None, no_span(), no_span()), make_param_node("elem".to_string(), element_type.clone(), None, no_span(), no_span())]); +let fold_callable = Rc::new(Node { + name: "".to_string(), + span: no_span(), + ident_span: None, + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: fold_params.clone(), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, +}); +let lam_value = arg_value(a.clone()); +let prov_map = match (*elem_provenance.clone()).clone() { + SubValueRelation::SubValueUnknown => v1_rt::rc_empty_map::>(), + _ => v1_rt::rc_map_insert(v1_rt::rc_empty_map::>(), "elem".to_string(), elem_provenance.clone()), +}; +let fold_scope = Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: scope.locals.clone(), + body_locals: scope.body_locals.clone(), + match_bound_names: scope.match_bound_names.clone(), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: scope.caller_decl_name.clone(), + lambda_param_provenance: prov_map.clone(), +}); +let ar = infer_expr(lam_value.clone(), fold_scope.clone(), Some(fold_callable.clone())); +Rc::new(ArgInferResult { + typed_arg: make_arg_node(arg_name_at(a.clone(), scope.type_env.clone().source_indices.clone()), ar.typed.clone(), a.span.clone(), a.span.clone()), + diagnostics: ar.diagnostics.clone(), +}) +} + } else { + { + let nf_lam_value = arg_value(a.clone()); +let nf_prov_map = match (*elem_provenance.clone()).clone() { + SubValueRelation::SubValueUnknown => v1_rt::rc_empty_map::>(), + _ => v1_rt::rc_map_insert(v1_rt::rc_empty_map::>(), "elem".to_string(), elem_provenance.clone()), +}; +let nf_scope = if is_lambda_expr(nf_lam_value.clone()) { + Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: scope.locals.clone(), + body_locals: scope.body_locals.clone(), + match_bound_names: scope.match_bound_names.clone(), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: scope.caller_decl_name.clone(), + lambda_param_provenance: nf_prov_map.clone(), +}) + } else { + scope.clone() + }; +match (*arg_contract.clone()).clone() { + DeclaredArgContract::MethodUnresolved => infer_arg_with_element_type(a.clone(), element_type.clone(), nf_scope.clone()), + DeclaredArgContract::ContractUnavailable => { + let ar = infer_expr(nf_lam_value.clone(), nf_scope.clone(), None); +let contract_diag = categorized_error("no declared argument contract is available for this method call; refusing rather than substituting the receiver element type".to_string(), a.span.clone(), nf_scope.module_name.clone(), "method-arg-contract-unavailable".to_string()); +Rc::new(ArgInferResult { + typed_arg: make_arg_node(arg_name_at(a.clone(), nf_scope.type_env.clone().source_indices.clone()), ar.typed.clone(), a.span.clone(), a.span.clone()), + diagnostics: v1_rt::concat(ar.diagnostics.clone(), Rc::new(vec![contract_diag.clone()])), +}) +}, + DeclaredArgContract::ContractKnown { types: declared_types, .. } => match declared_types.clone().iter().cloned().skip(idx.clone() as usize).next() { + Some(declared_type) => infer_arg_with_element_type(a.clone(), declared_type.clone(), nf_scope.clone()), + None => { + let ar = infer_expr(nf_lam_value.clone(), nf_scope.clone(), None); +let contract_diag = categorized_error("no declared argument contract is available at this parameter position; refusing rather than substituting the receiver element type".to_string(), a.span.clone(), nf_scope.module_name.clone(), "method-arg-contract-unavailable".to_string()); +Rc::new(ArgInferResult { + typed_arg: make_arg_node(arg_name_at(a.clone(), nf_scope.type_env.clone().source_indices.clone()), ar.typed.clone(), a.span.clone(), a.span.clone()), + diagnostics: v1_rt::concat(ar.diagnostics.clone(), Rc::new(vec![contract_diag.clone()])), +}) +}, +}, +} +} + } + } +}); + } + __result + }) + } +} + +pub fn is_lambda_expr(e: Rc) -> bool { + match (*e.expr_data.clone()).clone() { + ExprData::ExprLambda => true, + _ => false, + } +} + +pub fn seed_override_map() -> Rc>> { + Rc::new(vec!["".to_string()]).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, k: String| { + v1_rt::rc_map_insert(acc, k.clone(), unit_type()) + }, + ) +} + +pub fn fold_override_map(key: String, value: Rc) -> Rc>> { + v1_rt::rc_map_insert(seed_override_map(), key.clone(), value.clone()) +} + +pub fn empty_override_map() -> Rc>> { + seed_override_map() +} + +pub fn infer_arg_with_element_type( + arg: Rc, + element_type: Rc, + scope: Rc, +) -> Rc { + { + let ar = infer_expr( + arg_value(arg.clone()), + scope.clone(), + Some(element_type.clone()), + ); + Rc::new(ArgInferResult { + typed_arg: make_arg_node( + arg_name_at(arg.clone(), scope.type_env.clone().source_indices.clone()), + ar.typed.clone(), + arg.span.clone(), + arg.span.clone(), + ), + diagnostics: ar.diagnostics.clone(), + }) + } +} + +pub fn binding_is_namespace_root_nominal(binding: Rc) -> bool { + (((binding.resolved.clone().name.clone() == binding.name.clone()) + && (binding.resolved.clone().connective.clone() == Connective::NoConnective)) + && ((binding.resolved.clone().children.clone().len() as i64) == 0)) +} + +pub fn spine_root_is_shadowed(scope: Rc, root: String) -> bool { + match v1_rt::map_get(&scope.locals.clone(), root.clone()) { + Some(root_binding) => !binding_is_namespace_root_nominal(root_binding.clone()), + None => false, + } +} + +pub fn qualified_value_projection( + texpr: Rc, + scope: Rc, + span: Rc, +) -> Option> { + match field_access_spine(texpr.clone(), scope.type_env.clone().source_indices.clone()) { + None => None, + Some(spine) => match spine_root_is_shadowed(scope.clone(), spine.root.clone()) { + true => None, + false => match symbol_index_lookup( + scope.type_env.clone().symbol_index.clone(), + spine.dotted.clone(), + ) { + None => None, + Some(decl) => { + let raw_value_type = match decl.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), + _ => match decl.type_annotation.clone() { + Some(ann) => ann.clone(), + None => decl.clone(), + }, + }; + let value_type = qualify_borrowed_type_names( + raw_value_type.clone(), + qualified_all_but_last(spine.dotted.clone()), + scope.type_env.clone(), + v1_rt::rc_empty_map::(), + ); + Some(ok_infer(make_named_expr_node( + spine.dotted.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(Rc::new(VarBindingKind::FunctionValueBinding)), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: value_type.clone(), + })), + span.clone(), + kernel_span(spine.dotted.clone()), + ))) + } + }, + }, + } +} + +pub fn infer_expr_body( + texpr: Rc, + scope: Rc, + expected: Option>, +) -> Rc { + match (*texpr.expr_data.clone()).clone() { + ExprData::ExprLiteral { value: lit, .. } => { + let span = texpr.span.clone(); + ok_infer(make_expr_node( + Rc::new(ExprData::ExprLiteral { value: lit.clone() }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: infer_literal_node(lit.clone()), + })), + span.clone(), + )) + } + ExprData::ExprError { kind, message, .. } => { + let span = texpr.span.clone(); + let diagnostics = match kind.clone() { + ExprErrorKind::CensusHeadsBodyStripped => Rc::new(vec![inference_error( + message.clone(), + span.clone(), + scope.module_name.clone(), + )]), + _ => Rc::new(vec![]), + }; + Rc::new(InferResult { + typed: make_expr_error_node(kind.clone(), message.clone(), span.clone()), + diagnostics: diagnostics.clone(), + }) + } + ExprData::ExprVar { + binding_kind: _, .. + } => { + let name = + expr_var_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let span = texpr.span.clone(); + match constructor_reference_admission_unshadowed( + name.clone(), + span.clone(), + scope.clone(), + ) { + Some(refusal) => refusal.clone(), + None => match v1_rt::map_get(&scope.locals.clone(), name.clone()) { + Some(binding) => { + let scope_parent = lookup_variant_parent_enum(scope.clone(), name.clone()); + match scope_parent.clone() { + Some(scope_enum) => ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(Rc::new( + VarBindingKind::VariantValueBinding { + parent_enum: scope_enum.clone(), + }, + )), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: variant_reference_inferred_node( + expected.clone(), + name.clone(), + scope_enum.clone(), + scope.clone(), + binding.resolved.clone(), + ), + })), + span.clone(), + span.clone(), + )), + None => { + let binding_kind = + infer_var_binding_kind(scope.clone(), name.clone()); + ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(binding_kind.clone()), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: binding.resolved.clone(), + })), + span.clone(), + span.clone(), + )) + } + } + } + None => match (*lookup_func_sig( + scope.func_env.clone(), + scope.type_env.clone(), + name.clone(), + )) + .clone() + { + FuncSigLookup::FuncSigResolved { sig: fsig, .. } => { + match ((fsig.params.clone().len() as i64) == 0) { + true => ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: fsig.inferred.clone(), + })), + span.clone(), + span.clone(), + )), + false => ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(Rc::new( + VarBindingKind::FunctionValueBinding, + )), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: resolved_callable_type( + fsig.params.clone(), + fsig.inferred.clone(), + ), + })), + span.clone(), + span.clone(), + )), + } + } + FuncSigLookup::FuncSigAmbiguous { + candidates: ambiguous_fn_candidates, + .. + } => ambiguous_reference_refusal( + name.clone(), + ambiguous_fn_candidates.clone(), + span.clone(), + scope.clone(), + ), + FuncSigLookup::FuncSigUnresolved => { + match lookup_binding_by_name(scope.type_env.clone(), name.clone()) { + Some(gbinding) => { + let scope_parent = + lookup_variant_parent_enum(scope.clone(), name.clone()); + match scope_parent.clone() { + Some(scope_enum) => ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(Rc::new( + VarBindingKind::VariantValueBinding { + parent_enum: scope_enum.clone(), + }, + )), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: variant_reference_inferred_node( + expected.clone(), + name.clone(), + scope_enum.clone(), + scope.clone(), + gbinding.resolved.clone(), + ), + })), + span.clone(), + span.clone(), + )), + None => { + let binding_kind = + infer_var_binding_kind(scope.clone(), name.clone()); + ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(binding_kind.clone()), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: gbinding.resolved.clone(), + })), + span.clone(), + span.clone(), + )) + } + } + } + None => { + let expected_variant_enum = + expected_variant_owner_instantiation( + expected.clone(), + name.clone(), + scope.clone(), + ); + match expected_variant_enum.clone() { + Some(exp_enum) => ok_infer(make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: Some(Rc::new( + VarBindingKind::VariantValueBinding { + parent_enum: authored_name_at( + scope + .type_env + .clone() + .source_indices + .clone(), + exp_enum.clone(), + ), + }, + )), + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: exp_enum.clone(), + })), + span.clone(), + span.clone(), + )), + None => { + let var_ambiguity_cands = + global_bare_strict_ambiguity_candidates( + scope.type_env.clone(), + name.clone(), + ); + if ((var_ambiguity_cands.clone().len() as i64) > 0) { + ambiguous_reference_refusal( + name.clone(), + var_ambiguity_cands.clone(), + span.clone(), + scope.clone(), + ) + } else { + { + let err_texpr = make_named_expr_node( + name.clone(), + Rc::new(ExprData::ExprVar { + binding_kind: None, + }), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { + node: error_type(), + })), + span.clone(), + span.clone(), + ); + Rc::new(InferResult { + typed: err_texpr.clone(), + diagnostics: Rc::new(vec![ + inference_error( + v1_rt::concat( + v1_rt::concat( + "undefined variable '" + .to_string(), + name.clone(), + ), + "'".to_string(), + ), + span.clone(), + scope.module_name.clone(), + ), + ]), + }) + } + } + } + } + } + } + } + }, + }, + } + } + ExprData::ExprFieldAccess { summary: _, .. } => { + let field_name = + field_access_field_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let span = texpr.span.clone(); + let base_expr = field_access_base(texpr.clone()); + match qualified_value_projection(texpr.clone(), scope.clone(), span.clone()) { + Some(proj) => proj.clone(), + None => { + let base_result = infer_expr(base_expr.clone(), scope.clone(), None); + let base_typed = base_result.typed.clone(); + let base_diags = base_result.diagnostics.clone(); + let base_rt = resolved_type(base_typed.clone()); + let base_expansion = + if is_deferred_field_access_base(base_rt.clone(), scope.type_env.clone()) { + Rc::new(NodeResolveResult { + resolved: base_rt.clone(), + diagnostics: Rc::new(vec![]), + }) + } else { + expand_type_for_field_access( + base_rt.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ) + }; + let resolved_base = base_expansion.resolved.clone(); + let resolved_base_diags = base_expansion.diagnostics.clone(); + let resolved_base_is_error = if (resolved_base.inferred.clone() != None) { + is_compiler_error(resolved_base.inferred.clone().clone().unwrap()) + } else { + false + }; + if resolved_base_is_error.clone() { + Rc::new(InferResult { + typed: make_expr_error_node( + ExprErrorKind::SemanticExprError, + "error type cascade".to_string(), + span.clone(), + ), + diagnostics: v1_rt::concat( + base_diags.clone(), + resolved_base_diags.clone(), + ), + }) + } else { + { + let field_type_lookup = lookup_field_type_node( + resolved_base.clone(), + field_name.clone(), + scope.type_env.clone().source_indices.clone(), + ); + match field_type_lookup.clone() { + Some(raw_field_type) => { + let field_type = stamp_field_type_from_decl_params( + raw_field_type.clone(), + resolved_base.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let field_summary = match field_summary_for_type( + base_rt.clone(), + scope.type_env.clone(), + field_name.clone(), + ) { + Some(s) => Some(s.clone()), + None => field_summary_for_type( + resolved_base.clone(), + scope.type_env.clone(), + field_name.clone(), + ), + }; + let fa_texpr = make_named_expr_node( + field_name.clone(), + Rc::new(ExprData::ExprFieldAccess { + summary: field_summary.clone(), + }), + Rc::new(vec![base_typed.clone()]), + Some(Rc::new(InferredNode::Resolved { + node: field_type.clone(), + })), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: fa_texpr.clone(), + diagnostics: v1_rt::concat( + base_diags.clone(), + resolved_base_diags.clone(), + ), + }) + } + None => { + let base_is_type_var = is_deferred_field_access_base( + resolved_base.clone(), + scope.type_env.clone(), + ); + if base_is_type_var.clone() { + { + let fa_texpr = make_named_expr_node( + field_name.clone(), + Rc::new(ExprData::ExprFieldAccess { + summary: Some(Rc::new(FieldSummary { + access_style: FieldAccessStyle::StoredField, + value_shape: FieldValueShape::PlainValue, + })), + }), + Rc::new(vec![base_typed.clone()]), + Some(Rc::new(InferredNode::TypeVariable { + id: "field_of_type_var".to_string(), + })), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: fa_texpr.clone(), + diagnostics: v1_rt::concat( + base_diags.clone(), + resolved_base_diags.clone(), + ), + }) + } + } else { + match check_service_field_access_node( + base_rt.clone(), + field_name.clone(), + scope.service_registry.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(svc_type) => { + let fa_texpr = make_named_expr_node( + field_name.clone(), + Rc::new(ExprData::ExprFieldAccess { + summary: Some(Rc::new(FieldSummary { + access_style: + FieldAccessStyle::StoredField, + value_shape: + FieldValueShape::PlainValue, + })), + }), + Rc::new(vec![base_typed.clone()]), + Some(Rc::new(InferredNode::Resolved { + node: svc_type.clone(), + })), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: fa_texpr.clone(), + diagnostics: v1_rt::concat( + base_diags.clone(), + resolved_base_diags.clone(), + ), + }) + } + None => { + let error_message = v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + "no field '".to_string(), + field_name.clone(), + ), + "' on type '".to_string(), + ), + authored_name_at( + scope + .type_env + .clone() + .source_indices + .clone(), + resolved_base.clone(), + ), + ), + "'".to_string(), + ); + let fa_texpr = make_expr_error_node( + ExprErrorKind::SemanticExprError, + error_message.clone(), + span.clone(), + ); + Rc::new(InferResult { + typed: fa_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + base_diags.clone(), + resolved_base_diags.clone(), + ), + Rc::new(vec![inference_error( + error_message.clone(), + span.clone(), + scope.module_name.clone(), + )]), + ), + }) + } + } + } + } + } + } + } + } + } + } + ExprData::ExprCall { .. } => { + let func_name = + expr_call_func_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let span = texpr.span.clone(); + let call_args = texpr.children.clone(); + let call_sig_lookup = body_shadow_aware_func_sig(scope.clone(), func_name.clone()); + match (*call_sig_lookup.clone()).clone() { + FuncSigLookup::FuncSigAmbiguous { + candidates: ambiguous_fn_candidates, + .. + } => ambiguous_reference_refusal( + func_name.clone(), + ambiguous_fn_candidates.clone(), + span.clone(), + scope.clone(), + ), + _ => { + match constructor_reference_admission_unshadowed( + func_name.clone(), + span.clone(), + scope.clone(), + ) { + Some(refusal) => refusal.clone(), + None => { + let sig = func_sig_if_resolved(call_sig_lookup.clone()); + let sig_params = match sig.clone() { + Some(s) => s.params.clone(), + None => Rc::new(vec![]), + }; + let call_sig_split = split_sig_params( + sig_params.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let has_lambda = { + let mut __found = false; + for a in call_args.clone().iter().cloned() { + if is_lambda_expr(arg_value(a.clone())) { + __found = true; + break; + } + } + __found + }; + let call_method_args = Rc::new( + call_args + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + let call_method_name = Some(func_name.clone()); + let call_fold_info = extract_fold_init_info( + call_method_name.clone(), + call_method_args.clone(), + 2, + scope.clone(), + expected.clone(), + ); + let call_fold_acc_type = match call_fold_info.clone() { + Some(fi) => resolved_type(arg_value(fi.typed_arg.clone())), + None => error_type(), + }; + let arg_call = if ((has_lambda.clone() + && ((call_args.clone().len() as i64) >= 2)) + && (sig.clone() == None)) + { + Rc::new(ArgGenericFoldState { + subst: v1_rt::rc_empty_map::>(), + results: match call_args.clone().first().cloned() { + Some(first_arg) => { + let first_result = infer_expr( + arg_value(first_arg.clone()), + scope.clone(), + None, + ); + let first_type = + resolved_type(first_result.typed.clone()); + let elem_type = for_each_element_type_node( + first_type.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let call_elem_provenance = derive_element_provenance( + first_result.typed.clone(), + elem_type.clone(), + scope.clone(), + ); + let remaining_results = infer_method_args_with_fold( + call_method_name.clone(), + call_method_args.clone(), + call_fold_info.clone(), + call_fold_acc_type.clone(), + elem_type.clone(), + call_elem_provenance.clone(), + Rc::new(DeclaredArgContract::MethodUnresolved), + scope.clone(), + ); + v1_rt::concat( + Rc::new(vec![Rc::new(ArgInferResult { + typed_arg: make_arg_node( + arg_name_at( + first_arg.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + ), + first_result.typed.clone(), + first_arg.span.clone(), + first_arg.span.clone(), + ), + diagnostics: first_result.diagnostics.clone(), + })]), + remaining_results.clone(), + ) + } + None => Rc::new(vec![]), + }, + }) + } else { + { + let value_params = call_sig_split.value_params.clone(); + let generic_names = call_sig_split.generic_names.clone(); + let final_state = Rc::new( + call_args + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + Rc::new(ArgGenericFoldState { + results: Rc::new(vec![]), + subst: v1_rt::rc_empty_map::>(), + }), + |st: Rc, pair: (i64, Rc)| { + let a = pair.1.clone(); + let formal_lookup = value_params + .clone() + .iter() + .cloned() + .skip(pair.0.clone() as usize) + .next(); + let formal_raw = match formal_lookup.clone() { + Some(p) => param_node_type_expr(p.clone()), + None => { + type_variable_node("callable_param".to_string()) + } + }; + let has_formal = match formal_lookup.clone() { + Some(_) => true, + None => false, + }; + let formal_param_type = substitute_generics( + formal_raw.clone(), + st.subst.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let expected = if has_formal.clone() { + Some(formal_param_type.clone()) + } else { + None + }; + let ar = infer_expr( + arg_value(a.clone()), + scope.clone(), + expected.clone(), + ); + let next_subst = + if (is_lambda_expr(arg_value(a.clone())) + || !has_formal.clone()) + { + st.subst.clone() + } else { + if should_unify_record_lit_generics( + formal_raw.clone(), + arg_value(a.clone()), + generic_names.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + ) { + unify_record_lit_generics( + formal_raw.clone(), + ar.typed.clone(), + generic_names.clone(), + scope.clone(), + st.subst.clone(), + ) + } else { + unify_generics( + formal_raw.clone(), + resolved_type(ar.typed.clone()), + generic_names.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + st.subst.clone(), + ) + } + }; + Rc::new(ArgGenericFoldState { + results: v1_rt::concat( + st.results.clone(), + Rc::new(vec![Rc::new(ArgInferResult { + typed_arg: make_arg_node( + arg_name_at( + a.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + ), + ar.typed.clone(), + a.span.clone(), + a.span.clone(), + ), + diagnostics: ar.diagnostics.clone(), + })]), + ), + subst: next_subst.clone(), + }) + }, + ); + final_state.clone() + } + }; + let arg_infer_results = arg_call.results.clone(); + let call_subst = arg_call.subst.clone(); + let typed_args = Rc::new({ + let mut __result = Vec::new(); + for air in arg_infer_results.clone().iter().cloned() { + __result.push(air.typed_arg.clone()); + } + __result + }); + let arg_diags = v1_rt::concat( + Rc::new({ + let mut __result = Vec::new(); + for air in arg_infer_results.clone().iter().cloned() { + __result.extend((*air.diagnostics.clone()).iter().cloned()); + } + __result + }), + function_value_call_named_arg_diags( + func_name.clone(), + typed_args.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + scope.body_locals.clone(), + scope.locals.clone(), + ), + ); + let typed_arg_nodes = typed_args.clone(); + if (sig.clone() != None) { + { + let resolved_type = match sig.clone() { + Some(s) => substitute_generics( + s.inferred.clone(), + call_subst.clone(), + scope.type_env.clone().source_indices.clone(), + ), + None => error_type(), + }; + let value_params_for_check = + call_sig_split.value_params.clone(); + let arg_shape_diags = direct_call_shape_diags( + func_name.clone(), + sig_params.clone(), + typed_args.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + span.clone(), + ); + let call_application_plan = build_call_application_plan( + value_params_for_check.clone(), + typed_args.clone(), + call_subst.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ); + let arg_compat_diags = if module_skips_direct_call_arg_check( + scope.module_name.clone(), + ) { + Rc::new(vec![]) + } else { + direct_call_arg_mismatch_diags( + call_application_plan.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ) + }; + let structured_arg_diags = + direct_call_structured_application_mismatch_diags( + call_application_plan.clone(), + scope.clone(), + ); + Rc::new(InferResult { + typed: make_named_expr_node( + func_name.clone(), + Rc::new(ExprData::ExprCall { + call_semantics: Some( + CallSemantics::PlainCallSemantics, + ), + descent_evidence: None, + }), + typed_arg_nodes.clone(), + Some(Rc::new(InferredNode::Resolved { + node: resolved_type.clone(), + })), + span.clone(), + node_name_span(texpr.clone()), + ), + diagnostics: v1_rt::concat( + arg_diags.clone(), + v1_rt::concat( + arg_shape_diags.clone(), + v1_rt::concat( + arg_compat_diags.clone(), + structured_arg_diags.clone(), + ), + ), + ), + }) + } + } else { + { + let first_arg_type = match typed_args.clone().first().cloned() { + Some(ta) => resolved_type(arg_value(ta.clone())), + None => unit_type(), + }; + let method_receiver = match typed_args.clone().first().cloned() + { + Some(ta) => arg_value(ta.clone()), + None => internal_expr_error_node( + "method bridge missing receiver".to_string(), + span.clone(), + ), + }; + let call_acc_is_under_resolved = !is_fully_resolved( + call_fold_acc_type.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let refined_call_fold_acc_type = if ((call_fold_info.clone() + != None) + && call_acc_is_under_resolved.clone()) + { + match Rc::new({ + let mut __result = Vec::new(); + for a in typed_args.clone().iter().cloned() { + if is_lambda_expr(arg_value(a.clone())) { + __result.push(a); + } + } + __result + }) + .first() + .cloned() + { + Some(lambda_arg) => { + resolved_type(arg_value(lambda_arg.clone())) + } + None => call_fold_acc_type.clone(), + } + } else { + call_fold_acc_type.clone() + }; + let method_resolution = + if listed_import_required_bare_call_blocked( + scope.type_env.clone(), + func_name.clone(), + ) { + Rc::new(KnownMethodResolution { + semantics: None, + result_type: None, + diagnostics: Rc::new(vec![]), + }) + } else { + resolve_known_method_node( + method_receiver.clone(), + resolve_method_receiver_type( + first_arg_type.clone(), + scope.type_env.clone(), + ), + func_name.clone(), + if (call_fold_info.clone() != None) { + Some(refined_call_fold_acc_type.clone()) + } else { + None + }, + scope.service_registry.clone(), + scope.type_env.clone().source_indices.clone(), + ) + }; + let callee_is_body_binding = v1_rt::map_has( + &scope.body_locals.clone(), + func_name.clone(), + ); + let is_known_method = (!callee_is_body_binding.clone() + && (method_resolution.result_type.clone() != None)); + if (is_known_method.clone() + && ((typed_args.clone().len() as i64) > 0)) + { + { + let receiver = method_receiver.clone(); + let remaining = Rc::new( + typed_args + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + let base_result_type = + match method_resolution.result_type.clone() { + Some(mt) => mt.clone(), + None => error_type(), + }; + let method_tv = if (method_resolution.semantics.clone() + == None) + { + Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }) + } else { + match (*method_resolution + .semantics + .clone() + .clone() + .unwrap()) + .clone() + { + MethodSemantics::AlgebraMethodSemantics { + algebra_template: at, + .. + } => match at.clone() { + Some(t) => { + if (template_return_has_variables( + t.clone(), + ) || !is_fully_resolved( + base_result_type.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + )) { + { + let call_arg_types = Rc::new({ + let mut __result = + Vec::new(); + for a in remaining + .clone() + .iter() + .cloned() + { + __result.push( + resolved_type( + arg_value( + a.clone(), + ), + ), + ); + } + __result + }); + let fold_overrides = + if (call_fold_info.clone() + != None) + { + fold_override_map("FoldAccumulator".to_string(), refined_call_fold_acc_type.clone()) + } else { + empty_override_map() + }; + resolve_type_variables_from_template(t.clone(), call_arg_types.clone(), first_arg_type.clone(), fold_overrides.clone(), scope.type_env.clone().source_indices.clone()) + } + } else { + Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }) + } + } + None => Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }), + }, + _ => Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }), + } + }; + let bridge_result_type = method_tv.ty.clone(); + let template_subst_diags = + method_tv.diagnostics.clone(); + let returns_receiver_self = + if (method_resolution.semantics.clone() == None) { + false + } else { + match (*method_resolution + .semantics + .clone() + .clone() + .unwrap()) + .clone() + { + MethodSemantics::AlgebraMethodSemantics { + algebra_template: at, + .. + } => match at.clone() { + Some(t) => { + template_return_is_receiver_self( + t.clone(), + ) + } + None => false, + }, + _ => false, + } + }; + let final_receiver = if ((returns_receiver_self + .clone() + && is_fully_resolved( + bridge_result_type.clone(), + scope.type_env.clone().source_indices.clone(), + )) + && !is_fully_resolved( + first_arg_type.clone(), + scope.type_env.clone().source_indices.clone(), + )) { + Rc::new(Node { + name: receiver.name.clone(), + span: receiver.span.clone(), + ident_span: receiver.ident_span.clone(), + children: bridge_result_type.children.clone(), + connective: receiver.connective.clone(), + params: receiver.params.clone(), + inferred: Some(Rc::new( + InferredNode::Resolved { + node: bridge_result_type.clone(), + }, + )), + return_cardinality: receiver + .return_cardinality + .clone(), + uses: receiver.uses.clone(), + body: receiver.body.clone(), + transport: receiver.transport.clone(), + properties: receiver.properties.clone(), + type_annotation: receiver + .type_annotation + .clone(), + is_self_recursive: receiver + .is_self_recursive + .clone(), + has_non_tail_self_call: receiver + .has_non_tail_self_call + .clone(), + match_pattern: receiver.match_pattern.clone(), + expr_data: receiver.expr_data.clone(), + ident: None, + }) + } else { + receiver.clone() + }; + let remaining_arg_nodes = Rc::new({ + let mut __result = Vec::new(); + for ta in remaining.clone().iter().cloned() { + __result.push(make_arg_node( + arg_name_at( + ta.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + ), + arg_value(ta.clone()), + span.clone(), + span.clone(), + )); + } + __result + }); + Rc::new(InferResult { + typed: make_named_expr_node( + func_name.clone(), + Rc::new(ExprData::ExprMethodCall { + method_semantics: method_resolution + .semantics + .clone(), + }), + v1_rt::concat( + Rc::new(vec![final_receiver.clone()]), + remaining_arg_nodes.clone(), + ), + Some(Rc::new(InferredNode::Resolved { + node: bridge_result_type.clone(), + })), + span.clone(), + node_name_span(texpr.clone()), + ), + diagnostics: v1_rt::concat( + v1_rt::concat( + arg_diags.clone(), + method_resolution.diagnostics.clone(), + ), + template_subst_diags.clone(), + ), + }) + } + } else { + if (!callee_is_body_binding.clone() + && (func_name.clone() == "empty_map".to_string())) + { + { + let bare_m = bare_map_node(); + match expected.clone() { + Some(exp) => if node_is_keyed_collection(exp.clone(), scope.type_env.clone().source_indices.clone()) { + Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: exp.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: arg_diags.clone(), +}) + } else { + { + let empty_map_diags = v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_map(): expected type is not a keyed collection".to_string(), span.clone(), scope.module_name.clone())])); +match bare_m.clone() { + Some(map_t) => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: map_t.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: empty_map_diags.clone(), +}), + None => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { + message: "empty_map(): Map kernel container profile missing (compiler misconfigured)".to_string(), + span: span.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: v1_rt::concat(empty_map_diags.clone(), Rc::new(vec![inference_error("empty_map(): Map kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), +}), +} +} + }, + None => match bare_m.clone() { + Some(map_t) => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: map_t.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: arg_diags.clone(), +}), + None => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { + message: "empty_map(): Map kernel container profile missing (compiler misconfigured)".to_string(), + span: span.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_map(): Map kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), +}), +}, +} + } + } else { + if (!callee_is_body_binding.clone() + && (func_name.clone() == "empty_set".to_string())) + { + { + let bare_s = bare_set_node(); + match expected.clone() { + Some(exp) => if node_is_set_collection(exp.clone(), scope.type_env.clone().source_indices.clone()) { + Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: exp.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: arg_diags.clone(), +}) + } else { + { + let empty_set_diags = v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_set(): expected type is not Set<...>".to_string(), span.clone(), scope.module_name.clone())])); +match bare_s.clone() { + Some(set_t) => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: set_t.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: empty_set_diags.clone(), +}), + None => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { + message: "empty_set(): Set kernel container profile missing (compiler misconfigured)".to_string(), + span: span.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: v1_rt::concat(empty_set_diags.clone(), Rc::new(vec![inference_error("empty_set(): Set kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), +}), +} +} + }, + None => match bare_s.clone() { + Some(set_t) => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: set_t.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: arg_diags.clone(), +}), + None => Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { + message: "empty_set(): Set kernel container profile missing (compiler misconfigured)".to_string(), + span: span.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_set(): Set kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), +}), +}, +} + } + } else { + if (!callee_is_body_binding.clone() + && (infer_builtin_call_type(func_name.clone()) + != None)) + { + { + let tier2b = + infer_tier2b_builtin_with_kernel_diags( + func_name.clone(), + typed_args.clone(), + scope.clone(), + span.clone(), + ); + let bt = tier2b.bt.clone(); + let call_semantics = if (func_name.clone() + == "lookup".to_string()) + { + Some(CallSemantics::LookupCallSemantics) + } else { + Some(CallSemantics::PlainCallSemantics) + }; + Rc::new(InferResult { + typed: make_named_expr_node( + func_name.clone(), + Rc::new(ExprData::ExprCall { + call_semantics: call_semantics + .clone(), + descent_evidence: None, + }), + typed_arg_nodes.clone(), + Some(Rc::new( + InferredNode::Resolved { + node: bt.clone(), + }, + )), + span.clone(), + node_name_span(texpr.clone()), + ), + diagnostics: v1_rt::concat( + arg_diags.clone(), + tier2b.kernel_diags.clone(), + ), + }) + } + } else { + { + let callable_local = match v1_rt::map_get( + &scope.locals.clone(), + func_name.clone(), + ) { + Some(binding) => { + if ((binding + .resolved + .clone() + .params + .clone() + .len() + as i64) + > 0) + { + Some(binding.resolved.clone()) + } else { + None + } + } + None => None, + }; + if (callable_local.clone() != None) { + { + let callable_type = + match callable_local.clone() { + Some(ct) => ct.clone(), + None => error_type(), + }; + let resolved_type = match callable_type.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: ret, .. }) => ret.clone(), + _ => error_type(), +}; + Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(if callee_is_body_binding.clone() { + CallSemantics::FunctionValueCallSemantics + } else { + CallSemantics::PlainCallSemantics + }), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: resolved_type.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: arg_diags.clone(), +}) + } + } else { + match infer_variant_constructor_call( + func_name.clone(), + call_args.clone(), + span.clone(), + node_name_span(texpr.clone()), + scope.clone(), + ) { + Some(ctor_result) => { + ctor_result.clone() + } + None => { + let type_match = + lookup_type_by_name( + scope.type_env.clone(), + func_name.clone(), + ); + let global_bare_callable = match type_match.clone() { + Some(_) => None, + None => global_bare_callable_node(scope.type_env.clone(), func_name.clone()), +}; + let resolved_type = match type_match.clone() { + Some(tn) => tn.clone(), + None => match global_bare_callable.clone() { + Some(gnode) => if ((gnode.params.clone().len() as i64) > 0) { + borrowed_callable_call_type(gnode.clone(), typed_arg_nodes.clone(), scope.clone()) + } else { + callable_return_type(gnode.clone()) + }, + None => error_type(), +}, +}; + let call_diags = match type_match.clone() { + Some(_) => Rc::new(vec![]), + None => match global_bare_callable.clone() { + Some(_) => Rc::new(vec![]), + None => { + let call_ambiguity_cands = global_bare_strict_ambiguity_candidates(scope.type_env.clone(), func_name.clone()); +if ((call_ambiguity_cands.clone().len() as i64) > 0) { + Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::AmbiguousReference { + name: func_name.clone(), + candidates: call_ambiguity_cands.clone(), + span: span.clone(), +}), scope.module_name.clone())]) + } else { + Rc::new(vec![inference_error(v1_rt::concat(v1_rt::concat("function '".to_string(), func_name.clone()), "' not found in scope".to_string()), span.clone(), scope.module_name.clone())]) + } +}, +}, +}; + Rc::new(InferResult { + typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, +}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { + node: resolved_type.clone(), +})), span.clone(), node_name_span(texpr.clone())), + diagnostics: v1_rt::concat(arg_diags.clone(), call_diags.clone()), +}) + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let method_name = + expr_method_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let span = texpr.span.clone(); + let recv = method_receiver(texpr.clone()); + let mc_args = method_arg_nodes(texpr.clone()); + let qualified_direct_call = match field_access_spine( + recv.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + None => None, + Some(recv_spine) => { + match spine_root_is_shadowed(scope.clone(), recv_spine.root.clone()) { + true => None, + false => { + let dotted = v1_rt::concat( + v1_rt::concat(recv_spine.dotted.clone(), ".".to_string()), + method_name.clone(), + ); + match symbol_index_lookup( + scope.type_env.clone().symbol_index.clone(), + dotted.clone(), + ) { + None => None, + Some(_) => Some(infer_expr( + make_named_expr_node( + dotted.clone(), + Rc::new(ExprData::ExprCall { + call_semantics: Some(CallSemantics::PlainCallSemantics), + descent_evidence: None, + }), + mc_args.clone(), + None, + span.clone(), + kernel_span(dotted.clone()), + ), + scope.clone(), + expected.clone(), + )), + } + } + } + } + }; + match qualified_direct_call.clone() { + Some(qdc) => qdc.clone(), + None => { + let recv_result = infer_expr(recv.clone(), scope.clone(), None); + let recv_typed = recv_result.typed.clone(); + let recv_diags = recv_result.diagnostics.clone(); + let recv_rt = resolve_method_receiver_type( + resolved_type(recv_typed.clone()), + scope.type_env.clone(), + ); + let recv_elem_type = for_each_element_type_node( + recv_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let mc_method_name = Some(method_name.clone()); + let fold_info = extract_fold_init_info( + mc_method_name.clone(), + mc_args.clone(), + 2, + scope.clone(), + expected.clone(), + ); + let fold_acc_type = match fold_info.clone() { + Some(fi) => resolved_type(arg_value(fi.typed_arg.clone())), + None => error_type(), + }; + let mc_elem_provenance = derive_element_provenance( + recv_typed.clone(), + recv_elem_type.clone(), + scope.clone(), + ); + let mc_arg_contract = declared_arg_types_for_method( + recv_rt.clone(), + method_name.clone(), + scope.type_env.clone().source_indices.clone(), + |n| { + expand_type_for_field_access( + n.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ) + .resolved + .clone() + }, + ); + let mc_arg_infer_results = infer_method_args_with_fold( + mc_method_name.clone(), + mc_args.clone(), + fold_info.clone(), + fold_acc_type.clone(), + recv_elem_type.clone(), + mc_elem_provenance.clone(), + mc_arg_contract.clone(), + scope.clone(), + ); + let typed_mc_args = Rc::new({ + let mut __result = Vec::new(); + for air in mc_arg_infer_results.clone().iter().cloned() { + __result.push(air.typed_arg.clone()); + } + __result + }); + let mc_arg_diags = Rc::new({ + let mut __result = Vec::new(); + for air in mc_arg_infer_results.clone().iter().cloned() { + __result.extend((*air.diagnostics.clone()).iter().cloned()); + } + __result + }); + let mc_acc_is_under_resolved = !is_fully_resolved( + fold_acc_type.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let refined_fold_acc_type = + if ((fold_info.clone() != None) && mc_acc_is_under_resolved.clone()) { + match Rc::new({ + let mut __result = Vec::new(); + for a in typed_mc_args.clone().iter().cloned() { + if is_lambda_expr(arg_value(a.clone())) { + __result.push(a); + } + } + __result + }) + .first() + .cloned() + { + Some(lambda_arg) => resolved_type(arg_value(lambda_arg.clone())), + None => fold_acc_type.clone(), + } + } else { + fold_acc_type.clone() + }; + let method_resolution = resolve_known_method_node( + recv_typed.clone(), + recv_rt.clone(), + method_name.clone(), + if (fold_info.clone() != None) { + Some(refined_fold_acc_type.clone()) + } else { + None + }, + scope.service_registry.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let pipe_fb = match method_resolution.result_type.clone() { + Some(rt) => Rc::new(MethodPipeFallback { + result_ty: rt.clone(), + kernel_diags: Rc::new(vec![]), + }), + None => method_pipe_map_keys_values_fallback( + recv_rt.clone(), + method_name.clone(), + scope.clone(), + span.clone(), + ), + }; + let base_result_type = pipe_fb.result_ty.clone(); + let method_tv_mc = if (method_resolution.semantics.clone() == None) { + Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }) + } else { + match (*method_resolution.semantics.clone().clone().unwrap()).clone() { + MethodSemantics::AlgebraMethodSemantics { + algebra_template: at, + .. + } => match at.clone() { + Some(t) => { + if (template_return_has_variables(t.clone()) + || !is_fully_resolved( + base_result_type.clone(), + scope.type_env.clone().source_indices.clone(), + )) + { + { + let mc_arg_types = Rc::new({ + let mut __result = Vec::new(); + for a in typed_mc_args.clone().iter().cloned() { + __result + .push(resolved_type(arg_value(a.clone()))); + } + __result + }); + let mc_fold_overrides = if (fold_info.clone() != None) { + fold_override_map( + "FoldAccumulator".to_string(), + refined_fold_acc_type.clone(), + ) + } else { + empty_override_map() + }; + resolve_type_variables_from_template( + t.clone(), + mc_arg_types.clone(), + recv_rt.clone(), + mc_fold_overrides.clone(), + scope.type_env.clone().source_indices.clone(), + ) + } + } else { + Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }) + } + } + None => Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }), + }, + _ => Rc::new(KernelTypeBuild { + ty: base_result_type.clone(), + diagnostics: Rc::new(vec![]), + }), + } + }; + let result_type = method_tv_mc.ty.clone(); + let mc_template_diags = method_tv_mc.diagnostics.clone(); + let method_semantics = if (method_resolution.semantics.clone() != None) { + method_resolution.semantics.clone() + } else { + Some(Rc::new(MethodSemantics::PlainMethodSemantics)) + }; + let typed_mc_arg_nodes = typed_mc_args.clone(); + let mc_texpr = make_named_expr_node( + method_name.clone(), + Rc::new(ExprData::ExprMethodCall { + method_semantics: method_semantics.clone(), + }), + v1_rt::concat( + Rc::new(vec![recv_typed.clone()]), + typed_mc_arg_nodes.clone(), + ), + Some(Rc::new(InferredNode::Resolved { + node: result_type.clone(), + })), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: mc_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat(recv_diags.clone(), mc_arg_diags.clone()), + pipe_fb.kernel_diags.clone(), + ), + v1_rt::concat( + method_resolution.diagnostics.clone(), + mc_template_diags.clone(), + ), + ), + }) + } + } + } + ExprData::ExprMatch => { + let span = texpr.span.clone(); + let scrut = match_scrutinee(texpr.clone()); + let arm_nodes = match_arm_nodes(texpr.clone()); + let scrut_result = infer_expr(scrut.clone(), scope.clone(), None); + let scrut_typed = scrut_result.typed.clone(); + let scrut_diags = scrut_result.diagnostics.clone(); + let scrut_rt = resolved_type(scrut_typed.clone()); + let scrut_subject = pattern_subject_from_inferred(scrut_typed.inferred.clone()); + let scrut_provenance = classify_binding_provenance(scrut.clone(), scope.clone()); + let arm_infer_results = Rc::new({ + let mut __result = Vec::new(); + for arm_node in arm_nodes.clone().iter().cloned() { + __result.push({ + let arm_pat = arm_pattern(arm_node.clone()); + let arm_g = arm_guard(arm_node.clone()); + let arm_b = arm_body(arm_node.clone()); + let typed_pattern = annotate_pattern_parent_enums( + arm_pat.clone(), + scrut_subject.clone(), + scope.clone(), + ); + let pattern_result = extend_scope_with_pattern_node( + scope.clone(), + typed_pattern.clone(), + scrut_subject.clone(), + scrut_provenance.clone(), + ); + let arm_scope = pattern_result.scope.clone(); + let pattern_diags = pattern_result.diagnostics.clone(); + let guard_result = if (arm_g.clone() != None) { + Some(infer_expr(arm_g.clone().unwrap(), arm_scope.clone(), None)) + } else { + None + }; + let body_result = + infer_expr(arm_b.clone(), arm_scope.clone(), expected.clone()); + let body_typed = body_result.typed.clone(); + let body_diags = body_result.diagnostics.clone(); + let guard_unwrapped = match guard_result.clone() { + Some(gr) => gr.clone(), + None => Rc::new(InferResult { + typed: arm_b.clone(), + diagnostics: Rc::new(vec![]), + }), + }; + let guard_diags = if (guard_result.clone() != None) { + guard_unwrapped.diagnostics.clone() + } else { + Rc::new(vec![]) + }; + Rc::new(ArmInferResult { + typed_arm: make_arm_node( + typed_pattern.clone(), + if (guard_result.clone() != None) { + Some(guard_unwrapped.typed.clone()) + } else { + None + }, + body_typed.clone(), + span.clone(), + ), + diagnostics: v1_rt::concat( + pattern_diags.clone(), + v1_rt::concat(guard_diags.clone(), body_diags.clone()), + ), + body_type: resolved_type(body_typed.clone()), + }) + }); + } + __result + }); + let arm_body_types = Rc::new({ + let mut __result = Vec::new(); + for ar in arm_infer_results.clone().iter().cloned() { + __result.push(ar.body_type.clone()); + } + __result + }); + let unified_arm_type = match arm_body_types.clone().first().cloned() { + Some(first_type) => Rc::new( + arm_body_types + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold(first_type.clone(), |acc: _, t: Rc| { + prefer_specific_type( + acc, + t.clone(), + scope.type_env.clone().source_indices.clone(), + ) + }), + None => scrut_rt.clone(), + }; + let arm_infer_results = if is_fully_resolved( + unified_arm_type.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Rc::new({ + let mut __result = Vec::new(); + for pair in Rc::new( + arm_nodes + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.push({ + let idx = pair.0.clone(); + let arm_node = pair.1.clone(); + let original_list = Rc::new({ + let mut __result = Vec::new(); + for ap in Rc::new({ + let mut __result = Vec::new(); + for ap in Rc::new( + arm_infer_results + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + if (ap.0.clone() == idx.clone()) { + __result.push(ap); + } + } + __result + }) + .iter() + .cloned() + { + __result.push(ap.1.clone()); + } + __result + }); + let original = match original_list.clone().first().cloned() { + Some(ar) => ar.clone(), + None => Rc::new(ArmInferResult { + typed_arm: arm_node.clone(), + diagnostics: Rc::new(vec![]), + body_type: scrut_rt.clone(), + }), + }; + if !is_fully_resolved( + original.body_type.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + { + let arm_pat = arm_pattern(arm_node.clone()); + let arm_g = arm_guard(arm_node.clone()); + let arm_b = arm_body(arm_node.clone()); + let typed_pattern = annotate_pattern_parent_enums( + arm_pat.clone(), + scrut_subject.clone(), + scope.clone(), + ); + let pattern_result = extend_scope_with_pattern_node( + scope.clone(), + typed_pattern.clone(), + scrut_subject.clone(), + scrut_provenance.clone(), + ); + let arm_scope = pattern_result.scope.clone(); + let pattern_diags = pattern_result.diagnostics.clone(); + let guard_result = if (arm_g.clone() != None) { + Some(infer_expr( + arm_g.clone().unwrap(), + arm_scope.clone(), + None, + )) + } else { + None + }; + let body_result = infer_expr( + arm_b.clone(), + arm_scope.clone(), + Some(unified_arm_type.clone()), + ); + let body_typed = body_result.typed.clone(); + let body_diags = body_result.diagnostics.clone(); + let guard_unwrapped = match guard_result.clone() { + Some(gr) => gr.clone(), + None => Rc::new(InferResult { + typed: arm_b.clone(), + diagnostics: Rc::new(vec![]), + }), + }; + let guard_diags = if (guard_result.clone() != None) { + guard_unwrapped.diagnostics.clone() + } else { + Rc::new(vec![]) + }; + Rc::new(ArmInferResult { + typed_arm: make_arm_node( + typed_pattern.clone(), + if (guard_result.clone() != None) { + Some(guard_unwrapped.typed.clone()) + } else { + None + }, + body_typed.clone(), + span.clone(), + ), + diagnostics: v1_rt::concat( + pattern_diags.clone(), + v1_rt::concat(guard_diags.clone(), body_diags.clone()), + ), + body_type: resolved_type(body_typed.clone()), + }) + } + } else { + original.clone() + } + }); + } + __result + }) + } else { + arm_infer_results.clone() + }; + let typed_arms = Rc::new({ + let mut __result = Vec::new(); + for ar in arm_infer_results.clone().iter().cloned() { + __result.push(ar.typed_arm.clone()); + } + __result + }); + let arm_diags = Rc::new({ + let mut __result = Vec::new(); + for ar in arm_infer_results.clone().iter().cloned() { + __result.extend((*ar.diagnostics.clone()).iter().cloned()); + } + __result + }); + let result_type = unified_arm_type.clone(); + let empty_arms_diags = if ((arm_infer_results.clone().len() as i64) == 0) { + Rc::new(vec![inference_error( + "match expression has no arms".to_string(), + span.clone(), + scope.module_name.clone(), + )]) + } else { + Rc::new(vec![]) + }; + let exhaustiveness_diags = + match (*resolve_pattern_subject(scope.clone(), scrut_subject.clone())).clone() { + PatternSubject::PatternResolved { + node: resolved_scrutinee, + .. + } => check_match_exhaustiveness( + resolved_scrutinee.clone(), + typed_arms.clone(), + scope.type_env.clone(), + span.clone(), + scope.module_name.clone(), + ), + PatternSubject::PatternDynamic { span: _, .. } => Rc::new(vec![]), + PatternSubject::PatternLookupBlocked => Rc::new(vec![]), + }; + let match_texpr = make_expr_node( + Rc::new(ExprData::ExprMatch), + v1_rt::concat(Rc::new(vec![scrut_typed.clone()]), typed_arms.clone()), + Some(Rc::new(InferredNode::Resolved { + node: result_type.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: match_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat(scrut_diags.clone(), arm_diags.clone()), + empty_arms_diags.clone(), + ), + exhaustiveness_diags.clone(), + ), + }) + } + ExprData::ExprIf => { + let span = texpr.span.clone(); + let cond = if_condition(texpr.clone()); + let then_expr = if_then_branch(texpr.clone()); + let else_expr = if_else_branch(texpr.clone()); + let cond_result = infer_expr(cond.clone(), scope.clone(), None); + let cond_typed = cond_result.typed.clone(); + let cond_diags = cond_result.diagnostics.clone(); + let then_result = infer_expr(then_expr.clone(), scope.clone(), expected.clone()); + let then_typed = then_result.typed.clone(); + let then_diags = then_result.diagnostics.clone(); + match else_expr.clone() { + Some(else_branch) => { + let else_result = + infer_expr(else_branch.clone(), scope.clone(), expected.clone()); + let then_rt = resolved_type(then_result.typed.clone()); + let else_rt = resolved_type(else_result.typed.clone()); + let then_result = if (!is_fully_resolved( + then_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ) && is_fully_resolved( + else_rt.clone(), + scope.type_env.clone().source_indices.clone(), + )) { + infer_expr(then_expr.clone(), scope.clone(), Some(else_rt.clone())) + } else { + then_result.clone() + }; + let else_result = if (!is_fully_resolved( + else_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ) && is_fully_resolved( + then_rt.clone(), + scope.type_env.clone().source_indices.clone(), + )) { + infer_expr(else_branch.clone(), scope.clone(), Some(then_rt.clone())) + } else { + else_result.clone() + }; + let then_typed = then_result.typed.clone(); + let then_diags = then_result.diagnostics.clone(); + let else_typed = else_result.typed.clone(); + let else_diags = else_result.diagnostics.clone(); + let then_rt = resolved_type(then_typed.clone()); + let else_rt = resolved_type(else_typed.clone()); + let unified = prefer_specific_type( + then_rt.clone(), + else_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let branch_diags = if node_type_compatible( + then_rt.clone(), + else_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Rc::new(vec![]) + } else { + Rc::new(vec![inference_error( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + "if branches resolve to incompatible types: ".to_string(), + node_type_shape( + then_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ), + ), + " vs ".to_string(), + ), + node_type_shape( + else_rt.clone(), + scope.type_env.clone().source_indices.clone(), + ), + ), + span.clone(), + scope.module_name.clone(), + )]) + }; + let if_texpr = make_expr_node( + Rc::new(ExprData::ExprIf), + Rc::new(vec![ + cond_typed.clone(), + then_typed.clone(), + else_typed.clone(), + ]), + Some(Rc::new(InferredNode::Resolved { + node: unified.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: if_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat(cond_diags.clone(), then_diags.clone()), + else_diags.clone(), + ), + branch_diags.clone(), + ), + }) + } + None => { + let if_texpr2 = make_expr_node( + Rc::new(ExprData::ExprIf), + Rc::new(vec![cond_typed.clone(), then_typed.clone()]), + Some(Rc::new(InferredNode::Resolved { node: unit_type() })), + span.clone(), + ); + Rc::new(InferResult { + typed: if_texpr2.clone(), + diagnostics: v1_rt::concat(cond_diags.clone(), then_diags.clone()), + }) + } + } + } + ExprData::ExprLet => { + let let_name = + let_binding_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let span = texpr.span.clone(); + let val_expr = let_value(texpr.clone()); + let body_expr = let_body(texpr.clone()); + let is_tail_return = match body_expr.clone() { + Some(bd) => match (*bd.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + (authored_name_at( + scope.type_env.clone().source_indices.clone(), + bd.clone(), + ) == let_name.clone()) + } + _ => false, + }, + None => false, + }; + let val_expected = if ((texpr.type_annotation.clone() != None) + && is_type_expr_annotation(texpr.type_annotation.clone().clone().unwrap())) + { + Some(texpr.type_annotation.clone().clone().unwrap()) + } else { + if is_tail_return.clone() { + expected.clone() + } else { + None + } + }; + let val_result = infer_expr(val_expr.clone(), scope.clone(), val_expected.clone()); + let val_typed = val_result.typed.clone(); + let val_diags = val_result.diagnostics.clone(); + let val_type = resolved_type(val_typed.clone()); + if (body_expr.clone() == None) { + { + let let_texpr = make_named_expr_node( + let_name.clone(), + Rc::new(ExprData::ExprLet), + Rc::new(vec![val_typed.clone()]), + Some(Rc::new(InferredNode::Resolved { + node: val_type.clone(), + })), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: let_texpr.clone(), + diagnostics: val_diags.clone(), + }) + } + } else { + { + let extended = extend_scope( + scope.clone(), + let_name.clone(), + val_type.clone(), + classify_binding_provenance(val_typed.clone(), scope.clone()), + ); + let body_result = infer_expr( + body_expr.clone().unwrap(), + extended.clone(), + expected.clone(), + ); + let body_typed = body_result.typed.clone(); + let body_diags = body_result.diagnostics.clone(); + let let_texpr2 = make_named_expr_node( + let_name.clone(), + Rc::new(ExprData::ExprLet), + Rc::new(vec![val_typed.clone(), body_typed.clone()]), + body_typed.inferred.clone(), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: let_texpr2.clone(), + diagnostics: v1_rt::concat(val_diags.clone(), body_diags.clone()), + }) + } + } + } + ExprData::ExprRecordLit { parent_enum: _, .. } => { + let span = texpr.span.clone(); + let field_inits = texpr.children.clone(); + infer_record_lit( + record_lit_type_name_at( + texpr.clone(), + scope.type_env.clone().source_indices.clone(), + ), + field_inits.clone(), + span.clone(), + node_name_span(texpr.clone()), + scope.clone(), + expected.clone(), + ) + } + ExprData::ExprListLit => { + let span = texpr.span.clone(); + let elements = texpr.children.clone(); + let elem_expected = match expected.clone() { + Some(exp) => { + if node_is_element_collection( + exp.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + match exp.children.clone().first().cloned() { + Some(elem) => Some(child_type_node(elem.clone())), + None => None, + } + } else { + None + } + } + None => None, + }; + let elem_results = Rc::new({ + let mut __result = Vec::new(); + for e in elements.clone().iter().cloned() { + __result.push(infer_expr(e.clone(), scope.clone(), elem_expected.clone())); + } + __result + }); + let typed_elements = Rc::new({ + let mut __result = Vec::new(); + for r in elem_results.clone().iter().cloned() { + __result.push(r.typed.clone()); + } + __result + }); + let elem_diags = Rc::new({ + let mut __result = Vec::new(); + for r in elem_results.clone().iter().cloned() { + __result.extend((*r.diagnostics.clone()).iter().cloned()); + } + __result + }); + let elem_type_node = if ((elem_results.clone().len() as i64) > 0) { + match elem_results.clone().first().cloned() { + Some(r) => resolved_type(r.typed.clone()), + None => unit_type(), + } + } else { + match expected.clone() { + Some(exp) => { + if node_is_element_collection( + exp.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + match exp.children.clone().first().cloned() { + Some(elem) => child_type_node(elem.clone()), + None => unit_type(), + } + } else { + unit_type() + } + } + None => unit_type(), + } + }; + let empty_list_diags = if ((elem_results.clone().len() as i64) == 0) { + match expected.clone() { + Some(exp) => { + if node_is_element_collection( + exp.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + match exp.children.clone().first().cloned() { + Some(_) => Rc::new(vec![]), + None => Rc::new(vec![inference_error( + "empty list literal: expected type has no element type" + .to_string(), + span.clone(), + scope.module_name.clone(), + )]), + } + } else { + Rc::new(vec![inference_error( + "empty list literal: expected type is not a collection".to_string(), + span.clone(), + scope.module_name.clone(), + )]) + } + } + None => Rc::new(vec![]), + } + } else { + Rc::new(vec![]) + }; + let list_k = list_kernel_ty_from_element(elem_type_node.clone()); + let ll_texpr = make_expr_node( + Rc::new(ExprData::ExprListLit), + typed_elements.clone(), + Some(Rc::new(InferredNode::Resolved { + node: list_k.ty.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: ll_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat(elem_diags.clone(), empty_list_diags.clone()), + list_k.miss_diags.clone(), + ), + }) + } + ExprData::ExprBinOp { op, .. } => { + let span = texpr.span.clone(); + let left_expr = binop_left(texpr.clone()); + let right_expr = binop_right(texpr.clone()); + let left_result = infer_expr(left_expr.clone(), scope.clone(), None); + let left_typed = left_result.typed.clone(); + let left_diags = left_result.diagnostics.clone(); + let right_result = infer_expr(right_expr.clone(), scope.clone(), None); + let right_typed = right_result.typed.clone(); + let right_diags = right_result.diagnostics.clone(); + let binop_info = infer_binop_type_node( + op.clone(), + resolved_type(left_typed.clone()), + scope.type_env.clone().source_indices.clone(), + ); + let bo_texpr = make_expr_node( + Rc::new(ExprData::ExprBinOp { + op: op.clone(), + algebra_field: binop_info.algebra_field.clone(), + }), + Rc::new(vec![left_typed.clone(), right_typed.clone()]), + Some(Rc::new(InferredNode::Resolved { + node: binop_info.result_type.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: bo_texpr.clone(), + diagnostics: v1_rt::concat(left_diags.clone(), right_diags.clone()), + }) + } + ExprData::ExprUnaryOp { op: op, .. } => { + let span = texpr.span.clone(); + let operand_expr = unaryop_operand(texpr.clone()); + let operand_result = infer_expr(operand_expr.clone(), scope.clone(), None); + let operand_typed = operand_result.typed.clone(); + let operand_diags = operand_result.diagnostics.clone(); + let result_type = match op.clone() { + UnaryOpKind::Not => bool_type(), + UnaryOpKind::Neg => resolved_type(operand_typed.clone()), + }; + let uo_texpr = make_expr_node( + Rc::new(ExprData::ExprUnaryOp { op: op.clone() }), + Rc::new(vec![operand_typed.clone()]), + Some(Rc::new(InferredNode::Resolved { + node: result_type.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: uo_texpr.clone(), + diagnostics: operand_diags.clone(), + }) + } + ExprData::ExprLambda => { + let span = texpr.span.clone(); + let lam_body = lambda_body(texpr.clone()); + let lam_params = + lambda_param_names_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let lam_param_nodes = Rc::new( + texpr + .children + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + let elem_prov = + match v1_rt::map_get(&scope.lambda_param_provenance.clone(), "elem".to_string()) { + Some(p) => p.clone(), + None => Rc::new(SubValueRelation::SubValueUnknown), + }; + let lam_scope = if (expected.clone() != None) { + { + let exp = expected.clone().unwrap(); + if ((exp.params.clone().len() as i64) > 0) { + Rc::new( + lam_params + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + scope.clone(), + |acc: Rc, pair: (i64, String)| { + let param_prov = if (pair.0.clone() + == ((lam_params.clone().len() as i64) - 1)) + { + elem_prov.clone() + } else { + Rc::new(SubValueRelation::SubValueUnknown) + }; + match exp + .params + .clone() + .iter() + .cloned() + .skip(pair.0.clone() as usize) + .next() + { + Some(cp) => extend_scope( + acc.clone(), + pair.1.clone(), + param_node_type_expr(cp.clone()), + param_prov.clone(), + ), + None => extend_scope( + acc.clone(), + pair.1.clone(), + type_variable_node("callable_param".to_string()), + param_prov.clone(), + ), + } + }, + ) + } else { + if ((lam_params.clone().len() as i64) == 1) { + match lam_params.clone().first().cloned() { + Some(p) => extend_scope( + scope.clone(), + p.clone(), + exp.clone(), + elem_prov.clone(), + ), + None => scope.clone(), + } + } else { + Rc::new( + lam_params + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + scope.clone(), + |acc: Rc, pair: (i64, String)| { + let param_prov = if (pair.0.clone() + == ((lam_params.clone().len() as i64) - 1)) + { + elem_prov.clone() + } else { + Rc::new(SubValueRelation::SubValueUnknown) + }; + if (pair.0.clone() == ((lam_params.clone().len() as i64) - 1)) { + extend_scope( + acc.clone(), + pair.1.clone(), + exp.clone(), + param_prov.clone(), + ) + } else { + extend_scope( + acc.clone(), + pair.1.clone(), + type_variable_node("lambda_param".to_string()), + param_prov.clone(), + ) + } + }, + ) + } + } + } + } else { + extend_scope_with_params(scope.clone(), lam_params.clone()) + }; + let body_expected = if (expected.clone() != None) { + { + let exp = expected.clone().unwrap(); + if ((exp.params.clone().len() as i64) > 0) { + { + let declared_ret = resolved_type(exp.clone()); + if is_fully_resolved( + declared_ret.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(declared_ret.clone()) + } else { + None + } + } + } else { + None + } + } + } else { + None + }; + let body_scope = Rc::new(InferScope { + type_env: lam_scope.type_env.clone(), + func_env: lam_scope.func_env.clone(), + locals: lam_scope.locals.clone(), + body_locals: lam_scope.body_locals.clone(), + match_bound_names: lam_scope.match_bound_names.clone(), + module_name: lam_scope.module_name.clone(), + service_registry: lam_scope.service_registry.clone(), + item_registry: lam_scope.item_registry.clone(), + caller_decl_name: lam_scope.caller_decl_name.clone(), + lambda_param_provenance: v1_rt::rc_empty_map::>(), + }); + let body_result = + infer_expr(lam_body.clone(), body_scope.clone(), body_expected.clone()); + let body_typed = body_result.typed.clone(); + let body_diags = body_result.diagnostics.clone(); + let typed_param_nodes = Rc::new({ + let mut __result = Vec::new(); + for pair in Rc::new( + lam_param_nodes + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.push({ + let pn = pair.1.clone(); + let param_name = match lam_params + .clone() + .iter() + .cloned() + .skip(pair.0.clone() as usize) + .next() + { + Some(n) => n.clone(), + None => "".to_string(), + }; + let param_type = + match v1_rt::map_get(&lam_scope.locals.clone(), param_name.clone()) { + Some(binding) => Some(Rc::new(InferredNode::Resolved { + node: binding.resolved.clone(), + })), + None => None, + }; + Rc::new(Node { + name: pn.name.clone(), + ident: pn.ident.clone(), + span: pn.span.clone(), + ident_span: pn.ident_span.clone(), + children: pn.children.clone(), + connective: pn.connective.clone(), + params: pn.params.clone(), + inferred: param_type.clone(), + return_cardinality: pn.return_cardinality.clone(), + uses: pn.uses.clone(), + body: pn.body.clone(), + transport: pn.transport.clone(), + properties: pn.properties.clone(), + type_annotation: pn.type_annotation.clone(), + is_self_recursive: pn.is_self_recursive.clone(), + has_non_tail_self_call: pn.has_non_tail_self_call.clone(), + match_pattern: pn.match_pattern.clone(), + expr_data: pn.expr_data.clone(), + }) + }); + } + __result + }); + let lam_texpr = make_expr_node( + Rc::new(ExprData::ExprLambda), + v1_rt::concat(Rc::new(vec![body_typed.clone()]), typed_param_nodes.clone()), + body_typed.inferred.clone(), + span.clone(), + ); + Rc::new(InferResult { + typed: lam_texpr.clone(), + diagnostics: body_diags.clone(), + }) + } + ExprData::ExprStringInterp => { + let span = texpr.span.clone(); + let typed_part_nodes = Rc::new({ + let mut __result = Vec::new(); + for part_node in texpr.children.clone().iter().cloned() { + __result.push(match (*part_node.expr_data.clone()).clone() { + ExprData::ExprLiteral { value: _, .. } => part_node.clone(), + _ => match part_node.children.clone().first().cloned() { + Some(inner) => { + let r = infer_expr(inner.clone(), scope.clone(), None); + make_interp_part_node(r.typed.clone(), part_node.span.clone()) + } + None => part_node.clone(), + }, + }); + } + __result + }); + let interp_diags = Rc::new({ + let mut __result = Vec::new(); + for part_node in texpr.children.clone().iter().cloned() { + __result.extend( + (*match (*part_node.expr_data.clone()).clone() { + ExprData::ExprLiteral { value: _, .. } => Rc::new(vec![]), + _ => match part_node.children.clone().first().cloned() { + Some(inner) => { + let r = infer_expr(inner.clone(), scope.clone(), None); + r.diagnostics.clone() + } + None => Rc::new(vec![]), + }, + }) + .iter() + .cloned(), + ); + } + __result + }); + let si_texpr = make_expr_node( + Rc::new(ExprData::ExprStringInterp), + typed_part_nodes.clone(), + Some(Rc::new(InferredNode::Resolved { + node: string_type(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: si_texpr.clone(), + diagnostics: interp_diags.clone(), + }) + } + ExprData::ExprBlock => { + let span = texpr.span.clone(); + let stmts = texpr.children.clone(); + if ((stmts.clone().len() as i64) > 0) { + { + let state = infer_block_stmts( + stmts.clone(), + (stmts.clone().len() as i64), + scope.clone(), + Rc::new(vec![]), + Rc::new(vec![]), + unit_type(), + expected.clone(), + ); + let blk_texpr = make_expr_node( + Rc::new(ExprData::ExprBlock), + state.typed_stmts.clone(), + Some(Rc::new(InferredNode::Resolved { + node: state.last_type.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: blk_texpr.clone(), + diagnostics: Rc::new({ + let mut __result = Vec::new(); + for c in state.diag_chunks.clone().iter().cloned() { + __result.extend((*c.clone()).iter().cloned()); + } + __result + }), + }) + } + } else { + ok_infer(make_expr_node( + Rc::new(ExprData::ExprBlock), + Rc::new(vec![]), + Some(Rc::new(InferredNode::Resolved { node: unit_type() })), + span.clone(), + )) + } + } + ExprData::ExprCast => { + let span = texpr.span.clone(); + let cast_inner = cast_expr(texpr.clone()); + let target_type = cast_target(texpr.clone()); + let inner_result = infer_expr(cast_inner.clone(), scope.clone(), None); + let inner_typed = inner_result.typed.clone(); + let inner_diags = inner_result.diagnostics.clone(); + let si = scope.type_env.clone().source_indices.clone(); + let target_name = authored_name_at(si.clone(), target_type.clone()); + let cast_diag = validate_cast( + inner_typed.inferred.clone(), + target_name.clone(), + span.clone(), + si.clone(), + scope.module_name.clone(), + ); + let cast_diags = match cast_diag.clone() { + Some(d) => Rc::new(vec![d.clone()]), + None => Rc::new(vec![]), + }; + let cast_optional_diags = optional_cast_diags( + inner_typed.inferred.clone(), + target_type.clone(), + span.clone(), + si.clone(), + scope.module_name.clone(), + ); + let cast_sole_ctor_diags = sole_constructor_construction_diags( + target_name.clone(), + span.clone(), + scope.clone(), + ); + let cast_refinement_diags = where_refinement_mismatch_diags( + target_type.clone(), + inner_typed.clone(), + span.clone(), + scope.module_name.clone(), + scope.type_env.clone(), + ); + let cast_texpr = make_expr_node( + Rc::new(ExprData::ExprCast), + Rc::new(vec![inner_typed.clone(), target_type.clone()]), + Some(Rc::new(InferredNode::Resolved { + node: target_type.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: cast_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat(inner_diags.clone(), cast_diags.clone()), + cast_optional_diags.clone(), + ), + cast_sole_ctor_diags.clone(), + ), + cast_refinement_diags.clone(), + ), + }) + } + ExprData::ExprForEach => { + let variable = + foreach_variable_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); + let span = texpr.span.clone(); + let coll = foreach_collection(texpr.clone()); + let body_expr = foreach_body(texpr.clone()); + let coll_result = infer_expr(coll.clone(), scope.clone(), None); + let coll_typed = coll_result.typed.clone(); + let coll_diags = coll_result.diagnostics.clone(); + let elem_type_node = for_each_element_type_node( + resolved_type(coll_typed.clone()), + scope.type_env.clone().source_indices.clone(), + ); + let elem_provenance = derive_element_provenance( + coll_typed.clone(), + elem_type_node.clone(), + scope.clone(), + ); + let body_scope = extend_scope( + scope.clone(), + variable.clone(), + elem_type_node.clone(), + elem_provenance.clone(), + ); + let body_result = infer_expr(body_expr.clone(), body_scope.clone(), None); + let body_typed = body_result.typed.clone(); + let body_diags = body_result.diagnostics.clone(); + let fe_texpr = make_named_expr_node( + variable.clone(), + Rc::new(ExprData::ExprForEach), + Rc::new(vec![coll_typed.clone(), body_typed.clone()]), + body_typed.inferred.clone(), + span.clone(), + node_name_span(texpr.clone()), + ); + Rc::new(InferResult { + typed: fe_texpr.clone(), + diagnostics: v1_rt::concat(coll_diags.clone(), body_diags.clone()), + }) + } + ExprData::ExprIndex => { + let span = texpr.span.clone(); + let base_expr = index_base(texpr.clone()); + let idx_key = index_expr(texpr.clone()); + let base_result = infer_expr(base_expr.clone(), scope.clone(), None); + let base_typed = base_result.typed.clone(); + let base_diags = base_result.diagnostics.clone(); + let index_result = infer_expr(idx_key.clone(), scope.clone(), None); + let index_typed = index_result.typed.clone(); + let index_diags = index_result.diagnostics.clone(); + let index_check = match base_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: base_type, .. + }) => match index_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: index_type, .. + }) => Some(check_index_access_node( + base_type.clone(), + index_type.clone(), + span.clone(), + scope.module_name.clone(), + scope.type_env.clone().source_indices.clone(), + )), + _ => None, + }, + _ => None, + }; + let access_failure_inferred = match base_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: _, .. }) => index_typed.inferred.clone(), + _ => base_typed.inferred.clone(), + }; + let idx_inferred = match index_check.clone() { + Some(checked) => checked.inferred.clone(), + None => Some(inferred_or_error( + access_failure_inferred.clone(), + "invalid index access".to_string(), + span.clone(), + )), + }; + let index_access_diags = match index_check.clone() { + Some(checked) => checked.diagnostics.clone(), + None => Rc::new(vec![]), + }; + let idx_texpr = make_expr_node( + Rc::new(ExprData::ExprIndex), + Rc::new(vec![base_typed.clone(), index_typed.clone()]), + idx_inferred.clone(), + span.clone(), + ); + Rc::new(InferResult { + typed: idx_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat(base_diags.clone(), index_diags.clone()), + index_access_diags.clone(), + ), + }) + } + ExprData::ExprSlice => { + let span = texpr.span.clone(); + let base_expr = slice_base(texpr.clone()); + let start_expr = slice_start(texpr.clone()); + let end_expr = slice_end(texpr.clone()); + let base_result = infer_expr(base_expr.clone(), scope.clone(), None); + let base_typed = base_result.typed.clone(); + let base_diags = base_result.diagnostics.clone(); + let start_result = infer_expr(start_expr.clone(), scope.clone(), None); + let start_typed = start_result.typed.clone(); + let start_diags = start_result.diagnostics.clone(); + let end_result = infer_expr(end_expr.clone(), scope.clone(), None); + let end_typed = end_result.typed.clone(); + let end_diags = end_result.diagnostics.clone(); + let slice_check = match base_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: base_type, .. + }) => match start_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: start_type, .. + }) => match end_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: end_type, .. }) => { + Some(check_slice_access_node( + base_type.clone(), + start_type.clone(), + end_type.clone(), + span.clone(), + scope.module_name.clone(), + scope.type_env.clone().source_indices.clone(), + )) + } + _ => None, + }, + _ => None, + }, + _ => None, + }; + let access_failure_inferred = match base_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: _, .. }) => { + match start_typed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: _, .. }) => end_typed.inferred.clone(), + _ => start_typed.inferred.clone(), + } + } + _ => base_typed.inferred.clone(), + }; + let slc_inferred = match slice_check.clone() { + Some(checked) => checked.inferred.clone(), + None => Some(inferred_or_error( + access_failure_inferred.clone(), + "invalid slice access".to_string(), + span.clone(), + )), + }; + let slice_access_diags = match slice_check.clone() { + Some(checked) => checked.diagnostics.clone(), + None => Rc::new(vec![]), + }; + let slc_texpr = make_expr_node( + Rc::new(ExprData::ExprSlice), + Rc::new(vec![ + base_typed.clone(), + start_typed.clone(), + end_typed.clone(), + ]), + slc_inferred.clone(), + span.clone(), + ); + Rc::new(InferResult { + typed: slc_texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat(base_diags.clone(), start_diags.clone()), + end_diags.clone(), + ), + slice_access_diags.clone(), + ), + }) + } + ExprData::ExprReturn => { + let span = texpr.span.clone(); + let inner_expr = return_value(texpr.clone()); + let inner_result = infer_expr(inner_expr.clone(), scope.clone(), expected.clone()); + let ret_texpr = make_expr_node( + Rc::new(ExprData::ExprReturn), + Rc::new(vec![inner_result.typed.clone()]), + inner_result.typed.clone().inferred.clone(), + span.clone(), + ); + Rc::new(InferResult { + typed: ret_texpr.clone(), + diagnostics: inner_result.diagnostics.clone(), + }) + } + _ => { + let span = texpr.span.clone(); + Rc::new(InferResult { + typed: make_expr_error_node( + ExprErrorKind::InternalExprError, + "unhandled expression variant in infer_expr".to_string(), + span.clone(), + ), + diagnostics: Rc::new(vec![inference_error( + "unhandled expression variant in infer_expr".to_string(), + span.clone(), + scope.module_name.clone(), + )]), + }) + } + } +} + +pub fn infer_variant_constructor_call( + func_name: String, + call_args: Rc>>, + span: Rc, + name_span: Rc, + scope: Rc, +) -> Option> { + match lookup_variant_parent_enum(scope.clone(), func_name.clone()) { + None => None, + Some(parent_enum) => { + let si = scope.type_env.clone().source_indices.clone(); + match lookup_type_by_name(scope.type_env.clone(), parent_enum.clone()) { + Some(parent_node) => { + match find_child_named(parent_node.clone(), func_name.clone(), si.clone()) { + Some(variant_node) => { + if variant_has_positional_payload_shape( + variant_node.clone(), + si.clone(), + ) { + if ((call_args.clone().len() as i64) == 1) { + match call_args.clone().first().cloned() { + Some(arg) => match arg_name_at(arg.clone(), si.clone()) { + Some(arg_name) => { + let msg = v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat("positional variant constructor '".to_string(), func_name.clone()), "' does not accept named arguments (got '".to_string()), arg_name.clone()), ": ...')".to_string()); + Some(Rc::new(InferResult { + typed: semantic_expr_error_node( + msg.clone(), + arg.span.clone(), + ), + diagnostics: Rc::new(vec![inference_error( + msg.clone(), + arg.span.clone(), + scope.module_name.clone(), + )]), + })) + } + None => { + let payload_expr = arg_value(arg.clone()); + let payload_init = make_field_init_node( + "0".to_string(), + payload_expr.clone(), + payload_expr.span.clone(), + kernel_span("0".to_string()), + ); + Some(infer_record_lit( + Some(func_name.clone()), + Rc::new(vec![payload_init.clone()]), + span.clone(), + name_span.clone(), + scope.clone(), + None, + )) + } + }, + None => None, + } + } else { + { + let arity_msg = v1_rt::concat( + v1_rt::concat( + "positional variant constructor '".to_string(), + func_name.clone(), + ), + "' expects exactly one argument".to_string(), + ); + Some(Rc::new(InferResult { + typed: semantic_expr_error_node( + arity_msg.clone(), + span.clone(), + ), + diagnostics: Rc::new(vec![inference_error( + arity_msg.clone(), + span.clone(), + scope.module_name.clone(), + )]), + })) + } + } + } else { + None + } + } + None => None, + } + } + None => None, + } + } + } +} + +pub fn is_deferred_field_access_base(n: Rc, env: Rc) -> bool { + if ((n.inferred.clone() != None) && is_type_variable(n.inferred.clone().clone().unwrap())) { + true + } else { + if (((n.connective.clone() == Connective::NoConnective) + && ((n.children.clone().len() as i64) == 0)) + && (n.inferred.clone() == None)) + { + { + let name = authored_name_at(env.source_indices.clone(), n.clone()); + match lookup_type_by_name(env.clone(), name.clone()) { + Some(decl) => ((decl.params.clone().len() as i64) > 0), + None => false, + } + } + } else { + false + } + } +} + +pub fn needs_alias_field_expansion(n: Rc, env: Rc) -> bool { + if is_deferred_field_access_base(n.clone(), env.clone()) { + false + } else { + if ((n.connective.clone() == Connective::Conj) + || (n.connective.clone() == Connective::Disj)) + { + false + } else { + if (((n.connective.clone() == Connective::NoConnective) + && ((n.children.clone().len() as i64) > 0)) + && (n.inferred.clone() == None)) + { + is_user_generic_use_site(n.clone(), env.clone()) + } else { + match lookup_type_for(env.clone(), n.clone()) { + Some(binding) => { + if ((binding.connective.clone() == Connective::Conj) + || (binding.connective.clone() == Connective::Disj)) + { + ((n.connective.clone() == Connective::NoConnective) + && ((n.children.clone().len() as i64) == 0)) + } else { + if (((binding.connective.clone() == Connective::NoConnective) + && ((binding.children.clone().len() as i64) == 0)) + && (binding.inferred.clone() != None)) + { + true + } else { + if ((binding.connective.clone() == Connective::NoConnective) + && ((binding.children.clone().len() as i64) > 0)) + { + (is_user_generic_use_site(binding.clone(), env.clone()) + || (binding.inferred.clone() != None)) + } else { + false + } + } + } + } + None => false, + } + } + } + } +} + +pub fn call_locals_shadow_note() -> String { + thread_local! { + static CACHED: String = { + "Body-scope binders shadow the fn-sig lookup in the ExprCall arm (nearest-first precedence: body locals > module fns > census global_bare). Without this gate a corpus-unique census homonym out-precedes a `let` callee: refinement.dag's `let classify = by.classify; match classify(base)` typed the scrutinee as a v2 lens test module's `fn classify -> Optional`, refusing the match arms against the wrong enum (variant not found in Optional + non-exhaustive missing Absent/Present). The gate reads body_locals — the strict body-grain subset (let / match pattern / fn+lambda params) of scope.locals — because the module context pre-seeds locals with variant and service census bindings that must NOT eclipse fn sigs (an imported 0-arg fn would lose its sig to its own census row: html_fragment.dag's html_markup_medium() typed as an unresolved primitive). Absent sends the call down the local-callable path exactly as the pre-census seed did. Companion precedence law lives in func_sig_from_global_bare (infer_lookup): the census fallback never serves an algebra method-template name (filter/any/contains/…) — a whole-pool census entry for the UNLOADED v2.std.algebra must not preempt the known-method bridge (main-parity: on main such free calls type through the bridge; a census-served sig typed filter(xs, f) as a plain call to a never-loaded module and the runtime died NoSuchFunction).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn peel_alias_fixpoint_guard_note() -> String { + thread_local! { + static CACHED: String = { + "Termination (§4 boundedness) and diagnostic completeness (§5): peel iterates resolve_node toward a groundable form; a node that resolves to ITSELF (a self-resolving generic constructor such as List — NoConnective, children>0, inferred=none, unbound-or-identity under resolve) is a resolve FIXED POINT, the expansion frontier. Without the once==n check the recurse arm loops forever on that shape (measured: one peel call spun 3M+ iterations / 396M resolve calls on the #6640 total-census tree, witness test.claim.bmc_bootstrap_provision_witness, fp trace c1f861179e→d33138c3f8→256ee7d351 repeating — progress-then-self-loop, no >1-cycle, so consecutive-equal suffices; a memo cannot terminate it, only make each spin fast). The fixed-point/non-alias arm is a legitimate speculative probe miss ONLY when resolve_node returns no diagnostics. The old Node return projected .resolved and discarded .diagnostics, making that quiet miss byte-identical to a real resolver refusal and zeroing the refusal's frequency before CompileResult, compile-clean, and the diagnostic census could observe it. The peel now returns the existing NodeResolveResult authority and accumulates every hop's diagnostics. ExprFieldAccess and record-literal alias field discovery are judgment-producing callers and must carry those diagnostics. Variant-membership and emit-shaping callers are metadata-only probes: they may inspect .resolved but do not admit an executable artifact or own a diagnostic ledger, so making them emit would turn speculative shape lookup into a false red. No second peel outcome vocabulary is minted beside the resolver's own typed carrier.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn peel_alias_once_for_field_access( + n: Rc, + env: Rc, + module_name: String, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + let once = resolve_node(n.clone(), env.clone(), module_name.clone()); + let resolved_once = once.resolved.clone(); + if ((resolved_once.connective.clone() == Connective::Conj) + || (resolved_once.connective.clone() == Connective::Disj)) + { + once + } else { + if (((resolved_once.connective.clone() == Connective::NoConnective) + && ((resolved_once.children.clone().len() as i64) > 0)) + && (resolved_once.inferred.clone() == None)) + { + if (resolved_once.clone() == n.clone()) { + once + } else { + { + let rest = peel_alias_once_for_field_access( + resolved_once.clone(), + env.clone(), + module_name.clone(), + ); + Rc::new(NodeResolveResult { + resolved: rest.resolved.clone(), + diagnostics: v1_rt::concat( + once.diagnostics.clone(), + rest.diagnostics.clone(), + ), + }) + } + } + } else { + once + } + } + }) +} + +pub fn structural_from_expanded_type(normed: Rc) -> Rc { + match normed.connective.clone() { + Connective::Conj => normed, + Connective::Disj => normed, + _ => match normed.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: target, .. }) => match target.connective.clone() { + Connective::Conj => target.clone(), + Connective::Disj => target.clone(), + _ => normed, + }, + _ => normed, + }, + } +} + +pub fn record_field_type_is_unresolved_param( + field: Rc, + param_names: Rc>, + env: Rc, +) -> bool { + match product_field_result_type(field.clone()) { + Some(ft) => { + if ((ft.connective.clone() == Connective::NoConnective) + && ((ft.children.clone().len() as i64) == 0)) + { + match ft.inferred.clone() { + Some(inf) => is_type_variable(inf.clone()), + None => { + let fname = authored_name_at(env.source_indices.clone(), ft.clone()); + let in_params = { + let mut __found = false; + for pn in param_names.clone().iter().cloned() { + if (pn.clone() == fname.clone()) { + __found = true; + break; + } + } + __found + }; + let conv = is_type_variable_name(fname.clone()); + (in_params.clone() || conv.clone()) + } + } + } else { + false + } + } + None => false, + } +} + +pub fn record_has_unresolved_param_field(record: Rc, env: Rc) -> bool { + { + let param_names = Rc::new({ + let mut __result = Vec::new(); + for p in record.params.clone().iter().cloned() { + __result.push(generic_param_name_at(p.clone(), env.source_indices.clone())); + } + __result + }); + { + let mut __found = false; + for f in record.children.clone().iter().cloned() { + if record_field_type_is_unresolved_param( + f.clone(), + param_names.clone(), + env.clone(), + ) { + __found = true; + break; + } + } + __found + } + } +} + +pub fn alias_chain_generic_decl(env: Rc, carrier: Rc, target: Rc) -> Rc { + if ((target.params.clone().len() as i64) > 0) { + target + } else { + resolve_generic_use_decl(env.clone(), carrier.clone()) + } +} + +pub fn alias_chain_type_arg_subst( + env: Rc, + carrier: Rc, + target: Rc, + type_args: Rc>>, +) -> Rc>> { + { + let decl = alias_chain_generic_decl(env.clone(), carrier.clone(), target.clone()); + Rc::new( + decl.params + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, pair: (i64, Rc)| { + let slot = generic_param_name_at(pair.1.clone(), env.source_indices.clone()); + match type_args + .clone() + .iter() + .cloned() + .skip(pair.0.clone() as usize) + .next() + { + Some(arg) => v1_rt::rc_map_insert( + acc.clone(), + slot.clone(), + resolve_scrutinee_type_node(env.clone(), arg.clone()), + ), + None => acc.clone(), + } + }, + ) + } +} + +pub fn alias_chain_target_after_args( + target: Rc, + carrier: Rc, + env: Rc, +) -> Rc { + { + let type_args = carrier.children.clone(); + if ((type_args.clone().len() as i64) == 0) { + target.clone() + } else { + { + let decl = alias_chain_generic_decl(env.clone(), carrier.clone(), target.clone()); + let subst = alias_chain_type_arg_subst( + env.clone(), + carrier.clone(), + target.clone(), + type_args.clone(), + ); + let is_parameterized_alias = (((decl.inferred.clone() != None) + && ((decl.children.clone().len() as i64) == 0)) + && (decl.connective.clone() == Connective::NoConnective)); + if is_parameterized_alias.clone() { + match decl.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: alias_body, .. + }) => substitute_generics( + alias_body.clone(), + subst.clone(), + env.source_indices.clone(), + ), + _ => target.clone(), + } + } else { + substitute_generics(decl.clone(), subst.clone(), env.source_indices.clone()) + } + } + } + } +} + +pub fn alias_chain_carrier(n: Rc) -> Rc { + if ((n.connective.clone() == Connective::NoConnective) && (n.name.clone() != "".to_string())) { + n + } else { + structural_from_expanded_type(n) + } +} + +pub fn expand_alias_chain_for_field_access( + n: Rc, + env: Rc, + module_name: String, + origin_name: String, + seen: Rc>, + lossy: bool, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + let peel_result = if needs_alias_field_expansion(n.clone(), env.clone()) { + peel_alias_once_for_field_access(n.clone(), env.clone(), module_name.clone()) + } else { + Rc::new(NodeResolveResult { + resolved: n.clone(), + diagnostics: Rc::new(vec![]), + }) + }; + let peeled = peel_result.resolved.clone(); + let carrier = alias_chain_carrier(peeled.clone()); + let carrier_name = if (carrier.name.clone() != "".to_string()) { + carrier.name.clone() + } else { + authored_name_at(env.source_indices.clone(), carrier.clone()) + }; + let structural = + structural_from_expanded_type(resolve_scrutinee_type_node(env.clone(), peeled.clone())); + let is_record = ((structural.connective.clone() == Connective::Conj) + || (structural.connective.clone() == Connective::Disj)); + if is_record.clone() { + { + let resolved_record = + if ((record_has_unresolved_param_field(structural.clone(), env.clone()) + && ((carrier.children.clone().len() as i64) > 0)) + && (carrier_name.clone() != "".to_string())) + { + match lookup_type_by_name(env.clone(), carrier_name.clone()) { + Some(target) => { + let subst = alias_chain_type_arg_subst( + env.clone(), + carrier.clone(), + target.clone(), + carrier.children.clone(), + ); + substitute_generics( + structural.clone(), + subst.clone(), + env.source_indices.clone(), + ) + } + None => structural.clone(), + } + } else { + structural.clone() + }; + let fail_closed = (lossy.clone() + && record_has_unresolved_param_field(resolved_record.clone(), env.clone())); + if fail_closed.clone() { + Rc::new(NodeResolveResult { + resolved: nominal_type_ref(origin_name.clone()), + diagnostics: peel_result.diagnostics.clone(), + }) + } else { + Rc::new(NodeResolveResult { + resolved: resolved_record.clone(), + diagnostics: peel_result.diagnostics.clone(), + }) + } + } + } else { + { + let next_name = carrier_name.clone(); + let is_optional = + (structural.return_cardinality.clone() == Cardinality::CardOptional); + if is_optional.clone() { + { + let expanded_inner = expand_alias_chain_for_field_access( + with_required_cardinality(structural.clone()), + env.clone(), + module_name.clone(), + origin_name.clone(), + seen.clone(), + lossy.clone(), + ); + Rc::new(NodeResolveResult { + resolved: with_optional_cardinality(expanded_inner.resolved.clone()), + diagnostics: v1_rt::concat( + peel_result.diagnostics.clone(), + expanded_inner.diagnostics.clone(), + ), + }) + } + } else { + { + let stop = ((next_name.clone() == "".to_string()) + || emit_map_has(seen.clone(), next_name.clone())); + if stop.clone() { + Rc::new(NodeResolveResult { + resolved: structural.clone(), + diagnostics: peel_result.diagnostics.clone(), + }) + } else { + match lookup_type_by_name(env.clone(), next_name.clone()) { + Some(target) => { + let next_seen = + v1_rt::rc_map_insert(seen.clone(), next_name.clone(), true); + let type_arg_count = (carrier.children.clone().len() as i64); + let decl = alias_chain_generic_decl( + env.clone(), + carrier.clone(), + target.clone(), + ); + let param_count = (decl.params.clone().len() as i64); + let dropped_args = (((type_arg_count.clone() > 0) + && (param_count.clone() > 0)) + && (param_count.clone() != type_arg_count.clone())); + let next_lossy = (lossy.clone() || dropped_args.clone()); + let next_n = if ((type_arg_count.clone() > 0) + && !dropped_args.clone()) + { + alias_chain_target_after_args( + target.clone(), + carrier.clone(), + env.clone(), + ) + } else { + target.clone() + }; + let expanded_next = expand_alias_chain_for_field_access( + next_n.clone(), + env.clone(), + module_name.clone(), + origin_name.clone(), + next_seen.clone(), + next_lossy.clone(), + ); + Rc::new(NodeResolveResult { + resolved: expanded_next.resolved.clone(), + diagnostics: v1_rt::concat( + peel_result.diagnostics.clone(), + expanded_next.diagnostics.clone(), + ), + }) + } + None => Rc::new(NodeResolveResult { + resolved: structural.clone(), + diagnostics: peel_result.diagnostics.clone(), + }), + } + } + } + } + } + } + }) +} + +pub fn expand_type_for_field_access_with_seen( + n: Rc, + env: Rc, + module_name: String, + seen: Rc>, +) -> Rc { + if is_deferred_field_access_base(n.clone(), env.clone()) { + Rc::new(NodeResolveResult { + resolved: n.clone(), + diagnostics: Rc::new(vec![]), + }) + } else { + { + let origin_name = authored_name_at(env.source_indices.clone(), n.clone()); + expand_alias_chain_for_field_access( + n.clone(), + env.clone(), + module_name.clone(), + origin_name.clone(), + seen.clone(), + false, + ) + } + } +} + +pub fn expand_type_for_field_access( + n: Rc, + env: Rc, + module_name: String, +) -> Rc { + expand_type_for_field_access_with_seen( + n.clone(), + env.clone(), + module_name.clone(), + v1_rt::rc_empty_map::(), + ) +} + +pub fn record_lit_alias_struct_expansion( + type_name: String, + scope: Rc, +) -> Option> { + match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { + Some(decl) => { + let to_expand = if (((decl.connective.clone() == Connective::NoConnective) + && ((decl.children.clone().len() as i64) == 0)) + && (decl.inferred.clone() != None)) + { + match decl.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: target, .. }) => target.clone(), + _ => decl.clone(), + } + } else { + decl.clone() + }; + Some(expand_type_for_field_access( + to_expand.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + )) + } + None => None, + } +} + +pub fn record_lit_construction_field_names( + type_name: String, + scope: Rc, +) -> Option>> { + { + let si = scope.type_env.clone().source_indices.clone(); + match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { + Some(decl) => { + if ((((decl.params.clone().len() as i64) == 0) + && (decl.connective.clone() == Connective::Conj)) + && ((decl.children.clone().len() as i64) > 0)) + { + Some(Rc::new({ + let mut __result = Vec::new(); + for f in decl.children.clone().iter().cloned() { + __result.push(authored_name_at(si.clone(), f.clone())); + } + __result + })) + } else { + None + } + } + None => None, + } + } +} + +pub fn field_in_any_variant_named(type_name: String, field: String, scope: Rc) -> bool { + { + let si = scope.type_env.clone().source_indices.clone(); + match variant_owner_node(scope.clone(), type_name.clone()) { + Some(owner) => { + let mut __found = false; + for arm in owner.children.clone().iter().cloned() { + if if (authored_name_at(si.clone(), arm.clone()) == type_name.clone()) { + { + let ea = expand_type_for_field_access( + arm.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ) + .resolved + .clone(); + let fields = if (ea.connective.clone() == Connective::Conj) { + ea.children.clone() + } else { + arm.children.clone() + }; + { + let mut __found = false; + for f in fields.clone().iter().cloned() { + if (authored_name_at(si.clone(), f.clone()) == field.clone()) { + __found = true; + break; + } + } + __found + } + } + } else { + false + } { + __found = true; + break; + } + } + __found + } + None => false, + } + } +} + +pub fn type_has_sole_constructor(type_name: String, scope: Rc) -> bool { + match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { + Some(decl) => { + let mut __found = false; + for p in decl.properties.clone().iter().cloned() { + if (p.name.clone() == "sole_constructor".to_string()) { + __found = true; + break; + } + } + __found + } + None => false, + } +} + +pub fn sole_constructor_construction_diags( + type_name: String, + span: Rc, + scope: Rc, +) -> Rc>> { + if type_has_sole_constructor(type_name.clone(), scope.clone()) { + match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { + Some(decl) => { + if (decl.span.clone().file.clone() == span.file.clone()) { + Rc::new(vec![]) + } else { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::SoleConstructorViolation { + type_name: type_name.clone(), + span: span.clone(), + }), + scope.module_name.clone(), + )]) + } + } + None => Rc::new(vec![]), + } + } else { + Rc::new(vec![]) + } +} + +pub fn zero_field_variant_tag_reference_frontier_note() -> String { + thread_local! { + static CACHED: String = { + "P0 field-wall frontier (operator Ruling 1a, 2026-07-15): a ZERO-field literal of a coproduct VARIANT (field_inits empty AND variant_owner_node != none) is sanctioned as a TAG REFERENCE, not a construction — the `discriminant(v: PrefixToken {})` idiom (16+ sites in src/v2/std/compilers/target_model.dag) names a variant to obtain its stable tag identity without materializing a value. Presence checking is skipped for exactly this shape; PARTIAL literals (any field present) stay red, and zero-field literals of NON-variant records (variant_owner_node == none) stay red — so the audit F1 probes (CacheProvider/CostAccount partial literals) are unaffected. This is a decidable structural exemption (not an absorbing fallback: it refuses precisely, never widens on failure). DISSOLVE-ON: a first-class variant-tag carrier that types the discriminant argument position, at which point the exemption is deleted and the sites migrate to the carrier.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn presence_check_census_gate_note() -> String { + thread_local! { + static CACHED: String = { + "Field-presence enforcement (P0 wall, #6663) stands down when the literal's bare type name is AMBIGUOUS in the corpus-wide census (global_bare, order-independent): with two same-named decls in the closure, every name-keyed template lookup below resolves by overlay-wins import order (a LEDGERED binding fork, see guarded_cache_union_note), so enforcing would GUESS which decl the author meant and red correct literals against the wrong layer's fields (2026-07-16 main-red: v2 nested Monoid/BooleanAlgebra/OrderedRing literals checked against dag/std flat shapes). Skipping on ambiguity is the pre-wall behavior for exactly those names; enforcement stays live for census-unique names (~98 percent of the corpus) AND for names this module DECLARES LOCALLY. The local carve-out is the one census-ambiguous case that still enforces, and it is read from TypeEnv.str_bindings ONLY: build_type_env sets str_bindings = local_str_bindings (this module's own declarations; the direct-import overlay lands in ancestry_str_bindings), and lookup_binding_by_name_local consults str_bindings FIRST, so a locally-declared name resolves to the local decl deterministically and order-independently - the precedence note's 'locals > kernel > direct-selected > transitive union' with no fork to guess (direct_import_export_precedence_note). The gate must NOT reach lookup_type_by_name here: that walks on into ancestry_str_bindings, i.e. the import-order overlay, which makes the WALL ITSELF order-dependent - the same source text refusing under one import order and passing under the other (reproduced 2026-07-20, target/probe-presencewall ARM SET A: probe.c1 'import a then b' passes while probe.c2 'import b then a' reds on one identical literal), which is exactly the GUESS this gate exists to refuse. Dissolve-on: containment SymbolIndex (namespace lane) makes the expected type scope-resolved; then this gate is dead code and the wall goes total. Ratchet (PR #6709 review, accepted): before the wall goes total, stand-downs become counted out-of-band ledger rows (binding_forks channel shape — LEDGERED, never diagnostics; a red refusal would re-red correct literals), landing with the SymbolIndex work that dissolves this gate.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn map_literal_expected_keyed_node( + type_name: Option, + expected: Option>, + scope: Rc, +) -> Option> { + match type_name.clone() { + Some(_) => None, + None => match expected.clone() { + Some(e) => { + if node_is_keyed_collection( + e.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(e.clone()) + } else { + None + } + } + None => None, + }, + } +} + +pub fn infer_map_literal( + map_node: Rc, + field_inits: Rc>>, + span: Rc, + scope: Rc, +) -> Rc { + { + let value_expected = match map_node + .children + .clone() + .iter() + .cloned() + .skip(1 as usize) + .next() + { + Some(v) => Some(v.clone()), + None => None, + }; + let fi_results = Rc::new({ + let mut __result = Vec::new(); + for fi in field_inits.clone().iter().cloned() { + __result.push({ + let ar = infer_expr( + field_init_node_value(fi.clone()), + scope.clone(), + value_expected.clone(), + ); + Rc::new(FieldInferResult { + typed_field: make_field_init_node( + field_init_node_name_at( + fi.clone(), + scope.type_env.clone().source_indices.clone(), + ), + ar.typed.clone(), + fi.span.clone(), + node_name_span(fi.clone()), + ), + infer_result: ar.clone(), + diagnostics: ar.diagnostics.clone(), + }) + }); + } + __result + }); + Rc::new(InferResult { + typed: make_expr_node( + Rc::new(ExprData::ExprRecordLit { parent_enum: None }), + Rc::new({ + let mut __result = Vec::new(); + for fir in fi_results.clone().iter().cloned() { + __result.push(fir.typed_field.clone()); + } + __result + }), + Some(Rc::new(InferredNode::Resolved { + node: map_node.clone(), + })), + span.clone(), + ), + diagnostics: Rc::new({ + let mut __result = Vec::new(); + for fir in fi_results.clone().iter().cloned() { + __result.extend((*fir.diagnostics.clone()).iter().cloned()); + } + __result + }), + }) + } +} + +pub fn infer_record_lit( + type_name: Option, + field_inits: Rc>>, + span: Rc, + name_span: Rc, + scope: Rc, + expected: Option>, +) -> Rc { + match map_literal_expected_keyed_node(type_name.clone(), expected.clone(), scope.clone()) { + Some(map_node) => infer_map_literal( + map_node.clone(), + field_inits.clone(), + span.clone(), + scope.clone(), + ), + None => infer_record_lit_structural( + type_name.clone(), + field_inits.clone(), + span.clone(), + name_span.clone(), + scope.clone(), + expected.clone(), + ), + } +} + +pub fn infer_record_lit_structural( + type_name: Option, + field_inits: Rc>>, + span: Rc, + name_span: Rc, + scope: Rc, + expected: Option>, +) -> Rc { + { + let instantiated_struct_fields = + record_lit_instantiated_fields(type_name.clone(), expected.clone(), scope.clone()); + let expected_struct_fields = if (instantiated_struct_fields.clone() == None) { + record_lit_fields_from_expected(type_name.clone(), expected.clone(), scope.clone()) + } else { + None + }; + let expected_variant_node = if ((instantiated_struct_fields.clone() == None) + && (expected_struct_fields.clone() == None)) + { + match type_name.clone() { + Some(_) => record_lit_variant_from_expected( + type_name.clone(), + expected.clone(), + scope.clone(), + ), + None => None, + } + } else { + None + }; + let alias_struct_expansion = match type_name.clone() { + Some(tn) => { + if ((((instantiated_struct_fields.clone() == None) + && (expected_struct_fields.clone() == None)) + && (expected_variant_node.clone() == None)) + && (expected.clone() == None)) + { + record_lit_alias_struct_expansion(tn.clone(), scope.clone()) + } else { + None + } + } + None => None, + }; + let struct_fields = match type_name.clone() { + Some(_) => match instantiated_struct_fields.clone() { + Some(fields) => fields.clone(), + None => match expected_struct_fields.clone() { + Some(fields) => fields.clone(), + None => match expected_variant_node.clone() { + Some(variant_node) => variant_node.children.clone(), + None => match expected.clone() { + Some(_) => record_lit_expected_fields(type_name.clone(), scope.clone()), + None => match alias_struct_expansion.clone() { + Some(expansion) => { + if ((expansion.resolved.clone().connective.clone() + == Connective::Conj) + && ((expansion.resolved.clone().children.clone().len() + as i64) + > 0)) + { + expansion.resolved.clone().children.clone() + } else { + record_lit_expected_fields(type_name.clone(), scope.clone()) + } + } + None => { + record_lit_expected_fields(type_name.clone(), scope.clone()) + } + }, + }, + }, + }, + }, + None => match instantiated_struct_fields.clone() { + Some(fields) => fields.clone(), + None => match expected_struct_fields.clone() { + Some(fields) => fields.clone(), + None => record_lit_expected_fields(type_name.clone(), scope.clone()), + }, + }, + }; + let alias_struct_diags = match alias_struct_expansion.clone() { + Some(expansion) => expansion.diagnostics.clone(), + None => Rc::new(vec![]), + }; + let construction_field_names = match type_name.clone() { + Some(tn) => record_lit_construction_field_names(tn.clone(), scope.clone()), + None => None, + }; + let tn_str = match type_name.clone() { + Some(tn) => tn.clone(), + None => "".to_string(), + }; + let si_presence = scope.type_env.clone().source_indices.clone(); + let presence_variant_owner = variant_owner_node(scope.clone(), tn_str.clone()); + let presence_fields = if (tn_str.clone() == "".to_string()) { + Rc::new(vec![]) + } else { + match presence_variant_owner.clone() { + Some(variant_owner) => match Rc::new({ + let mut __result = Vec::new(); + for v in variant_owner.children.clone().iter().cloned() { + if (authored_name_at(si_presence.clone(), v.clone()) + == qualified_last_segment(tn_str.clone())) + { + __result.push(v); + } + } + __result + }) + .first() + .cloned() + { + Some(variant_node) => variant_node.children.clone(), + None => Rc::new(vec![]), + }, + None => match record_lit_variant_from_expected( + type_name.clone(), + expected.clone(), + scope.clone(), + ) { + Some(variant_node) => variant_node.children.clone(), + None => match instantiated_struct_fields.clone() { + Some(inst_fields) => inst_fields.clone(), + None => match lookup_type_by_name(scope.type_env.clone(), tn_str.clone()) { + Some(decl) => { + if (((decl.connective.clone() == Connective::Conj) + && ((decl.params.clone().len() as i64) == 0)) + && ((decl.children.clone().len() as i64) > 0)) + { + decl.children.clone() + } else { + Rc::new(vec![]) + } + } + None => record_lit_expected_fields(type_name.clone(), scope.clone()), + }, + }, + }, + } + }; + let is_zero_field_variant_tag_reference = + (((field_inits.clone().len() as i64) == 0) && (presence_variant_owner.clone() != None)); + let presence_name_is_ambiguous = + (global_bare_is_ambiguous(scope.type_env.clone(), tn_str.clone()) + && (v1_rt::map_get(&scope.type_env.clone().str_bindings.clone(), tn_str.clone()) + == None)); + let presence_ambiguity_refusal_diags = if ((tn_str.clone() != "".to_string()) + && (v1_rt::map_get(&scope.type_env.clone().str_bindings.clone(), tn_str.clone()) + == None)) + { + { + let strict_cands = + global_bare_strict_ambiguity_candidates(scope.type_env.clone(), tn_str.clone()); + if ((strict_cands.clone().len() as i64) > 0) { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::AmbiguousReference { + name: tn_str.clone(), + candidates: strict_cands.clone(), + span: name_span.clone(), + }), + scope.module_name.clone(), + )]) + } else { + Rc::new(vec![]) + } + } + } else { + Rc::new(vec![]) + }; + let missing_field_diags = if ((((tn_str.clone() == "".to_string()) + || ((presence_fields.clone().len() as i64) == 0)) + || is_zero_field_variant_tag_reference.clone()) + || presence_name_is_ambiguous.clone()) + { + Rc::new(vec![]) + } else { + Rc::new({ + let mut __result = Vec::new(); + for sf in Rc::new({ + let mut __result = Vec::new(); + for sf in presence_fields.clone().iter().cloned() { + if { + let sf_type = match sf.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), + _ => field_node_type_expr(sf.clone()), + }; + (((sf_type.return_cardinality.clone() != Cardinality::CardOptional) + && (sf.body.clone() == None)) + && ({ + let mut __found = false; + for fi in field_inits.clone().iter().cloned() { + if (field_init_node_name_at( + fi.clone(), + si_presence.clone(), + ) == authored_name_at(si_presence.clone(), sf.clone())) + { + __found = true; + break; + } + } + __found + } == false)) + } { + __result.push(sf); + } + } + __result + }) + .iter() + .cloned() + { + __result.push(make_error_node( + Rc::new(CompilerDiagnostic::MissingField { + field: authored_name_at(si_presence.clone(), sf.clone()), + type_name: tn_str.clone(), + span: name_span.clone(), + }), + scope.module_name.clone(), + )); + } + __result + }) + }; + let fi_infer_results = Rc::new({ + let mut __result = Vec::new(); + for fi in field_inits.clone().iter().cloned() { + __result.push({ + let fi_name = field_init_node_name_at( + fi.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let unknown_field_diags = match construction_field_names.clone() { + Some(names) => { + if ({ + let mut __found = false; + for n in names.clone().iter().cloned() { + if (n.clone() == fi_name.clone()) { + __found = true; + break; + } + } + __found + } || field_in_any_variant_named( + tn_str.clone(), + fi_name.clone(), + scope.clone(), + )) { + Rc::new(vec![]) + } else { + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::FieldNotFound { + field: fi_name.clone(), + type_name: tn_str.clone(), + span: fi.span.clone(), + }), + scope.module_name.clone(), + )]) + } + } + None => Rc::new(vec![]), + }; + let field_declared_type = match Rc::new({ + let mut __result = Vec::new(); + for sf in struct_fields.clone().iter().cloned() { + if (authored_name_at( + scope.type_env.clone().source_indices.clone(), + sf.clone(), + ) == fi_name.clone()) + { + __result.push(sf); + } + } + __result + }) + .first() + .cloned() + { + Some(sf) => Some(field_declared_type_node(sf.clone())), + None => None, + }; + let field_expected = match field_declared_type.clone() { + Some(ft) => { + if ((((ft.ident_span.clone() != None) + || type_node_is_callable(ft.clone())) + || (ft.return_cardinality.clone() == Cardinality::CardOptional)) + || field_type_is_optional_coproduct( + ft.clone(), + scope.type_env.clone(), + )) + { + Some(ft.clone()) + } else { + None + } + } + None => None, + }; + let ar = infer_expr( + field_init_node_value(fi.clone()), + scope.clone(), + field_expected.clone(), + ); + let ar_typed = ar.typed.clone(); + let ar_diags = ar.diagnostics.clone(); + let field_type_diags = match field_declared_type.clone() { + Some(expected_node) => { + let got_node = resolved_type(ar_typed.clone()); + if rejects_string_for_optional_coproduct_field( + expected_node.clone(), + got_node.clone(), + scope.type_env.clone().source_indices.clone(), + scope.type_env.clone(), + ) { + { + let expected_for_shape = match lookup_type_for( + scope.type_env.clone(), + with_required_cardinality(expected_node.clone()), + ) { + Some(resolved) => resolved.clone(), + None => expected_node.clone(), + }; + Rc::new(vec![type_mismatch_error( + node_type_shape( + expected_for_shape.clone(), + scope.type_env.clone().source_indices.clone(), + ), + node_type_shape( + got_node.clone(), + scope.type_env.clone().source_indices.clone(), + ), + ar_typed.span.clone(), + scope.module_name.clone(), + )]) + } + } else { + { + let expected_required = match lookup_type_for( + scope.type_env.clone(), + with_required_cardinality(expected_node.clone()), + ) { + Some(resolved) => resolved.clone(), + None => with_required_cardinality(expected_node.clone()), + }; + let formal_peeled = peel_nominal_alias_identity( + expected_required.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ); + let actual_peeled = peel_nominal_alias_identity( + got_node.clone(), + scope.type_env.clone(), + scope.module_name.clone(), + ); + if kernel_value_declared_type_mismatch( + formal_peeled.clone(), + actual_peeled.clone(), + scope.type_env.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Rc::new(vec![type_mismatch_error( + node_type_shape( + formal_peeled.clone(), + scope.type_env.clone().source_indices.clone(), + ), + node_type_shape( + actual_peeled.clone(), + scope.type_env.clone().source_indices.clone(), + ), + ar_typed.span.clone(), + scope.module_name.clone(), + )]) + } else { + if structured_application_site_type_mismatch( + expected_node.clone(), + field_init_node_value(fi.clone()), + scope.clone(), + ) { + Rc::new(vec![type_mismatch_error( + node_type_shape( + formal_peeled.clone(), + scope.type_env.clone().source_indices.clone(), + ), + node_type_shape( + actual_peeled.clone(), + scope.type_env.clone().source_indices.clone(), + ), + ar_typed.span.clone(), + scope.module_name.clone(), + )]) + } else { + Rc::new(vec![]) + } + } + } + } + } + None => Rc::new(vec![]), + }; + Rc::new(FieldInferResult { + typed_field: make_field_init_node( + fi_name.clone(), + ar_typed.clone(), + fi.span.clone(), + node_name_span(fi.clone()), + ), + infer_result: ar.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat(ar_diags.clone(), field_type_diags.clone()), + unknown_field_diags.clone(), + ), + bare_none_field_construction_diags( + fi.clone(), + fi_name.clone(), + field_declared_type.clone(), + tn_str.clone(), + scope.clone(), + ), + ), + }) + }); + } + __result + }); + let typed_fields = Rc::new({ + let mut __result = Vec::new(); + for fir in fi_infer_results.clone().iter().cloned() { + __result.push(fir.typed_field.clone()); + } + __result + }); + let fi_diags = Rc::new({ + let mut __result = Vec::new(); + for fir in fi_infer_results.clone().iter().cloned() { + __result.extend((*fir.diagnostics.clone()).iter().cloned()); + } + __result + }); + if (type_name.clone() == None) { + { + let child_nodes = Rc::new({ + let mut __result = Vec::new(); + for fir in fi_infer_results.clone().iter().cloned() { + __result.push(Rc::new(Node { + name: field_init_node_name_at( + fir.typed_field.clone(), + scope.type_env.clone().source_indices.clone(), + ), + span: fir.typed_field.clone().span.clone(), + ident_span: fir.typed_field.clone().ident_span.clone(), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: fir.infer_result.clone().typed.clone().inferred.clone(), + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + })); + } + __result + }); + let anon_node = Rc::new(Node { + name: "".to_string(), + span: no_span(), + ident_span: None, + children: child_nodes.clone(), + connective: Connective::Conj, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let typed_field_nodes = typed_fields.clone(); + let texpr = make_expr_node( + Rc::new(ExprData::ExprRecordLit { parent_enum: None }), + typed_field_nodes.clone(), + Some(Rc::new(InferredNode::Resolved { + node: anon_node.clone(), + })), + span.clone(), + ); + Rc::new(InferResult { + typed: texpr.clone(), + diagnostics: v1_rt::concat(fi_diags.clone(), alias_struct_diags.clone()), + }) + } + } else { + { + let type_lookup = + lookup_type_by_name(scope.type_env.clone(), type_name.clone().unwrap()); + let local_variant_parent = + match lookup_variant_parent_enum(scope.clone(), type_name.clone().unwrap()) { + Some(p) => Some(p.clone()), + None => match variant_owner_node(scope.clone(), type_name.clone().unwrap()) + { + Some(owner) => Some(authored_name_at( + scope.type_env.clone().source_indices.clone(), + owner.clone(), + )), + None => record_lit_parent_enum_from_expected( + type_name.clone().unwrap(), + expected.clone(), + scope.clone(), + ), + }, + }; + let effective_lookup = match type_lookup.clone() { + Some(_) => type_lookup.clone(), + None => { + let local_lookup = + lookup_in_scope(scope.locals.clone(), type_name.clone().unwrap()); + match local_lookup.clone() { + Some(local_node) => { + lookup_type_for(scope.type_env.clone(), local_node.clone()) + } + None => match record_lit_variant_from_expected( + type_name.clone(), + expected.clone(), + scope.clone(), + ) { + Some(_) => { + record_lit_expected_coproduct(expected.clone(), scope.clone()) + } + None => None, + }, + } + } + }; + let variant_lookup_resolved = match effective_lookup.clone() { + Some(tn) => tn.clone(), + None => error_type(), + }; + let type_name_declares_own_type = match lookup_binding_by_name( + scope.type_env.clone(), + type_name.clone().unwrap(), + ) { + Some(name_binding) => binding_declares_name( + name_binding.clone(), + type_name.clone().unwrap(), + scope.type_env.clone().source_indices.clone(), + ), + None => false, + }; + let raw_resolved = match local_variant_parent.clone() { + Some(parent_name) => { + if ((parent_name.clone() == "Optional".to_string()) + || type_name_declares_own_type.clone()) + { + variant_lookup_resolved.clone() + } else { + match lookup_type_by_name(scope.type_env.clone(), parent_name.clone()) { + Some(parent_decl) => parent_decl.clone(), + None => variant_lookup_resolved.clone(), + } + } + } + None => variant_lookup_resolved.clone(), + }; + let expected_optional_parent = Some("Optional".to_string()); + let is_present_ctor = ((type_name.clone().unwrap() == "Present".to_string()) + && (local_variant_parent.clone().as_deref() + == expected_optional_parent.clone().as_deref())); + let resolved_node = if is_present_ctor.clone() { + { + let val_field = Rc::new({ + let mut __result = Vec::new(); + for fir in fi_infer_results.clone().iter().cloned() { + if (field_init_node_name_at( + fir.typed_field.clone(), + scope.type_env.clone().source_indices.clone(), + ) == "value".to_string()) + { + __result.push(fir); + } + } + __result + }) + .first() + .cloned(); + match val_field.clone() { + Some(val_fir) => with_optional_cardinality(resolved_type( + val_fir.infer_result.clone().typed.clone(), + )), + None => raw_resolved.clone(), + } + } + } else { + raw_resolved.clone() + }; + let type_diags = match effective_lookup.clone() { + Some(_) => Rc::new(vec![]), + None => Rc::new(vec![make_error_node( + bare_name_miss_diagnostic( + scope.type_env.clone(), + type_name.clone().unwrap(), + span.clone(), + ), + scope.module_name.clone(), + )]), + }; + let sole_ctor_diags = sole_constructor_construction_diags( + type_name.clone().unwrap(), + span.clone(), + scope.clone(), + ); + let typed_field_nodes2 = typed_fields.clone(); + let rl_name = match type_name.clone() { + Some(tn_val) => tn_val.clone(), + None => "".to_string(), + }; + let texpr = make_named_expr_node( + rl_name.clone(), + Rc::new(ExprData::ExprRecordLit { + parent_enum: local_variant_parent.clone(), + }), + typed_field_nodes2.clone(), + Some(Rc::new(InferredNode::Resolved { + node: resolved_node.clone(), + })), + span.clone(), + name_span.clone(), + ); + let presence_ambiguity_diags = if ((type_diags.clone().len() as i64) > 0) { + Rc::new(vec![]) + } else { + presence_ambiguity_refusal_diags.clone() + }; + Rc::new(InferResult { + typed: texpr.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat(fi_diags.clone(), alias_struct_diags.clone()), + type_diags.clone(), + ), + sole_ctor_diags.clone(), + ), + missing_field_diags.clone(), + ), + presence_ambiguity_diags.clone(), + ), + }) + } + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[serde(tag = "_variant")] +pub enum DescentSizeExpr { + ParamSize { param: String }, + DividedSize { param: String, divisor: i64 }, +} +impl DescentSizeExpr { + pub fn param(&self) -> String { + match self { + DescentSizeExpr::ParamSize { param: __val, .. } => __val.clone(), + DescentSizeExpr::DividedSize { param: __val, .. } => __val.clone(), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DescentContext { + pub fn_name: String, + pub param_names: Rc>, + pub param_order: Rc>, + pub type_env: Rc, + pub sub_value_vars: Rc>>, + pub size_aliases: Rc>>, + pub scope_locals: Rc>>, + pub func_env: Rc, + pub per_field_vars: Rc>>>>, +} + +pub fn classify_size_expr(val: Rc, ctx: Rc) -> Option> { + match (*val.expr_data.clone()).clone() { + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let mname = + expr_method_name_at(val.clone(), ctx.type_env.clone().source_indices.clone()); + if (mname.clone() == "count".to_string()) { + { + let receiver = method_receiver(val.clone()); + match (*receiver.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let rname = expr_var_name_at( + receiver.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.param_names.clone(), rname.clone()) { + Some(_) => Some(Rc::new(DescentSizeExpr::ParamSize { + param: rname.clone(), + })), + None => None, + } + } + _ => None, + } + } + } else { + None + } + } + ExprData::ExprBinOp { .. } => { + let left = binop_left(val.clone()); + let right = binop_right(val.clone()); + match (*val.expr_data.clone()).clone() { + ExprData::ExprBinOp { op: BinOp::Div, .. } => { + match (*left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let lname = expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.size_aliases.clone(), lname.clone()) + .as_deref() + .cloned() + { + Some(DescentSizeExpr::ParamSize { param: p, .. }) => { + match expr_literal_int_optional(right.clone()) { + Some(d) => { + if (d.clone() > 0) { + Some(Rc::new(DescentSizeExpr::DividedSize { + param: p.clone(), + divisor: d.clone(), + })) + } else { + None + } + } + None => None, + } + } + _ => None, + } + } + _ => None, + } + } + _ => None, + } + } + _ => None, + } +} + +pub fn proportional_skip_alias_plus_literal( + alias_expr: Rc, + lit_expr: Rc, + param_name: String, + ctx: Rc, +) -> Option> { + match (*alias_expr.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let aname = expr_var_name_at( + alias_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.size_aliases.clone(), aname.clone()) + .as_deref() + .cloned() + { + Some(DescentSizeExpr::DividedSize { + param: p, + divisor: d, + .. + }) => { + if (p.clone() == param_name.clone()) { + match expr_literal_int_optional(lit_expr.clone()) { + Some(k) => { + if (k.clone() > 0) { + match proportional_divisor_from_int_at_least_two(d.clone()) { + Some(div_w) => { + let synth_field = Rc::new(InductiveField { + type_name: param_name.clone(), + variant_name: "".to_string(), + field_name: "skip".to_string(), + shape: RecursionShape::ListRecursion, + element_type: param_name.clone(), + }); + Some(Rc::new(SubValueRelation::StrictSubValue { + field: synth_field.clone(), + factor: Rc::new(ShrinkFactor::ProportionalShrink { + divisor: div_w.clone(), + }), + })) + } + None => None, + } + } else { + None + } + } + None => None, + } + } else { + None + } + } + _ => None, + } + } + _ => None, + } +} + +pub fn classify_collection_shrink( + arg_expr: Rc, + param_name: String, + ctx: Rc, +) -> Rc { + match (*arg_expr.expr_data.clone()).clone() { + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let mname = expr_method_name_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if ((mname.clone() == "take".to_string()) || (mname.clone() == "skip".to_string())) { + { + let receiver = method_receiver(arg_expr.clone()); + match (*receiver.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let rname = expr_var_name_at( + receiver.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if (rname.clone() == param_name.clone()) { + { + let args = method_arg_nodes(arg_expr.clone()); + match args.clone().first().cloned() { + Some(arg_node) => { + let arg_val = arg_value(arg_node.clone()); + match expr_literal_int_optional(arg_val.clone()) { + Some(k) => { + if ((k.clone() > 0) + && (mname.clone() == "skip".to_string())) + { + match positive_descent_amount_from_positive_int(k.clone()) { + Some(steps) => { + let synth_field = Rc::new(InductiveField { + type_name: param_name.clone(), + variant_name: "".to_string(), + field_name: mname.clone(), + shape: RecursionShape::ListRecursion, + element_type: param_name.clone(), +}); +Rc::new(SubValueRelation::StrictSubValue { + field: synth_field.clone(), + factor: Rc::new(ShrinkFactor::ConstantShrink { + steps: steps.clone(), +}), +}) +}, + None => Rc::new(SubValueRelation::SubValueUnknown), +} + } else { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + None => { + match (*arg_val.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, + .. + } => { + let aname = expr_var_name_at( + arg_val.clone(), + ctx.type_env + .clone() + .source_indices + .clone(), + ); + match v1_rt::map_get(&ctx.size_aliases.clone(), aname.clone()).as_deref().cloned() { + Some(DescentSizeExpr::DividedSize { param: p, divisor: d, .. }) => if (p.clone() == param_name.clone()) { + match proportional_divisor_from_int_at_least_two(d.clone()) { + Some(div_w) => { + let synth_field = Rc::new(InductiveField { + type_name: param_name.clone(), + variant_name: "".to_string(), + field_name: mname.clone(), + shape: RecursionShape::ListRecursion, + element_type: param_name.clone(), +}); +Rc::new(SubValueRelation::StrictSubValue { + field: synth_field.clone(), + factor: Rc::new(ShrinkFactor::ProportionalShrink { + divisor: div_w.clone(), +}), +}) +}, + None => Rc::new(SubValueRelation::SubValueUnknown), +} + } else { + Rc::new(SubValueRelation::SubValueUnknown) + }, + _ => Rc::new(SubValueRelation::SubValueUnknown), +} + } + ExprData::ExprBinOp { op, .. } => match op + .clone() + { + BinOp::Add => { + if (mname.clone() + == "skip".to_string()) + { + { + let left = binop_left( + arg_val.clone(), + ); + let right = binop_right( + arg_val.clone(), + ); + match proportional_skip_alias_plus_literal(left.clone(), right.clone(), param_name.clone(), ctx.clone()) { + Some(rel) => rel.clone(), + None => match proportional_skip_alias_plus_literal(right.clone(), left.clone(), param_name.clone(), ctx.clone()) { + Some(rel) => rel.clone(), + None => Rc::new(SubValueRelation::SubValueUnknown), +}, +} + } + } else { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + BinOp::Sub => Rc::new( + SubValueRelation::SubValueUnknown, + ), + _ => Rc::new( + SubValueRelation::SubValueUnknown, + ), + }, + _ => Rc::new( + SubValueRelation::SubValueUnknown, + ), + } + } + } + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + } else { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } + } + } else { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BlockAnnotateAcc { + pub ctx: Rc, + pub children: Rc>>, +} + +pub fn method_callback_element_position(semantics: Option>) -> Option { + match semantics.clone().as_deref().cloned() { + Some(MethodSemantics::AlgebraMethodSemantics { + algebra_template: at, + .. + }) => match at.clone() { + Some(template) => template.callback_element_position.clone(), + None => None, + }, + _ => None, + } +} + +pub fn maybe_insert_composed_field_relation( + acc: Rc>>, + fname: String, + composed: Option>, +) -> Rc>> { + match composed.clone() { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::SubValueUnknown => acc, + _ => v1_rt::rc_map_insert(acc, fname.clone(), rel.clone()), + }, + None => acc, + } +} + +pub fn maybe_insert_output_field_relation( + acc: Rc>>, + idx: i64, + fname: String, + sig: Rc, + val: Rc, + ctx: Rc, +) -> Rc>> { + { + let composed = match sig + .output_provenance + .clone() + .iter() + .cloned() + .skip(idx.clone() as usize) + .next() + { + Some(param_map) => { + classify_call_via_provenance(val.clone(), param_map.clone(), ctx.clone()) + } + None => None, + }; + maybe_insert_composed_field_relation(acc.clone(), fname.clone(), composed.clone()) + } +} + +pub fn maybe_insert_match_field_relation( + fp_acc: Rc>>, + pname: String, + field_label: String, + vname: String, + scrut_rel: Option>, + param_types: Rc>, + type_env: Rc, +) -> Rc>> { + match scrut_rel.clone() { + Some(rel) => { + let lookup_type = match (*rel.clone()).clone() { + SubValueRelation::PreservedValue => { + match v1_rt::map_get(¶m_types, pname.clone()) { + Some(t) => t.clone(), + None => "".to_string(), + } + } + SubValueRelation::StrictSubValue { field: f, .. } => f.element_type.clone(), + SubValueRelation::IteratedSubValue { field: f, .. } => f.element_type.clone(), + _ => "".to_string(), + }; + if (lookup_type.clone() != "".to_string()) { + { + let ind_fields = inductive_fields_for(type_env.clone(), lookup_type.clone()); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in ind_fields.clone().iter().cloned() { + if ((f.field_name.clone() == field_label.clone()) + && ((f.variant_name.clone() == vname.clone()) + || (f.variant_name.clone() == "".to_string()))) + { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => v1_rt::rc_map_insert( + fp_acc.clone(), + pname.clone(), + compose_sub_value(rel.clone(), ind_field.clone()), + ), + None => fp_acc.clone(), + } + } + } else { + fp_acc.clone() + } + } + None => fp_acc.clone(), + } +} + +pub fn build_per_field_for_let( + val: Rc, + binding_name: String, + ctx: Rc, +) -> Rc>>>> { + match (*val.expr_data.clone()).clone() { + ExprData::ExprCall { .. } => { + let callee = + expr_call_func_at(val.clone(), ctx.type_env.clone().source_indices.clone()); + match func_sig_if_resolved(lookup_func_sig( + ctx.func_env.clone(), + ctx.type_env.clone(), + callee.clone(), + )) { + Some(sig) => { + if ((sig.output_provenance.clone().len() as i64) > 1) { + { + let return_type = sig.inferred.clone(); + let field_map = Rc::new( + return_type + .children + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, + pair: (i64, Rc)| { + let idx = pair.0.clone(); + let field_node = pair.1.clone(); + let fname = authored_name_at( + ctx.type_env.clone().source_indices.clone(), + field_node.clone(), + ); + maybe_insert_output_field_relation( + acc, + idx.clone(), + fname.clone(), + sig.clone(), + val.clone(), + ctx.clone(), + ) + }, + ); + if ((Rc::new(v1_rt::map_keys(&field_map)).len() as i64) > 0) { + v1_rt::rc_map_insert( + ctx.per_field_vars.clone(), + binding_name.clone(), + field_map.clone(), + ) + } else { + ctx.per_field_vars.clone() + } + } + } else { + ctx.per_field_vars.clone() + } + } + None => ctx.per_field_vars.clone(), + } + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let callee = + expr_method_name_at(val.clone(), ctx.type_env.clone().source_indices.clone()); + match func_sig_if_resolved(lookup_func_sig( + ctx.func_env.clone(), + ctx.type_env.clone(), + callee.clone(), + )) { + Some(sig) => { + if ((sig.output_provenance.clone().len() as i64) > 1) { + { + let return_type = sig.inferred.clone(); + let field_map = Rc::new( + return_type + .children + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, + pair: (i64, Rc)| { + let idx = pair.0.clone(); + let field_node = pair.1.clone(); + let fname = authored_name_at( + ctx.type_env.clone().source_indices.clone(), + field_node.clone(), + ); + maybe_insert_output_field_relation( + acc, + idx.clone(), + fname.clone(), + sig.clone(), + val.clone(), + ctx.clone(), + ) + }, + ); + if ((Rc::new(v1_rt::map_keys(&field_map)).len() as i64) > 0) { + v1_rt::rc_map_insert( + ctx.per_field_vars.clone(), + binding_name.clone(), + field_map.clone(), + ) + } else { + ctx.per_field_vars.clone() + } + } + } else { + ctx.per_field_vars.clone() + } + } + None => ctx.per_field_vars.clone(), + } + } + _ => ctx.per_field_vars.clone(), + } +} + +pub fn resolve_collection_field( + mut expr: Rc, + mut ctx: Rc, +) -> Option> { + loop { + match (*expr.expr_data.clone()).clone() { + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(expr.clone()); + let fname = field_access_field_at( + expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = expr_var_name_at( + base.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let base_type = + match v1_rt::map_get(&ctx.param_names.clone(), bname.clone()) { + Some(t) => t.clone(), + None => { + match v1_rt::map_get(&ctx.sub_value_vars.clone(), bname.clone()) + { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { + field: f, .. + } => f.element_type.clone(), + SubValueRelation::IteratedSubValue { + field: f, .. + } => f.element_type.clone(), + _ => "".to_string(), + }, + None => "".to_string(), + } + } + }; + if (base_type.clone() != "".to_string()) { + break Rc::new({ + let mut __result = Vec::new(); + for f in Rc::new({ + let mut __result = Vec::new(); + for f in inductive_fields_for( + ctx.type_env.clone(), + base_type.clone(), + ) + .iter() + .cloned() + { + if (f.field_name.clone() == fname.clone()) { + __result.push(f); + } + } + __result + }) + .iter() + .cloned() + { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, + } { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + } else { + break None; + } + } + _ => { + break None; + } + } + } + ExprData::ExprVar { + binding_kind: _, .. + } => { + let rname = + expr_var_name_at(expr.clone(), ctx.type_env.clone().source_indices.clone()); + match v1_rt::map_get(&ctx.sub_value_vars.clone(), rname.clone()) { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { field: f, .. } => { + match f.shape.clone() { + RecursionShape::ListRecursion => { + break Some(f.clone()); + } + _ => { + break None; + } + } + } + SubValueRelation::IteratedSubValue { field: f, .. } => { + match f.shape.clone() { + RecursionShape::ListRecursion => { + break Some(f.clone()); + } + _ => { + break None; + } + } + } + _ => { + break None; + } + }, + None => { + break None; + } + } + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let inner_mname = + expr_method_name_at(expr.clone(), ctx.type_env.clone().source_indices.clone()); + let is_collection_preserving = (((((inner_mname.clone() + == "enumerate".to_string()) + || (inner_mname.clone() == "skip".to_string())) + || (inner_mname.clone() == "take".to_string())) + || (inner_mname.clone() == "filter".to_string())) + || (inner_mname.clone() == "reverse".to_string())); + if is_collection_preserving.clone() { + { + let __tco_0 = method_receiver(expr); + expr = __tco_0; + continue; + } + } else { + break None; + } + } + _ => { + break None; + } + } + } +} + +pub fn classify_binding_provenance(val: Rc, scope: Rc) -> Rc { + match (*val.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let vname = + expr_var_name_at(val.clone(), scope.type_env.clone().source_indices.clone()); + match v1_rt::map_get(&scope.locals.clone(), vname.clone()) { + Some(binding) => binding.provenance.clone(), + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(val.clone()); + let field = + field_access_field_at(val.clone(), scope.type_env.clone().source_indices.clone()); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = expr_var_name_at( + base.clone(), + scope.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&scope.locals.clone(), bname.clone()) { + Some(binding) => { + let fields = inductive_fields_for( + scope.type_env.clone(), + authored_name_at( + scope.type_env.clone().source_indices.clone(), + binding.resolved.clone(), + ), + ); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if (f.field_name.clone() == field.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => { + compose_sub_value(binding.provenance.clone(), ind_field.clone()) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } +} + +pub fn classify_let_value(val: Rc, ctx: Rc) -> Option> { + match (*val.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let vname = expr_var_name_at(val.clone(), ctx.type_env.clone().source_indices.clone()); + match v1_rt::map_get(&ctx.scope_locals.clone(), vname.clone()) { + Some(binding) => match (*binding.provenance.clone()).clone() { + SubValueRelation::SubValueUnknown => None, + _ => Some(binding.provenance.clone()), + }, + None => None, + } + } + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(val.clone()); + let field = + field_access_field_at(val.clone(), ctx.type_env.clone().source_indices.clone()); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = + expr_var_name_at(base.clone(), ctx.type_env.clone().source_indices.clone()); + let from_per_field = + match v1_rt::map_get(&ctx.per_field_vars.clone(), bname.clone()) { + Some(field_map) => v1_rt::map_get(&field_map, field.clone()), + None => None, + }; + match from_per_field.clone() { + Some(rel) => Some(rel.clone()), + None => { + let type_name = + match v1_rt::map_get(&ctx.scope_locals.clone(), bname.clone()) { + Some(binding) => authored_name_at( + ctx.type_env.clone().source_indices.clone(), + binding.resolved.clone(), + ), + None => match v1_rt::map_get( + &ctx.param_names.clone(), + bname.clone(), + ) { + Some(t) => t.clone(), + None => "".to_string(), + }, + }; + if (type_name.clone() != "".to_string()) { + { + let fields = inductive_fields_for( + ctx.type_env.clone(), + type_name.clone(), + ); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if (f.field_name.clone() == field.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => { + Some(Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), + })) + } + None => None, + } + } + } else { + None + } + } + } + } + _ => None, + } + } + ExprData::ExprCall { .. } => { + let callee = + expr_call_func_at(val.clone(), ctx.type_env.clone().source_indices.clone()); + let from_provenance = match func_sig_if_resolved(lookup_func_sig( + ctx.func_env.clone(), + ctx.type_env.clone(), + callee.clone(), + )) { + Some(sig) => match sig.output_provenance.clone().first().cloned() { + Some(param_map) => { + classify_call_via_provenance(val.clone(), param_map.clone(), ctx.clone()) + } + None => None, + }, + None => None, + }; + match from_provenance.clone() { + Some(_) => from_provenance.clone(), + None => { + if (is_child_accessor_in_model(callee.clone()) + || is_tree_size_reducing(callee.clone())) + { + { + let call_args = val.children.clone(); + match call_args.clone().first().cloned() { + Some(first_arg) => { + let inner = arg_value(first_arg.clone()); + match (*inner.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let iname = expr_var_name_at( + inner.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let inner_type = match v1_rt::map_get( + &ctx.param_names.clone(), + iname.clone(), + ) { + Some(t) => t.clone(), + None => match v1_rt::map_get( + &ctx.sub_value_vars.clone(), + iname.clone(), + ) { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { + field: f, + .. + } => f.element_type.clone(), + SubValueRelation::IteratedSubValue { + field: f, + .. + } => f.element_type.clone(), + _ => "".to_string(), + }, + None => "".to_string(), + }, + }; + if (inner_type.clone() != "".to_string()) { + { + let fields = inductive_fields_for( + ctx.type_env.clone(), + inner_type.clone(), + ); + let cf = + Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() + { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, +} { __result.push(f); } + } + __result + }) + .first() + .cloned(); + match cf.clone() { + Some(ind_field) => Some(Rc::new( + SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new( + ShrinkFactor::UnitShrink, + ), + }, + )), + None => None, + } + } + } else { + None + } + } + _ => None, + } + } + None => None, + } + } + } else { + None + } + } + } + } + _ => { + let type_based = match val.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + if is_container_type(authored_name_at( + ctx.type_env.clone().source_indices.clone(), + rt.clone(), + )) { + { + let elem = match rt.children.clone().first().cloned() { + Some(c) => authored_name_at( + ctx.type_env.clone().source_indices.clone(), + c.clone(), + ), + None => "".to_string(), + }; + if ((elem.clone() != "".to_string()) + && is_recursive_type_by_name(ctx.type_env.clone(), elem.clone())) + { + { + let fields = + inductive_fields_for(ctx.type_env.clone(), elem.clone()); + let cf = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, + } { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match cf.clone() { + Some(ind_field) => { + Some(Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), + })) + } + None => None, + } + } + } else { + None + } + } + } else { + None + } + } + _ => None, + }; + match type_based.clone() { + Some(_) => type_based.clone(), + None => match (*val.expr_data.clone()).clone() { + ExprData::ExprBinOp { op: op, .. } => { + let left = binop_left(val.clone()); + let right = binop_right(val.clone()); + match op.clone() { + BinOp::Sub => match (*left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let lname = expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if ((v1_rt::map_get(&ctx.param_names.clone(), lname.clone()) + != None) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + lname.clone(), + ) != None)) + { + match expr_literal_int_optional(right.clone()) { + Some(k) => { + match positive_descent_amount_from_positive_int( + k.clone(), + ) { + Some(steps) => Some(Rc::new( + SubValueRelation::ArithmeticDescent { + param: lname.clone(), + factor: Rc::new( + ShrinkFactor::ConstantShrink { + steps: steps.clone(), + }, + ), + }, + )), + None => None, + } + } + None => None, + } + } else { + None + } + } + _ => None, + }, + BinOp::Div => { + let left_name = match (*left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let lname = expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if ((v1_rt::map_get( + &ctx.param_names.clone(), + lname.clone(), + ) != None) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + lname.clone(), + ) != None)) + { + lname.clone() + } else { + "".to_string() + } + } + ExprData::ExprBinOp { op: BinOp::Sub, .. } => { + let inner_left = binop_left(left.clone()); + match (*inner_left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let lname = expr_var_name_at( + inner_left.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if ((v1_rt::map_get( + &ctx.param_names.clone(), + lname.clone(), + ) != None) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + lname.clone(), + ) != None)) + { + lname.clone() + } else { + "".to_string() + } + } + _ => "".to_string(), + } + } + _ => "".to_string(), + }; + if (left_name.clone() != "".to_string()) { + match expr_literal_int_optional(right.clone()) { + Some(k) => { + match proportional_divisor_from_int_at_least_two( + k.clone(), + ) { + Some(div_w) => Some(Rc::new( + SubValueRelation::ArithmeticDescent { + param: left_name.clone(), + factor: Rc::new( + ShrinkFactor::ProportionalShrink { + divisor: div_w.clone(), + }, + ), + }, + )), + None => None, + } + } + None => None, + } + } else { + None + } + } + BinOp::Add => None, + _ => None, + } + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let mname = expr_method_name_at( + val.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let is_collection_preserving = (((((mname.clone() + == "skip".to_string()) + || (mname.clone() == "filter".to_string())) + || (mname.clone() == "take".to_string())) + || (mname.clone() == "enumerate".to_string())) + || (mname.clone() == "reverse".to_string())); + if is_collection_preserving.clone() { + { + let receiver = method_receiver(val.clone()); + let coll_field = + resolve_collection_field(receiver.clone(), ctx.clone()); + match coll_field.clone() { + Some(ind_field) => { + Some(Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), + })) + } + None => { + if (mname.clone() == "skip".to_string()) { + { + let skip_args = method_arg_nodes(val.clone()); + let skip_amount = + match skip_args.clone().first().cloned() { + Some(a) => match expr_literal_int_optional( + arg_value(a.clone()), + ) { + Some(k) => { + if (k.clone() > 0) { + k.clone() + } else { + 0 + } + } + None => 0, + }, + None => 0, + }; + if (skip_amount.clone() > 0) { + match (*receiver.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, + .. + } => { + let rname = expr_var_name_at( + receiver.clone(), + ctx.type_env + .clone() + .source_indices + .clone(), + ); + if ((v1_rt::map_get( + &ctx.param_names.clone(), + rname.clone(), + ) != None) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + rname.clone(), + ) != None)) + { + match positive_descent_amount_from_positive_int(skip_amount.clone()) { + Some(steps) => { + let synth_field = Rc::new(InductiveField { + type_name: rname.clone(), + variant_name: "".to_string(), + field_name: mname.clone(), + shape: RecursionShape::ListRecursion, + element_type: rname.clone(), +}); +Some(Rc::new(SubValueRelation::StrictSubValue { + field: synth_field.clone(), + factor: Rc::new(ShrinkFactor::ConstantShrink { + steps: steps.clone(), +}), +})) +}, + None => None, +} + } else { + None + } + } + _ => None, + } + } else { + None + } + } + } else { + None + } + } + } + } + } else { + None + } + } + _ => None, + }, + } + } + } +} + +pub fn classify_call_via_provenance( + call: Rc, + param_map: Rc>>, + ctx: Rc, +) -> Option> { + { + let call_args = call.children.clone(); + let arg_by_name = call_args.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, arg_node: Rc| match arg_name_at( + arg_node.clone(), + ctx.type_env.clone().source_indices.clone(), + ) { + Some(aname) => { + v1_rt::rc_map_insert(acc.clone(), aname.clone(), arg_value(arg_node.clone())) + } + None => acc.clone(), + }, + ); + Rc::new(v1_rt::map_keys(¶m_map)).iter().cloned().fold( + None, + |result: _, callee_pname: String| match v1_rt::map_get(¶m_map, callee_pname.clone()) + { + Some(callee_rel) => match v1_rt::map_get(&arg_by_name, callee_pname.clone()) { + Some(arg_expr) => { + let arg_rel = classify_call_arg_provenance(arg_expr.clone(), ctx.clone()); + match arg_rel.clone() { + Some(arel) => { + let composed = + compose_output_relations(arel.clone(), callee_rel.clone()); + match result.clone() { + Some(prev) => { + Some(meet_sub_value(prev.clone(), composed.clone())) + } + None => Some(composed.clone()), + } + } + None => result.clone(), + } + } + None => result.clone(), + }, + None => result.clone(), + }, + ) + } +} + +pub fn classify_call_arg_provenance( + arg_expr: Rc, + ctx: Rc, +) -> Option> { + match (*arg_expr.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let name = expr_var_name_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if (v1_rt::map_get(&ctx.param_names.clone(), name.clone()) != None) { + Some(Rc::new(SubValueRelation::PreservedValue)) + } else { + v1_rt::map_get(&ctx.sub_value_vars.clone(), name.clone()) + } + } + _ => classify_let_value(arg_expr.clone(), ctx.clone()), + } +} + +pub fn merge_argument_relations(rels: Rc>>) -> Rc { + match rels.clone().first().cloned() { + None => Rc::new(SubValueRelation::SubValueUnknown), + Some(first_rel) => Rc::new( + rels.clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + first_rel.clone(), + |acc: Rc, rel: Rc| meet_sub_value(acc, rel.clone()), + ), + } +} + +pub fn classify_argument( + arg_expr: Rc, + param_name: String, + ctx: Rc, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*arg_expr.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let vname = expr_var_name_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if (vname.clone() == param_name.clone()) { + Rc::new(SubValueRelation::PreservedValue) + } else { + match v1_rt::map_get(&ctx.sub_value_vars.clone(), vname.clone()) { + Some(rel) => rel.clone(), + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + } + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(arg_expr.clone()); + let field = field_access_field_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = expr_var_name_at( + base.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let type_name = + match v1_rt::map_get(&ctx.param_names.clone(), bname.clone()) { + Some(t) => t.clone(), + None => { + match v1_rt::map_get(&ctx.sub_value_vars.clone(), bname.clone()) + { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { + field: f, .. + } => f.element_type.clone(), + SubValueRelation::IteratedSubValue { + field: f, .. + } => f.element_type.clone(), + _ => "".to_string(), + }, + None => "".to_string(), + } + } + }; + let fields = inductive_fields_for(ctx.type_env.clone(), type_name.clone()); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if (f.field_name.clone() == field.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), + }), + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } + } + ExprData::ExprCall { .. } => { + let call_args = arg_expr.children.clone(); + match call_args.clone().first().cloned() { + Some(first_arg) => { + let inner = arg_value(first_arg.clone()); + let inner_rel = + classify_argument(inner.clone(), param_name.clone(), ctx.clone()); + match (*inner_rel.clone()).clone() { + SubValueRelation::StrictSubValue { .. } => inner_rel.clone(), + SubValueRelation::IteratedSubValue { field: _, .. } => { + inner_rel.clone() + } + SubValueRelation::ArithmeticDescent { .. } => inner_rel.clone(), + SubValueRelation::PreservedValue => { + let callee = expr_call_func_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let from_provenance = match func_sig_if_resolved(lookup_func_sig( + ctx.func_env.clone(), + ctx.type_env.clone(), + callee.clone(), + )) { + Some(sig) => { + match sig.output_provenance.clone().first().cloned() { + Some(param_map) => classify_call_via_provenance( + arg_expr.clone(), + param_map.clone(), + ctx.clone(), + ), + None => None, + } + } + None => None, + }; + match from_provenance.clone() { + Some(prov_rel) => prov_rel.clone(), + None => { + if (is_child_accessor_in_model(callee.clone()) + || is_tree_size_reducing(callee.clone())) + { + { + let type_name = match v1_rt::map_get( + &ctx.param_names.clone(), + param_name.clone(), + ) { + Some(t) => t.clone(), + None => "".to_string(), + }; + let fields = inductive_fields_for( + ctx.type_env.clone(), + type_name.clone(), + ); + let cf = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, + } { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match cf.clone() { + Some(ind_field) => { + Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new( + ShrinkFactor::UnitShrink, + ), + }) + } + None => { + Rc::new(SubValueRelation::PreservedValue) + } + } + } + } else { + if is_property_contraction(callee.clone()) { + Rc::new(SubValueRelation::ArithmeticDescent { + param: param_name.clone(), + factor: Rc::new(ShrinkFactor::ConstantShrink { + steps: Rc::new( + PositiveDescentAmount::OneStep, + ), + }), + }) + } else { + Rc::new(SubValueRelation::PreservedValue) + } + } + } + } + } + SubValueRelation::NonIncreasingValue => { + Rc::new(SubValueRelation::NonIncreasingValue) + } + SubValueRelation::StrictAxisErased => { + Rc::new(SubValueRelation::StrictAxisErased) + } + SubValueRelation::MixedTop => Rc::new(SubValueRelation::MixedTop), + SubValueRelation::SubValueUnknown => { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => classify_collection_shrink(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprBinOp { op: op, .. } => { + let left = binop_left(arg_expr.clone()); + let right = binop_right(arg_expr.clone()); + match op.clone() { + BinOp::Sub => { + let left_is_param = match (*left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + ((expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ) == param_name.clone()) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ), + ) != None)) + } + _ => false, + }; + if left_is_param.clone() { + match expr_literal_int_optional(right.clone()) { + Some(k) => { + match positive_descent_amount_from_positive_int(k.clone()) { + Some(steps) => { + Rc::new(SubValueRelation::ArithmeticDescent { + param: param_name.clone(), + factor: Rc::new(ShrinkFactor::ConstantShrink { + steps: steps.clone(), + }), + }) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } else { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + BinOp::Div => { + let left_is_param = match (*left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + ((expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ) == param_name.clone()) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + expr_var_name_at( + left.clone(), + ctx.type_env.clone().source_indices.clone(), + ), + ) != None)) + } + ExprData::ExprBinOp { op: BinOp::Sub, .. } => { + let inner_left = binop_left(left.clone()); + match (*inner_left.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + ((expr_var_name_at( + inner_left.clone(), + ctx.type_env.clone().source_indices.clone(), + ) == param_name.clone()) + || (v1_rt::map_get( + &ctx.sub_value_vars.clone(), + expr_var_name_at( + inner_left.clone(), + ctx.type_env.clone().source_indices.clone(), + ), + ) != None)) + } + _ => false, + } + } + _ => false, + }; + if left_is_param.clone() { + match expr_literal_int_optional(right.clone()) { + Some(k) => { + match proportional_divisor_from_int_at_least_two(k.clone()) { + Some(div_w) => { + Rc::new(SubValueRelation::ArithmeticDescent { + param: param_name.clone(), + factor: Rc::new(ShrinkFactor::ProportionalShrink { + divisor: div_w.clone(), + }), + }) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } else { + Rc::new(SubValueRelation::SubValueUnknown) + } + } + BinOp::Add => Rc::new(SubValueRelation::SubValueUnknown), + _ => Rc::new(SubValueRelation::SubValueUnknown), + } + } + ExprData::ExprMatch => { + let arm_rels = Rc::new({ + let mut __result = Vec::new(); + for arm in match_arm_nodes(arg_expr.clone()).iter().cloned() { + __result.push(classify_argument( + arm_body(arm.clone()), + param_name.clone(), + ctx.clone(), + )); + } + __result + }); + merge_argument_relations(arm_rels.clone()) + } + ExprData::ExprIf => { + let then_rel = classify_argument( + if_then_branch(arg_expr.clone()), + param_name.clone(), + ctx.clone(), + ); + let else_rel = match if_else_branch(arg_expr.clone()) { + Some(e) => classify_argument(e.clone(), param_name.clone(), ctx.clone()), + None => Rc::new(SubValueRelation::SubValueUnknown), + }; + merge_argument_relations(Rc::new(vec![then_rel.clone(), else_rel.clone()])) + } + ExprData::ExprBlock => match arg_expr.children.clone().last().cloned() { + Some(last_expr) => { + classify_argument(last_expr.clone(), param_name.clone(), ctx.clone()) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + }, + ExprData::ExprLet => match let_body(arg_expr.clone()) { + Some(body) => classify_argument(body.clone(), param_name.clone(), ctx.clone()), + None => Rc::new(SubValueRelation::SubValueUnknown), + }, + ExprData::ExprCast => { + classify_argument(cast_expr(arg_expr.clone()), param_name.clone(), ctx.clone()) + } + ExprData::ExprReturn => match arg_expr.children.clone().first().cloned() { + Some(inner) => classify_argument(inner.clone(), param_name.clone(), ctx.clone()), + None => Rc::new(SubValueRelation::SubValueUnknown), + }, + _ => Rc::new(SubValueRelation::SubValueUnknown), + } + }) +} + +pub fn read_arg_provenance( + arg_expr: Rc, + param_name: String, + ctx: Rc, +) -> Rc { + match (*arg_expr.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let vname = expr_var_name_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.scope_locals.clone(), vname.clone()) { + Some(binding) => match (*binding.provenance.clone()).clone() { + SubValueRelation::SubValueUnknown => { + classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) + } + _ => binding.provenance.clone(), + }, + None => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + } + } + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(arg_expr.clone()); + let field = field_access_field_at( + arg_expr.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = + expr_var_name_at(base.clone(), ctx.type_env.clone().source_indices.clone()); + match v1_rt::map_get(&ctx.scope_locals.clone(), bname.clone()) { + Some(binding) => match (*binding.provenance.clone()).clone() { + SubValueRelation::SubValueUnknown => { + classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) + } + _ => { + let fields = inductive_fields_for( + ctx.type_env.clone(), + authored_name_at( + ctx.type_env.clone().source_indices.clone(), + binding.resolved.clone(), + ), + ); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if (f.field_name.clone() == field.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => compose_sub_value( + binding.provenance.clone(), + ind_field.clone(), + ), + None => Rc::new(SubValueRelation::SubValueUnknown), + } + } + }, + None => { + classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) + } + } + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } + } + ExprData::ExprCall { .. } => { + classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprBinOp { op: _, .. } => { + classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) + } + ExprData::ExprMatch => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprIf => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprBlock => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprLet => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprCast => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), + ExprData::ExprReturn => { + classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) + } + _ => Rc::new(SubValueRelation::SubValueUnknown), + } +} + +pub fn build_call_evidence( + call_node: Rc, + ctx: Rc, +) -> Rc>> { + { + let arg_map = Rc::new( + call_node + .children + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, pair: (i64, Rc)| { + let idx = pair.0.clone(); + let arg_node = pair.1.clone(); + let aname = arg_name_at( + arg_node.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match aname.clone() { + Some(pname) => v1_rt::rc_map_insert( + acc.clone(), + pname.clone(), + arg_value(arg_node.clone()), + ), + None => acc.clone(), + } + }, + ); + let positional_args = Rc::new({ + let mut __result = Vec::new(); + for arg_node in Rc::new({ + let mut __result = Vec::new(); + for arg_node in call_node.children.clone().iter().cloned() { + if (arg_name_at( + arg_node.clone(), + ctx.type_env.clone().source_indices.clone(), + ) == None) + { + __result.push(arg_node); + } + } + __result + }) + .iter() + .cloned() + { + __result.push(arg_value(arg_node.clone())); + } + __result + }); + let positional_idx = 0; + Rc::new({ + let mut __result = Vec::new(); + for pair in Rc::new( + ctx.param_order + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.push({ + let def_idx = pair.0.clone(); + let pname = pair.1.clone(); + match v1_rt::map_get(&arg_map, pname.clone()) { + Some(arg_val) => { + read_arg_provenance(arg_val.clone(), pname.clone(), ctx.clone()) + } + None => match positional_args + .clone() + .iter() + .cloned() + .skip(def_idx.clone() as usize) + .next() + { + Some(arg_val) => { + read_arg_provenance(arg_val.clone(), pname.clone(), ctx.clone()) + } + None => Rc::new(SubValueRelation::SubValueUnknown), + }, + } + }); + } + __result + }) + } +} + +pub fn descent_source_type(found: String, arg_node: Rc, ctx: Rc) -> String { + if (found.clone() != "".to_string()) { + found.clone() + } else { + match (*arg_value(arg_node.clone()).expr_data.clone()).clone() { + ExprData::ExprLambda => found.clone(), + _ => { + let arg_val = arg_value(arg_node.clone()); + match (*arg_val.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let vname = expr_var_name_at( + arg_val.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.param_names.clone(), vname.clone()) { + Some(t) => t.clone(), + None => "".to_string(), + } + } + _ => "".to_string(), + } + } + } + } +} + +pub fn annotate_descent(body: Rc, ctx: Rc) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*body.expr_data.clone()).clone() { + ExprData::ExprCall { + call_semantics: cs, .. + } => { + let evidence = build_call_evidence(body.clone(), ctx.clone()); + let source_type = body.children.clone().iter().cloned().fold( + "".to_string(), + |found: String, arg_node: Rc| { + descent_source_type(found, arg_node.clone(), ctx.clone()) + }, + ); + let annotated_children = Rc::new({ + let mut __result = Vec::new(); + for child in body.children.clone().iter().cloned() { + __result.push({ + let arg_val = arg_value(child.clone()); + match (*arg_val.expr_data.clone()).clone() { + ExprData::ExprLambda => { + if (source_type.clone() != "".to_string()) { + { + let lparams = lambda_param_names_at( + arg_val.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let p1 = match lparams.clone().first().cloned() { + Some(n) => n.clone(), + None => "".to_string(), + }; + let p2 = match lparams + .clone() + .iter() + .cloned() + .skip(1 as usize) + .next() + { + Some(n) => n.clone(), + None => "".to_string(), + }; + let lambda_ctx = Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: if (p2.clone() != "".to_string()) { + v1_rt::rc_map_insert( + v1_rt::rc_map_insert( + ctx.param_names.clone(), + p1.clone(), + source_type.clone(), + ), + p2.clone(), + source_type.clone(), + ) + } else { + if (p1.clone() != "".to_string()) { + v1_rt::rc_map_insert( + ctx.param_names.clone(), + p1.clone(), + source_type.clone(), + ) + } else { + ctx.param_names.clone() + } + }, + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: if (p1.clone() != "".to_string()) { + { + let source_fields = inductive_fields_for( + ctx.type_env.clone(), + source_type.clone(), + ); + let cf = Rc::new({ + let mut __result = Vec::new(); + for f in source_fields + .clone() + .iter() + .cloned() + { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, +} { __result.push(f); } + } + __result + }) + .first() + .cloned(); + let rel = match cf.clone() { + Some(f) => Rc::new(SubValueRelation::IteratedSubValue { + field: f.clone(), +}), + None => Rc::new(SubValueRelation::PreservedValue), +}; + if (p2.clone() != "".to_string()) { + v1_rt::rc_map_insert( + v1_rt::rc_map_insert( + ctx.sub_value_vars.clone(), + p1.clone(), + rel.clone(), + ), + p2.clone(), + rel.clone(), + ) + } else { + v1_rt::rc_map_insert( + ctx.sub_value_vars.clone(), + p1.clone(), + rel.clone(), + ) + } + } + } else { + ctx.sub_value_vars.clone() + }, + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), + }); + make_arg_node( + arg_name_at( + child.clone(), + ctx.type_env.clone().source_indices.clone(), + ), + annotate_descent( + arg_val.clone(), + lambda_ctx.clone(), + ), + child.span.clone(), + child.span.clone(), + ) + } + } else { + make_arg_node( + arg_name_at( + child.clone(), + ctx.type_env.clone().source_indices.clone(), + ), + annotate_descent(arg_val.clone(), ctx.clone()), + child.span.clone(), + child.span.clone(), + ) + } + } + _ => make_arg_node( + arg_name_at( + child.clone(), + ctx.type_env.clone().source_indices.clone(), + ), + annotate_descent(arg_val.clone(), ctx.clone()), + child.span.clone(), + child.span.clone(), + ), + } + }); + } + __result + }); + Rc::new(Node { + name: body.name.clone(), + span: body.span.clone(), + ident_span: body.ident_span.clone(), + children: annotated_children.clone(), + connective: body.connective.clone(), + params: body.params.clone(), + inferred: body.inferred.clone(), + return_cardinality: body.return_cardinality.clone(), + uses: body.uses.clone(), + body: body.body.clone(), + transport: body.transport.clone(), + properties: body.properties.clone(), + type_annotation: body.type_annotation.clone(), + is_self_recursive: body.is_self_recursive.clone(), + has_non_tail_self_call: body.has_non_tail_self_call.clone(), + match_pattern: body.match_pattern.clone(), + expr_data: Rc::new(ExprData::ExprCall { + call_semantics: cs.clone(), + descent_evidence: Some(evidence.clone()), + }), + ident: None, + }) + } + ExprData::ExprMatch => { + let scrut = match_scrutinee(body.clone()); + let scrut_type = match (*scrut.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let sname = expr_var_name_at( + scrut.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.param_names.clone(), sname.clone()) { + Some(t) => t.clone(), + None => { + match v1_rt::map_get(&ctx.sub_value_vars.clone(), sname.clone()) { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { field: f, .. } => { + f.element_type.clone() + } + SubValueRelation::IteratedSubValue { field: f, .. } => { + f.element_type.clone() + } + _ => "".to_string(), + }, + None => "".to_string(), + } + } + } + } + _ => "".to_string(), + }; + let scrut_inducing_field = match (*scrut.expr_data.clone()).clone() { + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(scrut.clone()); + let fname = field_access_field_at( + scrut.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = expr_var_name_at( + base.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let base_type = + match v1_rt::map_get(&ctx.param_names.clone(), bname.clone()) { + Some(t) => t.clone(), + None => "".to_string(), + }; + if (base_type.clone() != "".to_string()) { + { + let ind_fields = inductive_fields_for( + ctx.type_env.clone(), + base_type.clone(), + ); + Rc::new({ + let mut __result = Vec::new(); + for f in ind_fields.clone().iter().cloned() { + if (f.field_name.clone() == fname.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned() + } + } else { + None + } + } + _ => None, + } + } + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let mname = expr_method_name_at( + scrut.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if ((mname.clone() == "first".to_string()) + || (mname.clone() == "last".to_string())) + { + { + let receiver = method_receiver(scrut.clone()); + resolve_collection_field(receiver.clone(), ctx.clone()) + } + } else { + None + } + } + _ => None, + }; + let scrut_has_inductive = (((scrut_type.clone() != "".to_string()) + && ((inductive_fields_for(ctx.type_env.clone(), scrut_type.clone()).len() + as i64) + > 0)) + || (scrut_inducing_field.clone() != None)); + let scrut_variant_sig = match (*scrut.expr_data.clone()).clone() { + ExprData::ExprCall { .. } => { + let callee = expr_call_func_at( + scrut.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match func_sig_if_resolved(lookup_func_sig( + ctx.func_env.clone(), + ctx.type_env.clone(), + callee.clone(), + )) { + Some(sig) => { + if ((Rc::new(v1_rt::map_keys(&sig.variant_provenance.clone())).len() + as i64) + > 0) + { + Some(sig.clone()) + } else { + None + } + } + None => None, + } + } + _ => None, + }; + let annotated_scrut = annotate_descent(scrut.clone(), ctx.clone()); + let annotated_arms = Rc::new({ + let mut __result = Vec::new(); + for arm_node in match_arm_nodes(body.clone()).iter().cloned() { + __result.push({ + let variant_arm_ctx = match scrut_variant_sig.clone() { + Some(sig) => arm_ctx_from_variant_provenance(arm_node.clone(), sig.clone(), scrut.clone(), ctx.clone()), + None => None, +}; +let arm_ctx = match variant_arm_ctx.clone() { + Some(c) => c.clone(), + None => if scrut_has_inductive.clone() { + match (*arm_pattern(arm_node.clone())).clone() { + MatchPattern::VariantPattern { name: vname, field_bindings: bindings, .. } => match scrut_inducing_field.clone() { + Some(ind_field) => if (vname.clone() == "Present".to_string()) { + bindings.clone().iter().cloned().fold(ctx.clone(), |c: Rc, fb: Rc| match (*field_binding_pattern(fb.clone())).clone() { + MatchPattern::Bind { declaration: declaration, .. } => Rc::new(DescentContext { + fn_name: c.fn_name.clone(), + param_names: v1_rt::rc_map_insert(c.param_names.clone(), declaration.name.clone(), ind_field.element_type.clone()), + param_order: c.param_order.clone(), + type_env: c.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert(c.sub_value_vars.clone(), declaration.name.clone(), Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), +})), + size_aliases: c.size_aliases.clone(), + scope_locals: c.scope_locals.clone(), + func_env: c.func_env.clone(), + per_field_vars: c.per_field_vars.clone(), +}), + MatchPattern::VariantPattern { name: inner_vname, field_bindings: inner_bindings, .. } => { + let inner_ind_fields = inductive_fields_for(c.type_env.clone(), ind_field.element_type.clone()); +inner_bindings.clone().iter().cloned().fold(c.clone(), |ic: Rc, inner_fb: Rc| { + let inner_field_name = field_binding_name_at(inner_fb.clone(), ctx.type_env.clone().source_indices.clone()); +let inner_bind_name = match (*field_binding_pattern(inner_fb.clone())).clone() { + MatchPattern::Bind { declaration: declaration, .. } => declaration.name.clone(), + _ => "".to_string(), +}; +let inner_matching = Rc::new({ let mut __result = Vec::new(); for f in inner_ind_fields.clone().iter().cloned() { if ((f.variant_name.clone() == inner_vname.clone()) && (f.field_name.clone() == inner_field_name.clone())) { __result.push(f); } } __result }).first().cloned(); +match inner_matching.clone() { + Some(inner_ind_field) => if (inner_bind_name.clone() != "".to_string()) { + Rc::new(DescentContext { + fn_name: ic.fn_name.clone(), + param_names: v1_rt::rc_map_insert(ic.param_names.clone(), inner_bind_name.clone(), inner_ind_field.element_type.clone()), + param_order: ic.param_order.clone(), + type_env: ic.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert(ic.sub_value_vars.clone(), inner_bind_name.clone(), Rc::new(SubValueRelation::StrictSubValue { + field: inner_ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), +})), + size_aliases: ic.size_aliases.clone(), + scope_locals: ic.scope_locals.clone(), + func_env: ic.func_env.clone(), + per_field_vars: ic.per_field_vars.clone(), +}) + } else { + ic.clone() + }, + None => ic.clone(), +} +}) +}, + _ => c.clone(), +}) + } else { + ctx.clone() + }, + None => { + let ind_fields = inductive_fields_for(ctx.type_env.clone(), scrut_type.clone()); +bindings.clone().iter().cloned().fold(ctx.clone(), |c: Rc, fb: Rc| { + let field_name = field_binding_name_at(fb.clone(), ctx.type_env.clone().source_indices.clone()); +let bind_name = match (*field_binding_pattern(fb.clone())).clone() { + MatchPattern::Bind { declaration: declaration, .. } => declaration.name.clone(), + _ => "".to_string(), +}; +let matching = Rc::new({ let mut __result = Vec::new(); for f in ind_fields.clone().iter().cloned() { if ((f.variant_name.clone() == vname.clone()) && (f.field_name.clone() == field_name.clone())) { __result.push(f); } } __result }).first().cloned(); +match matching.clone() { + Some(ind_field) => if (bind_name.clone() != "".to_string()) { + Rc::new(DescentContext { + fn_name: c.fn_name.clone(), + param_names: c.param_names.clone(), + param_order: c.param_order.clone(), + type_env: c.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert(c.sub_value_vars.clone(), bind_name.clone(), Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), +})), + size_aliases: c.size_aliases.clone(), + scope_locals: c.scope_locals.clone(), + func_env: c.func_env.clone(), + per_field_vars: c.per_field_vars.clone(), +}) + } else { + c.clone() + }, + None => c.clone(), +} +}) +}, +}, + MatchPattern::Bind { declaration: declaration, .. } => if (scrut_type.clone() != "".to_string()) { + Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: v1_rt::rc_map_insert(ctx.param_names.clone(), declaration.name.clone(), scrut_type.clone()), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert(ctx.sub_value_vars.clone(), declaration.name.clone(), Rc::new(SubValueRelation::PreservedValue)), + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), +}) + } else { + match scrut_inducing_field.clone() { + Some(ind_field) => Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: v1_rt::rc_map_insert(ctx.param_names.clone(), declaration.name.clone(), ind_field.element_type.clone()), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert(ctx.sub_value_vars.clone(), declaration.name.clone(), Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new(ShrinkFactor::UnitShrink), +})), + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), +}), + None => ctx.clone(), +} + }, + _ => ctx.clone(), +} + } else { + ctx.clone() + }, +}; +let annotated_body = annotate_descent(arm_body(arm_node.clone()), arm_ctx.clone()); +make_arm_node(arm_pattern(arm_node.clone()), arm_guard(arm_node.clone()), annotated_body.clone(), arm_node.span.clone()) +}); + } + __result + }); + Rc::new(Node { + name: body.name.clone(), + span: body.span.clone(), + ident_span: body.ident_span.clone(), + children: v1_rt::concat( + Rc::new(vec![annotated_scrut.clone()]), + annotated_arms.clone(), + ), + connective: body.connective.clone(), + params: body.params.clone(), + inferred: body.inferred.clone(), + return_cardinality: body.return_cardinality.clone(), + uses: body.uses.clone(), + body: body.body.clone(), + transport: body.transport.clone(), + properties: body.properties.clone(), + type_annotation: body.type_annotation.clone(), + is_self_recursive: body.is_self_recursive.clone(), + has_non_tail_self_call: body.has_non_tail_self_call.clone(), + match_pattern: body.match_pattern.clone(), + expr_data: body.expr_data.clone(), + ident: None, + }) + } + ExprData::ExprLet => { + let val = let_value(body.clone()); + let binding_name = + let_binding_name_at(body.clone(), ctx.type_env.clone().source_indices.clone()); + let val_relation = classify_let_value(val.clone(), ctx.clone()); + let size_alias = classify_size_expr(val.clone(), ctx.clone()); + let inner_size_aliases = match size_alias.clone() { + Some(se) => v1_rt::rc_map_insert( + ctx.size_aliases.clone(), + binding_name.clone(), + se.clone(), + ), + None => ctx.size_aliases.clone(), + }; + let inner_per_field = + build_per_field_for_let(val.clone(), binding_name.clone(), ctx.clone()); + let inner_ctx = match val_relation.clone() { + Some(rel) => { + let sub_type = match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { field: f, .. } => { + f.element_type.clone() + } + SubValueRelation::IteratedSubValue { field: f, .. } => { + f.element_type.clone() + } + _ => "".to_string(), + }; + Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: if (sub_type.clone() != "".to_string()) { + v1_rt::rc_map_insert( + ctx.param_names.clone(), + binding_name.clone(), + sub_type.clone(), + ) + } else { + ctx.param_names.clone() + }, + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert( + ctx.sub_value_vars.clone(), + binding_name.clone(), + rel.clone(), + ), + size_aliases: inner_size_aliases.clone(), + scope_locals: v1_rt::rc_map_insert( + ctx.scope_locals.clone(), + binding_name.clone(), + Rc::new(TypeBinding { + name: binding_name.clone(), + resolved: resolved_type(val.clone()), + provenance: rel.clone(), + }), + ), + func_env: ctx.func_env.clone(), + per_field_vars: inner_per_field.clone(), + }) + } + None => Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: ctx.param_names.clone(), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: ctx.sub_value_vars.clone(), + size_aliases: inner_size_aliases.clone(), + scope_locals: v1_rt::rc_map_insert( + ctx.scope_locals.clone(), + binding_name.clone(), + Rc::new(TypeBinding { + name: binding_name.clone(), + resolved: resolved_type(val.clone()), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ), + func_env: ctx.func_env.clone(), + per_field_vars: inner_per_field.clone(), + }), + }; + let annotated_value = annotate_descent(val.clone(), ctx.clone()); + let annotated_children = match let_body(body.clone()) { + Some(body_child) => Rc::new(vec![ + annotated_value.clone(), + annotate_descent(body_child.clone(), inner_ctx.clone()), + ]), + None => Rc::new(vec![annotated_value.clone()]), + }; + Rc::new(Node { + name: body.name.clone(), + span: body.span.clone(), + ident_span: body.ident_span.clone(), + children: annotated_children.clone(), + connective: body.connective.clone(), + params: body.params.clone(), + inferred: body.inferred.clone(), + return_cardinality: body.return_cardinality.clone(), + uses: body.uses.clone(), + body: body.body.clone(), + transport: body.transport.clone(), + properties: body.properties.clone(), + type_annotation: body.type_annotation.clone(), + is_self_recursive: body.is_self_recursive.clone(), + has_non_tail_self_call: body.has_non_tail_self_call.clone(), + match_pattern: body.match_pattern.clone(), + expr_data: body.expr_data.clone(), + ident: None, + }) + } + ExprData::ExprBlock => { + let threaded = body.children.clone().iter().cloned().fold( + Rc::new(BlockAnnotateAcc { + ctx: ctx.clone(), + children: Rc::new(vec![]), + }), + |acc: Rc, child: Rc| { + let annotated = annotate_descent(child.clone(), acc.ctx.clone()); + let next_ctx = match (*child.expr_data.clone()).clone() { + ExprData::ExprLet => { + let val = let_value(child.clone()); + let bname = let_binding_name_at( + child.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let val_rel = classify_let_value(val.clone(), acc.ctx.clone()); + let sa = classify_size_expr(val.clone(), acc.ctx.clone()); + let new_sa = match sa.clone() { + Some(se) => v1_rt::rc_map_insert( + acc.ctx.clone().size_aliases.clone(), + bname.clone(), + se.clone(), + ), + None => acc.ctx.clone().size_aliases.clone(), + }; + match val_rel.clone() { + Some(rel) => { + let sub_type = match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { + field: f, .. + } => f.element_type.clone(), + SubValueRelation::IteratedSubValue { + field: f, .. + } => f.element_type.clone(), + _ => "".to_string(), + }; + Rc::new(DescentContext { + fn_name: acc.ctx.clone().fn_name.clone(), + param_names: if (sub_type.clone() != "".to_string()) { + v1_rt::rc_map_insert( + acc.ctx.clone().param_names.clone(), + bname.clone(), + sub_type.clone(), + ) + } else { + acc.ctx.clone().param_names.clone() + }, + param_order: acc.ctx.clone().param_order.clone(), + type_env: acc.ctx.clone().type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert( + acc.ctx.clone().sub_value_vars.clone(), + bname.clone(), + rel.clone(), + ), + size_aliases: new_sa.clone(), + scope_locals: v1_rt::rc_map_insert( + acc.ctx.clone().scope_locals.clone(), + bname.clone(), + Rc::new(TypeBinding { + name: bname.clone(), + resolved: resolved_type(val.clone()), + provenance: rel.clone(), + }), + ), + func_env: acc.ctx.clone().func_env.clone(), + per_field_vars: acc.ctx.clone().per_field_vars.clone(), + }) + } + None => Rc::new(DescentContext { + fn_name: acc.ctx.clone().fn_name.clone(), + param_names: acc.ctx.clone().param_names.clone(), + param_order: acc.ctx.clone().param_order.clone(), + type_env: acc.ctx.clone().type_env.clone(), + sub_value_vars: acc.ctx.clone().sub_value_vars.clone(), + size_aliases: new_sa.clone(), + scope_locals: v1_rt::rc_map_insert( + acc.ctx.clone().scope_locals.clone(), + bname.clone(), + Rc::new(TypeBinding { + name: bname.clone(), + resolved: resolved_type(val.clone()), + provenance: Rc::new( + SubValueRelation::SubValueUnknown, + ), + }), + ), + func_env: acc.ctx.clone().func_env.clone(), + per_field_vars: acc.ctx.clone().per_field_vars.clone(), + }), + } + } + _ => acc.ctx.clone(), + }; + Rc::new(BlockAnnotateAcc { + ctx: next_ctx.clone(), + children: v1_rt::concat( + acc.children.clone(), + Rc::new(vec![annotated.clone()]), + ), + }) + }, + ); + Rc::new(Node { + name: body.name.clone(), + span: body.span.clone(), + ident_span: body.ident_span.clone(), + children: threaded.children.clone(), + connective: body.connective.clone(), + params: body.params.clone(), + inferred: body.inferred.clone(), + return_cardinality: body.return_cardinality.clone(), + uses: body.uses.clone(), + body: body.body.clone(), + transport: body.transport.clone(), + properties: body.properties.clone(), + type_annotation: body.type_annotation.clone(), + is_self_recursive: body.is_self_recursive.clone(), + has_non_tail_self_call: body.has_non_tail_self_call.clone(), + match_pattern: body.match_pattern.clone(), + expr_data: body.expr_data.clone(), + ident: None, + }) + } + ExprData::ExprMethodCall { + method_semantics: ms, + .. + } => { + let mname = + expr_method_name_at(body.clone(), ctx.type_env.clone().source_indices.clone()); + let elem_position = method_callback_element_position(ms.clone()); + if (elem_position.clone() != None) { + { + let raw_receiver = method_receiver(body.clone()); + let receiver = match (*raw_receiver.expr_data.clone()).clone() { + ExprData::ExprMethodCall { + method_semantics: _, + .. + } => { + let inner_mname = expr_method_name_at( + raw_receiver.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + if (inner_mname.clone() == "enumerate".to_string()) { + method_receiver(raw_receiver.clone()) + } else { + raw_receiver.clone() + } + } + _ => raw_receiver.clone(), + }; + let receiver_field = match (*receiver.expr_data.clone()).clone() { + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(receiver.clone()); + let fname = field_access_field_at( + receiver.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match (*base.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let bname = expr_var_name_at( + base.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let base_type = match v1_rt::map_get( + &ctx.param_names.clone(), + bname.clone(), + ) { + Some(t) => t.clone(), + None => match v1_rt::map_get( + &ctx.sub_value_vars.clone(), + bname.clone(), + ) { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { + field: f, + .. + } => f.element_type.clone(), + SubValueRelation::IteratedSubValue { + field: f, + .. + } => f.element_type.clone(), + _ => "".to_string(), + }, + None => "".to_string(), + }, + }; + if (base_type.clone() != "".to_string()) { + Rc::new({ + let mut __result = Vec::new(); + for f in inductive_fields_for( + ctx.type_env.clone(), + base_type.clone(), + ) + .iter() + .cloned() + { + if (f.field_name.clone() == fname.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned() + } else { + None + } + } + _ => None, + } + } + ExprData::ExprVar { + binding_kind: _, .. + } => { + let rname = expr_var_name_at( + receiver.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + match v1_rt::map_get(&ctx.sub_value_vars.clone(), rname.clone()) { + Some(rel) => match (*rel.clone()).clone() { + SubValueRelation::StrictSubValue { field: f, .. } => { + match f.shape.clone() { + RecursionShape::ListRecursion => Some(f.clone()), + _ => None, + } + } + SubValueRelation::IteratedSubValue { field: f, .. } => { + match f.shape.clone() { + RecursionShape::ListRecursion => Some(f.clone()), + _ => None, + } + } + _ => None, + }, + None => None, + } + } + _ => None, + }; + let method_args = method_arg_nodes(body.clone()); + let lambda_arg = Rc::new({ + let mut __result = Vec::new(); + for a in method_args.clone().iter().cloned() { + if match (*arg_value(a.clone()).expr_data.clone()).clone() { + ExprData::ExprLambda => true, + _ => false, + } { + __result.push(a); + } + } + __result + }) + .first() + .cloned(); + let lambda_elem_info = match lambda_arg.clone() { + Some(la) => { + let lambda_node = arg_value(la.clone()); + let lparams = lambda_param_names_at( + lambda_node.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + lparams + .clone() + .iter() + .cloned() + .skip(elem_position.clone().unwrap() as usize) + .next() + } + None => None, + }; + let is_fold = (elem_position.clone().unwrap() > 0); + let inner_ctx = match lambda_elem_info.clone() { + Some(elem_name) => match receiver_field.clone() { + Some(ind_field) => Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: v1_rt::rc_map_insert( + ctx.param_names.clone(), + elem_name.clone(), + ind_field.element_type.clone(), + ), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: if is_fold.clone() { + v1_rt::rc_map_insert( + v1_rt::rc_empty_map::>(), + elem_name.clone(), + Rc::new(SubValueRelation::IteratedSubValue { + field: ind_field.clone(), + }), + ) + } else { + v1_rt::rc_map_insert( + ctx.sub_value_vars.clone(), + elem_name.clone(), + Rc::new(SubValueRelation::IteratedSubValue { + field: ind_field.clone(), + }), + ) + }, + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), + }), + None => Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: ctx.param_names.clone(), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: if is_fold.clone() { + v1_rt::rc_empty_map::>() + } else { + ctx.sub_value_vars.clone() + }, + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), + }), + }, + None => ctx.clone(), + }; + let annotated_receiver = + annotate_descent(method_receiver(body.clone()), ctx.clone()); + let annotated_args = Rc::new({ + let mut __result = Vec::new(); + for arg_node in method_arg_nodes(body.clone()).iter().cloned() { + __result.push({ + let arg_val = arg_value(arg_node.clone()); + let is_lambda = match (*arg_val.expr_data.clone()).clone() { + ExprData::ExprLambda => true, + _ => false, + }; + if is_lambda.clone() { + make_arg_node( + match arg_name_at( + arg_node.clone(), + ctx.type_env.clone().source_indices.clone(), + ) { + Some(n) => Some(n.clone()), + None => None, + }, + annotate_descent(arg_val.clone(), inner_ctx.clone()), + arg_node.span.clone(), + arg_node.span.clone(), + ) + } else { + make_arg_node( + match arg_name_at( + arg_node.clone(), + ctx.type_env.clone().source_indices.clone(), + ) { + Some(n) => Some(n.clone()), + None => None, + }, + annotate_descent(arg_val.clone(), ctx.clone()), + arg_node.span.clone(), + arg_node.span.clone(), + ) + } + }); + } + __result + }); + Rc::new(Node { + name: body.name.clone(), + span: body.span.clone(), + ident_span: body.ident_span.clone(), + children: v1_rt::concat( + Rc::new(vec![annotated_receiver.clone()]), + annotated_args.clone(), + ), + connective: body.connective.clone(), + params: body.params.clone(), + inferred: body.inferred.clone(), + return_cardinality: body.return_cardinality.clone(), + uses: body.uses.clone(), + body: body.body.clone(), + transport: body.transport.clone(), + properties: body.properties.clone(), + type_annotation: body.type_annotation.clone(), + is_self_recursive: body.is_self_recursive.clone(), + has_non_tail_self_call: body.has_non_tail_self_call.clone(), + match_pattern: body.match_pattern.clone(), + expr_data: body.expr_data.clone(), + ident: None, + }) + } + } else { + map_children(body.clone(), |child| { + annotate_descent(child.clone(), ctx.clone()) + }) + } + } + ExprData::ExprForEach => { + let coll = foreach_collection(body.clone()); + let fe_body = foreach_body(body.clone()); + let fe_var = + foreach_variable_at(body.clone(), ctx.type_env.clone().source_indices.clone()); + let coll_field = resolve_collection_field(coll.clone(), ctx.clone()); + let inner_ctx = match coll_field.clone() { + Some(ind_field) => Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: v1_rt::rc_map_insert( + ctx.param_names.clone(), + fe_var.clone(), + ind_field.element_type.clone(), + ), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert( + v1_rt::rc_empty_map::>(), + fe_var.clone(), + Rc::new(SubValueRelation::IteratedSubValue { + field: ind_field.clone(), + }), + ), + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), + }), + None => Rc::new(DescentContext { + fn_name: ctx.fn_name.clone(), + param_names: ctx.param_names.clone(), + param_order: ctx.param_order.clone(), + type_env: ctx.type_env.clone(), + sub_value_vars: v1_rt::rc_empty_map::>(), + size_aliases: ctx.size_aliases.clone(), + scope_locals: ctx.scope_locals.clone(), + func_env: ctx.func_env.clone(), + per_field_vars: ctx.per_field_vars.clone(), + }), + }; + let annotated_coll = annotate_descent(coll.clone(), ctx.clone()); + let annotated_body = annotate_descent(fe_body.clone(), inner_ctx.clone()); + Rc::new(Node { + name: body.name.clone(), + span: body.span.clone(), + ident_span: body.ident_span.clone(), + children: Rc::new(vec![annotated_coll.clone(), annotated_body.clone()]), + connective: body.connective.clone(), + params: body.params.clone(), + inferred: body.inferred.clone(), + return_cardinality: body.return_cardinality.clone(), + uses: body.uses.clone(), + body: body.body.clone(), + transport: body.transport.clone(), + properties: body.properties.clone(), + type_annotation: body.type_annotation.clone(), + is_self_recursive: body.is_self_recursive.clone(), + has_non_tail_self_call: body.has_non_tail_self_call.clone(), + match_pattern: body.match_pattern.clone(), + expr_data: body.expr_data.clone(), + ident: None, + }) + } + _ => map_children(body.clone(), |child| { + annotate_descent(child.clone(), ctx.clone()) + }), + } + }) +} + +pub fn resolved_type_name( + n: Rc, + source_indices: Rc>>, +) -> String { + match n.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + authored_name_at(source_indices.clone(), rt.clone()) + } + _ => match n.children.clone().first().cloned() { + Some(c) => authored_name_at(source_indices.clone(), c.clone()), + None => "".to_string(), + }, + } +} + +pub fn infer_output_provenance( + body: Rc, + params: Rc>>, + type_env: Rc, + scope_locals: Rc>>, + func_env: Rc, +) -> Rc>>>> { + { + let param_names = Rc::new({ + let mut __result = Vec::new(); + for p in params.clone().iter().cloned() { + __result.push(param_node_name_at( + p.clone(), + type_env.source_indices.clone(), + )); + } + __result + }); + let param_types = params.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, p: Rc| { + let pname = param_node_name_at(p.clone(), type_env.source_indices.clone()); + let ptype = resolved_type_name(p.clone(), type_env.source_indices.clone()); + if ((pname.clone() != "".to_string()) && (ptype.clone() != "".to_string())) { + v1_rt::rc_map_insert(acc.clone(), pname.clone(), ptype.clone()) + } else { + acc.clone() + } + }, + ); + let scalar = classify_body_provenance( + body.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + v1_rt::rc_empty_map::>>>(), + ); + if ((Rc::new(v1_rt::map_keys(&scalar)).len() as i64) > 0) { + Rc::new(vec![scalar.clone()]) + } else { + { + let per_field = classify_body_per_field( + body.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + v1_rt::rc_empty_map::>>>(), + ); + if (((per_field.clone().len() as i64) > 0) && { + let mut __found = false; + for m in per_field.clone().iter().cloned() { + if ((Rc::new(v1_rt::map_keys(&m)).len() as i64) > 0) { + __found = true; + break; + } + } + __found + }) { + per_field.clone() + } else { + Rc::new(vec![]) + } + } + } + } +} + +pub fn classify_body_provenance( + expr: Rc, + param_names: Rc>, + param_types: Rc>, + type_env: Rc, + func_env: Rc, + let_prov: Rc>>>>, +) -> Rc>> { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*expr.expr_data.clone()).clone() { + ExprData::ExprVar { + binding_kind: _, .. + } => { + let vname = expr_var_name_at(expr.clone(), type_env.source_indices.clone()); + match v1_rt::map_get(&let_prov, vname.clone()) { + Some(prov) => prov.clone(), + None => { + if { + let mut __found = false; + for pn in param_names.clone().iter().cloned() { + if (pn.clone() == vname.clone()) { + __found = true; + break; + } + } + __found + } { + v1_rt::rc_map_insert( + v1_rt::rc_empty_map::>(), + vname.clone(), + Rc::new(SubValueRelation::PreservedValue), + ) + } else { + v1_rt::rc_empty_map::>() + } + } + } + } + ExprData::ExprFieldAccess { summary: _, .. } => { + let base = field_access_base(expr.clone()); + let field = field_access_field_at(expr.clone(), type_env.source_indices.clone()); + let base_prov = classify_body_provenance( + base.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + Rc::new(v1_rt::map_keys(&base_prov)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, pname: String| { + match v1_rt::map_get(&base_prov, pname.clone()) { + Some(base_rel) => { + let type_for_lookup = match (*base_rel.clone()).clone() { + SubValueRelation::PreservedValue => { + match v1_rt::map_get(¶m_types, pname.clone()) { + Some(t) => t.clone(), + None => "".to_string(), + } + } + SubValueRelation::StrictSubValue { field: f, .. } => { + f.element_type.clone() + } + SubValueRelation::IteratedSubValue { field: f, .. } => { + f.element_type.clone() + } + _ => "".to_string(), + }; + if (type_for_lookup.clone() != "".to_string()) { + { + let fields = inductive_fields_for( + type_env.clone(), + type_for_lookup.clone(), + ); + let matching = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if (f.field_name.clone() == field.clone()) { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match matching.clone() { + Some(ind_field) => v1_rt::rc_map_insert( + acc.clone(), + pname.clone(), + compose_sub_value( + base_rel.clone(), + ind_field.clone(), + ), + ), + None => acc.clone(), + } + } + } else { + acc.clone() + } + } + None => acc.clone(), + } + }, + ) + } + ExprData::ExprCall { .. } => { + let callee = expr_call_func_at(expr.clone(), type_env.source_indices.clone()); + compose_callee_provenance( + callee.clone(), + call_args_by_name(expr.clone(), type_env.source_indices.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ) + } + ExprData::ExprMethodCall { + method_semantics: ms, + .. + } => { + let mname = expr_method_name_at(expr.clone(), type_env.source_indices.clone()); + let callee_result = compose_callee_provenance( + mname.clone(), + method_call_args_by_name( + expr.clone(), + func_env.clone(), + type_env.clone(), + type_env.source_indices.clone(), + ), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + if ((Rc::new(v1_rt::map_keys(&callee_result)).len() as i64) > 0) { + callee_result.clone() + } else { + { + let is_shrink = match ms.clone().as_deref().cloned() { + Some(MethodSemantics::AlgebraMethodSemantics { + size_effect: se, + .. + }) => match se.clone() { + Some(CollectionSizeEffect::ShrinkEffect) => true, + _ => false, + }, + _ => false, + }; + if (is_shrink.clone() + && match method_arg_nodes(expr.clone()).first().cloned() { + Some(arg_node) => { + match expr_literal_int_optional(arg_value(arg_node.clone())) { + Some(n) => (n.clone() > 0), + None => false, + } + } + None => false, + }) + { + { + let recv = method_receiver(expr.clone()); + let recv_prov = classify_body_provenance( + recv.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + Rc::new(v1_rt::map_keys(&recv_prov)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, + pname: String| { + match v1_rt::map_get(&recv_prov, pname.clone()) { + Some(recv_rel) => { + let synth_field = Rc::new(InductiveField { + type_name: pname.clone(), + variant_name: "".to_string(), + field_name: mname.clone(), + shape: RecursionShape::ListRecursion, + element_type: pname.clone(), + }); + v1_rt::rc_map_insert( + acc.clone(), + pname.clone(), + compose_sub_value( + recv_rel.clone(), + synth_field.clone(), + ), + ) + } + None => acc.clone(), + } + }, + ) + } + } else { + v1_rt::rc_empty_map::>() + } + } + } + } + ExprData::ExprMatch => { + let scrut = match_scrutinee(expr.clone()); + let scrut_prov = classify_body_provenance( + scrut.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + let arms = match_arm_nodes(expr.clone()); + let arm_provs = Rc::new({ + let mut __result = Vec::new(); + for arm in arms.clone().iter().cloned() { + __result.push({ + let arm_let_prov = match (*arm_pattern(arm.clone())).clone() { + MatchPattern::VariantPattern { name: vname, field_bindings: bindings, .. } => bindings.clone().iter().cloned().fold(let_prov.clone(), |acc: Rc>>>>, binding: Rc| { + let field_label = field_binding_name_at(binding.clone(), type_env.source_indices.clone()); +let bind_name = match (*field_binding_pattern(binding.clone())).clone() { + MatchPattern::Bind { declaration: declaration, .. } => declaration.name.clone(), + _ => "".to_string(), +}; +if ((bind_name.clone() != "".to_string()) && (field_label.clone() != "".to_string())) { + { + let field_prov = Rc::new(v1_rt::map_keys(&scrut_prov)).iter().cloned().fold(empty_prov_map(), |fp_acc: Rc>>, pname: String| maybe_insert_match_field_relation(fp_acc, pname.clone(), field_label.clone(), vname.clone(), v1_rt::map_get(&scrut_prov, pname.clone()), param_types.clone(), type_env.clone())); +v1_rt::rc_map_insert(acc.clone(), bind_name.clone(), field_prov.clone()) +} + } else { + acc.clone() + } +}), + MatchPattern::Bind { declaration: declaration, .. } => v1_rt::rc_map_insert(let_prov.clone(), declaration.name.clone(), scrut_prov.clone()), + _ => let_prov.clone(), +}; +classify_body_provenance(arm_body(arm.clone()), param_names.clone(), param_types.clone(), type_env.clone(), func_env.clone(), arm_let_prov.clone()) +}); + } + __result + }); + meet_body_provenance_maps(arm_provs.clone()) + } + ExprData::ExprIf => { + let then_prov = classify_body_provenance( + if_then_branch(expr.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + match if_else_branch(expr.clone()) { + Some(else_expr) => { + let else_prov = classify_body_provenance( + else_expr.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + meet_body_provenance_maps(Rc::new(vec![ + then_prov.clone(), + else_prov.clone(), + ])) + } + None => then_prov.clone(), + } + } + ExprData::ExprLet => { + let value = let_value(expr.clone()); + let bname = let_binding_name_at(expr.clone(), type_env.source_indices.clone()); + let value_prov = classify_body_provenance( + value.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + let updated = + v1_rt::rc_map_insert(let_prov.clone(), bname.clone(), value_prov.clone()); + match let_body(expr.clone()) { + Some(body) => classify_body_provenance( + body.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + updated.clone(), + ), + None => v1_rt::rc_empty_map::>(), + } + } + ExprData::ExprBlock => { + let block_result = expr.children.clone().iter().cloned().fold( + Rc::new(BlockProvFoldState { + prov: let_prov.clone(), + last: empty_prov_map(), + }), + |state: Rc, stmt: Rc| match (*stmt.expr_data.clone()) + .clone() + { + ExprData::ExprLet => { + let bname = + let_binding_name_at(stmt.clone(), type_env.source_indices.clone()); + let value = let_value(stmt.clone()); + let value_prov = classify_body_provenance( + value.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + state.prov.clone(), + ); + let updated_prov = v1_rt::rc_map_insert( + state.prov.clone(), + bname.clone(), + value_prov.clone(), + ); + match let_body(stmt.clone()) { + Some(body) => Rc::new(BlockProvFoldState { + prov: state.prov.clone(), + last: classify_body_provenance( + body.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + updated_prov.clone(), + ), + }), + None => Rc::new(BlockProvFoldState { + prov: updated_prov.clone(), + last: value_prov.clone(), + }), + } + } + _ => Rc::new(BlockProvFoldState { + prov: state.prov.clone(), + last: classify_body_provenance( + stmt.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + state.prov.clone(), + ), + }), + }, + ); + block_result.last.clone() + } + ExprData::ExprCast => classify_body_provenance( + cast_expr(expr.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ), + ExprData::ExprReturn => match expr.children.clone().first().cloned() { + Some(inner) => classify_body_provenance( + inner.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ), + None => v1_rt::rc_empty_map::>(), + }, + _ => v1_rt::rc_empty_map::>(), + } + }) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BlockProvFoldState { + pub prov: Rc>>>>, + pub last: Rc>>, +} + +pub fn call_args_by_name( + call: Rc, + source_indices: Rc>>, +) -> Rc>> { + call.children.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, arg_node: Rc| match arg_name_at( + arg_node.clone(), + source_indices.clone(), + ) { + Some(aname) => { + v1_rt::rc_map_insert(acc.clone(), aname.clone(), arg_value(arg_node.clone())) + } + None => acc.clone(), + }, + ) +} + +pub fn method_call_args_by_name( + call: Rc, + func_env: Rc, + type_env: Rc, + source_indices: Rc>>, +) -> Rc>> { + { + let mname = expr_method_name_at(call.clone(), source_indices.clone()); + let recv = method_receiver(call.clone()); + let mc_args = method_arg_nodes(call.clone()); + let base = match func_sig_if_resolved(lookup_func_sig( + func_env.clone(), + type_env.clone(), + mname.clone(), + )) { + Some(sig) => match sig.params.clone().first().cloned() { + Some(first_p) => { + let first_pname = param_node_name_at(first_p.clone(), source_indices.clone()); + if (first_pname.clone() != "".to_string()) { + v1_rt::rc_map_insert( + v1_rt::rc_empty_map::>(), + first_pname.clone(), + recv.clone(), + ) + } else { + v1_rt::rc_empty_map::>() + } + } + None => v1_rt::rc_empty_map::>(), + }, + None => v1_rt::rc_empty_map::>(), + }; + mc_args.clone().iter().cloned().fold( + base.clone(), + |acc: Rc>>, arg_node: Rc| match arg_name_at( + arg_node.clone(), + source_indices.clone(), + ) { + Some(aname) => { + v1_rt::rc_map_insert(acc.clone(), aname.clone(), arg_value(arg_node.clone())) + } + None => acc.clone(), + }, + ) + } +} + +pub fn compose_callee_provenance( + callee: String, + arg_by_name: Rc>>, + param_names: Rc>, + param_types: Rc>, + type_env: Rc, + func_env: Rc, + let_prov: Rc>>>>, +) -> Rc>> { + match func_sig_if_resolved(lookup_func_sig( + func_env.clone(), + type_env.clone(), + callee.clone(), + )) { + Some(sig) => match sig.output_provenance.clone().first().cloned() { + Some(callee_prov) => Rc::new(v1_rt::map_keys(&callee_prov)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, callee_pname: String| { + match v1_rt::map_get(&callee_prov, callee_pname.clone()) { + Some(callee_rel) => { + match v1_rt::map_get(&arg_by_name, callee_pname.clone()) { + Some(arg) => { + let arg_prov = classify_body_provenance( + arg.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + Rc::new(v1_rt::map_keys(&arg_prov)).iter().cloned().fold( + acc.clone(), + |inner: Rc>>, + pname: String| { + match v1_rt::map_get(&arg_prov, pname.clone()) { + Some(arg_rel) => { + let composed = compose_sub_value_relations( + arg_rel.clone(), + callee_rel.clone(), + ); + match (*composed.clone()).clone() { + SubValueRelation::SubValueUnknown => { + inner.clone() + } + _ => match v1_rt::map_get( + &inner, + pname.clone(), + ) { + Some(existing) => v1_rt::rc_map_insert( + inner.clone(), + pname.clone(), + meet_sub_value( + existing.clone(), + composed.clone(), + ), + ), + None => v1_rt::rc_map_insert( + inner.clone(), + pname.clone(), + composed.clone(), + ), + }, + } + } + None => inner.clone(), + } + }, + ) + } + None => acc.clone(), + } + } + None => acc.clone(), + } + }, + ), + None => v1_rt::rc_empty_map::>(), + }, + None => v1_rt::rc_empty_map::>(), + } +} + +pub fn classify_body_per_field( + expr: Rc, + param_names: Rc>, + param_types: Rc>, + type_env: Rc, + func_env: Rc, + let_prov: Rc>>>>, +) -> Rc>>>> { + { + let unwrapped = unwrap_body_terminal(expr.clone(), let_prov.clone(), type_env.clone()); + let terminal = unwrapped.expr.clone(); + let terminal_prov = unwrapped.let_prov.clone(); + classify_terminal_per_field( + terminal.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + terminal_prov.clone(), + ) + } +} + +pub fn classify_terminal_per_field( + expr: Rc, + param_names: Rc>, + param_types: Rc>, + type_env: Rc, + func_env: Rc, + let_prov: Rc>>>>, +) -> Rc>>>> { + match (*expr.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ + let mut __result = Vec::new(); + for fi in expr.children.clone().iter().cloned() { + __result.push(classify_body_provenance( + field_init_node_value(fi.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + )); + } + __result + }), + ExprData::ExprMatch => { + let arm_results = Rc::new({ + let mut __result = Vec::new(); + for arm in match_arm_nodes(expr.clone()).iter().cloned() { + __result.push({ + let arm_unwrapped = unwrap_body_terminal( + arm_body(arm.clone()), + let_prov.clone(), + type_env.clone(), + ); + match (*arm_unwrapped.expr.clone().expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ + let mut __result = Vec::new(); + for fi in + arm_unwrapped.expr.clone().children.clone().iter().cloned() + { + __result.push(classify_body_provenance( + field_init_node_value(fi.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + arm_unwrapped.let_prov.clone(), + )); + } + __result + }), + _ => Rc::new(vec![]), + } + }); + } + __result + }); + meet_per_field_results(arm_results.clone()) + } + ExprData::ExprIf => { + let then_unwrapped = unwrap_body_terminal( + if_then_branch(expr.clone()), + let_prov.clone(), + type_env.clone(), + ); + let then_result = match (*then_unwrapped.expr.clone().expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ + let mut __result = Vec::new(); + for fi in then_unwrapped.expr.clone().children.clone().iter().cloned() { + __result.push(classify_body_provenance( + field_init_node_value(fi.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + then_unwrapped.let_prov.clone(), + )); + } + __result + }), + _ => Rc::new(vec![]), + }; + match if_else_branch(expr.clone()) { + Some(else_expr) => { + let else_unwrapped = + unwrap_body_terminal(else_expr.clone(), let_prov.clone(), type_env.clone()); + let else_result = match (*else_unwrapped.expr.clone().expr_data.clone()).clone() + { + ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ + let mut __result = Vec::new(); + for fi in else_unwrapped.expr.clone().children.clone().iter().cloned() { + __result.push(classify_body_provenance( + field_init_node_value(fi.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + else_unwrapped.let_prov.clone(), + )); + } + __result + }), + _ => Rc::new(vec![]), + }; + meet_per_field_results(Rc::new(vec![then_result.clone(), else_result.clone()])) + } + None => then_result.clone(), + } + } + _ => Rc::new(vec![]), + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BodyTerminal { + pub expr: Rc, + pub let_prov: Rc>>>>, +} + +pub fn unwrap_body_terminal( + expr: Rc, + let_prov: Rc>>>>, + type_env: Rc, +) -> Rc { + match (*expr.expr_data.clone()).clone() { + ExprData::ExprBlock => match expr.children.clone().last().cloned() { + Some(last_stmt) => Rc::new(BodyTerminal { + expr: last_stmt.clone(), + let_prov: let_prov.clone(), + }), + None => Rc::new(BodyTerminal { + expr: expr.clone(), + let_prov: let_prov.clone(), + }), + }, + _ => Rc::new(BodyTerminal { + expr: expr.clone(), + let_prov: let_prov.clone(), + }), + } +} + +pub fn meet_per_field_results( + results: Rc>>>>>>, +) -> Rc>>>> { + match results.clone().first().cloned() { + None => Rc::new(vec![]), + Some(first_result) => { + if ((first_result.clone().len() as i64) == 0) { + Rc::new(vec![]) + } else { + { + let all_same_count = { + let mut __all = true; + for r in results.clone().iter().cloned() { + if !((r.clone().len() as i64) == (first_result.clone().len() as i64)) { + __all = false; + break; + } + } + __all + }; + if !all_same_count.clone() { + Rc::new(vec![]) + } else { + Rc::new({ + let mut __result = Vec::new(); + for pair in Rc::new( + first_result + .clone() + .iter() + .cloned() + .enumerate() + .map(|(i, v)| (i as i64, v)) + .collect::>(), + ) + .iter() + .cloned() + { + __result.push({ + let idx = pair.0.clone(); + let field_provs = Rc::new({ + let mut __result = Vec::new(); + for r in results.clone().iter().cloned() { + __result.push( + match r + .clone() + .iter() + .cloned() + .skip(idx.clone() as usize) + .next() + { + Some(m) => m.clone(), + None => empty_prov_map(), + }, + ); + } + __result + }); + meet_body_provenance_maps(field_provs.clone()) + }); + } + __result + }) + } + } + } + } + } +} + +pub fn empty_prov_map() -> Rc>> { + v1_rt::rc_empty_map::>() +} + +pub fn meet_body_provenance_maps( + provs: Rc>>>>, +) -> Rc>> { + match provs.clone().first().cloned() { + None => empty_prov_map(), + Some(first_prov) => Rc::new( + provs + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + first_prov.clone(), + |acc: Rc>>, + prov: Rc>>| { + intersect_prov_maps(acc, prov.clone()) + }, + ), + } +} + +pub fn intersect_prov_maps( + a: Rc>>, + b: Rc>>, +) -> Rc>> { + Rc::new(v1_rt::map_keys(&a)).iter().cloned().fold( + empty_prov_map(), + |result: Rc>>, key: String| match v1_rt::map_get( + &b, + key.clone(), + ) { + Some(b_rel) => match v1_rt::map_get(&a, key.clone()) { + Some(a_rel) => v1_rt::rc_map_insert( + result.clone(), + key.clone(), + meet_sub_value(a_rel.clone(), b_rel.clone()), + ), + None => result.clone(), + }, + None => result.clone(), + }, + ) +} + +pub fn arm_ctx_from_variant_provenance( + arm_node: Rc, + sig: Rc, + scrut: Rc, + ctx: Rc, +) -> Option> { + match (*arm_pattern(arm_node.clone())).clone() { + MatchPattern::VariantPattern { + name: vname, + field_bindings: bindings, + .. + } => match v1_rt::map_get(&sig.variant_provenance.clone(), vname.clone()) { + Some(variant_field_map) => { + let call_args = + call_args_by_name(scrut.clone(), ctx.type_env.clone().source_indices.clone()); + let extended = bindings.clone().iter().cloned().fold( + ctx.clone(), + |c: Rc, fb: Rc| { + let field_label = field_binding_name_at( + fb.clone(), + ctx.type_env.clone().source_indices.clone(), + ); + let bind_name = match (*field_binding_pattern(fb.clone())).clone() { + MatchPattern::Bind { + declaration: declaration, + .. + } => declaration.name.clone(), + _ => "".to_string(), + }; + if ((bind_name.clone() == "".to_string()) + || (field_label.clone() == "".to_string())) + { + c.clone() + } else { + match v1_rt::map_get(&variant_field_map, field_label.clone()) { + Some(param_map) => { + let composed = compose_callee_param_map( + param_map.clone(), + call_args.clone(), + c.param_order.clone(), + c.param_names.clone(), + c.type_env.clone(), + c.func_env.clone(), + v1_rt::rc_empty_map::< + String, + Rc>>, + >(), + ); + let all_rels = Rc::new({ + let mut __result = Vec::new(); + for k in Rc::new(v1_rt::map_keys(&composed)).iter().cloned() + { + __result.push( + match v1_rt::map_get(&composed, k.clone()) { + Some(r) => r.clone(), + None => { + Rc::new(SubValueRelation::SubValueUnknown) + } + }, + ); + } + __result + }); + let best = merge_argument_relations(all_rels.clone()); + match (*best.clone()).clone() { + SubValueRelation::SubValueUnknown => c.clone(), + _ => Rc::new(DescentContext { + fn_name: c.fn_name.clone(), + param_names: c.param_names.clone(), + param_order: c.param_order.clone(), + type_env: c.type_env.clone(), + sub_value_vars: v1_rt::rc_map_insert( + c.sub_value_vars.clone(), + bind_name.clone(), + best.clone(), + ), + size_aliases: c.size_aliases.clone(), + scope_locals: c.scope_locals.clone(), + func_env: c.func_env.clone(), + per_field_vars: c.per_field_vars.clone(), + }), + } + } + None => c.clone(), + } + } + }, + ); + Some(extended.clone()) + } + None => None, + }, + _ => None, + } +} + +pub fn compose_callee_param_map( + callee_prov: Rc>>, + arg_by_name: Rc>>, + param_names: Rc>, + param_types: Rc>, + type_env: Rc, + func_env: Rc, + let_prov: Rc>>>>, +) -> Rc>> { + Rc::new(v1_rt::map_keys(&callee_prov)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, callee_pname: String| match v1_rt::map_get( + &callee_prov, + callee_pname.clone(), + ) { + Some(callee_rel) => match v1_rt::map_get(&arg_by_name, callee_pname.clone()) { + Some(arg) => { + let arg_prov = classify_body_provenance( + arg.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + Rc::new(v1_rt::map_keys(&arg_prov)).iter().cloned().fold( + acc.clone(), + |inner: Rc>>, pname: String| { + match v1_rt::map_get(&arg_prov, pname.clone()) { + Some(arg_rel) => { + let composed = compose_sub_value_relations( + arg_rel.clone(), + callee_rel.clone(), + ); + match (*composed.clone()).clone() { + SubValueRelation::SubValueUnknown => inner.clone(), + _ => v1_rt::rc_map_insert( + inner.clone(), + pname.clone(), + composed.clone(), + ), + } + } + None => inner.clone(), + } + }, + ) + } + None => acc.clone(), + }, + None => acc.clone(), + }, + ) +} + +pub fn compose_output_relations( + arg_rel: Rc, + callee_rel: Rc, +) -> Rc { + compose_sub_value_relations(arg_rel.clone(), callee_rel.clone()) +} + +pub fn compute_variant_provenance( + body: Rc, + return_type: Rc, + params: Rc>>, + type_env: Rc, + func_env: Rc, +) -> Rc>>>>>> { + { + let rt_name = authored_name_at(type_env.source_indices.clone(), return_type.clone()); + let rt_def = lookup_type_by_name(type_env.clone(), rt_name.clone()); + match rt_def.clone() { + Some(def_node) => match def_node.connective.clone() { + Connective::Disj => { + let param_names = Rc::new({ + let mut __result = Vec::new(); + for p in params.clone().iter().cloned() { + __result.push(param_node_name_at( + p.clone(), + type_env.source_indices.clone(), + )); + } + __result + }); + let param_types = params.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, p: Rc| { + let pname = + param_node_name_at(p.clone(), type_env.source_indices.clone()); + let ptype = + resolved_type_name(p.clone(), type_env.source_indices.clone()); + if ((pname.clone() != "".to_string()) + && (ptype.clone() != "".to_string())) + { + v1_rt::rc_map_insert(acc.clone(), pname.clone(), ptype.clone()) + } else { + acc.clone() + } + }, + ); + collect_variant_constructors( + body.clone(), + rt_name.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + v1_rt::rc_empty_map::>>>(), + v1_rt::rc_empty_map::< + String, + Rc>>>>, + >(), + ) + } + _ => v1_rt::rc_empty_map::< + String, + Rc>>>>, + >(), + }, + None => v1_rt::rc_empty_map::< + String, + Rc>>>>, + >(), + } + } +} + +pub fn collect_variant_constructors( + body: Rc, + parent_enum: String, + param_names: Rc>, + param_types: Rc>, + type_env: Rc, + func_env: Rc, + let_prov: Rc>>>>, + acc: Rc>>>>>>, +) -> Rc>>>>>> { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match (*body.expr_data.clone()).clone() { + ExprData::ExprRecordLit { + parent_enum: pe, .. + } => match pe.clone() { + Some(enum_name) => { + if (enum_name.clone() == parent_enum.clone()) { + { + let variant_name = body.name.clone(); + let field_prov_map = body.children.clone().iter().cloned().fold( + v1_rt::rc_empty_map::< + String, + Rc>>, + >(), + |m: Rc< + HashMap>>>, + >, + fi: Rc| { + let fname = field_init_node_name_at( + fi.clone(), + type_env.source_indices.clone(), + ); + let fprov = classify_body_provenance( + field_init_node_value(fi.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + if (fname.clone() != "".to_string()) { + v1_rt::rc_map_insert( + m.clone(), + fname.clone(), + fprov.clone(), + ) + } else { + m.clone() + } + }, + ); + match v1_rt::map_get(&acc, variant_name.clone()) { + Some(existing) => { + let merged = merge_field_prov_maps( + existing.clone(), + field_prov_map.clone(), + ); + v1_rt::rc_map_insert( + acc.clone(), + variant_name.clone(), + merged.clone(), + ) + } + None => v1_rt::rc_map_insert( + acc.clone(), + variant_name.clone(), + field_prov_map.clone(), + ), + } + } + } else { + acc.clone() + } + } + None => acc.clone(), + }, + ExprData::ExprCall { .. } => { + let callee = expr_call_func_at(body.clone(), type_env.source_indices.clone()); + match func_sig_if_resolved(lookup_func_sig( + func_env.clone(), + type_env.clone(), + callee.clone(), + )) { + Some(sig) => { + if ((authored_name_at( + type_env.source_indices.clone(), + sig.inferred.clone(), + ) == parent_enum.clone()) + && ((Rc::new(v1_rt::map_keys(&sig.variant_provenance.clone())).len() + as i64) + > 0)) + { + { + let call_args = call_args_by_name( + body.clone(), + type_env.source_indices.clone(), + ); + Rc::new(v1_rt::map_keys(&sig.variant_provenance.clone())).iter().cloned().fold(acc.clone(), |variant_acc: Rc>>>>>>, variant_name: String| match v1_rt::map_get(&sig.variant_provenance.clone(), variant_name.clone()) { + Some(field_map) => { + let composed_field_map = Rc::new(v1_rt::map_keys(&field_map)).iter().cloned().fold(v1_rt::rc_empty_map::>>>(), |fm_acc: Rc>>>>, field_name: String| match v1_rt::map_get(&field_map, field_name.clone()) { + Some(param_map) => { + let composed = compose_callee_param_map(param_map.clone(), call_args.clone(), param_names.clone(), param_types.clone(), type_env.clone(), func_env.clone(), let_prov.clone()); +if ((Rc::new(v1_rt::map_keys(&composed)).len() as i64) > 0) { + v1_rt::rc_map_insert(fm_acc.clone(), field_name.clone(), composed.clone()) + } else { + fm_acc.clone() + } +}, + None => fm_acc.clone(), +}); +if ((Rc::new(v1_rt::map_keys(&composed_field_map)).len() as i64) > 0) { + match v1_rt::map_get(&variant_acc, variant_name.clone()) { + Some(existing) => v1_rt::rc_map_insert(variant_acc.clone(), variant_name.clone(), merge_field_prov_maps(existing.clone(), composed_field_map.clone())), + None => v1_rt::rc_map_insert(variant_acc.clone(), variant_name.clone(), composed_field_map.clone()), +} + } else { + variant_acc.clone() + } +}, + None => variant_acc.clone(), +}) + } + } else { + acc.clone() + } + } + None => acc.clone(), + } + } + ExprData::ExprMatch => match_arm_nodes(body.clone()).iter().cloned().fold( + acc.clone(), + |a: Rc< + HashMap>>>>>, + >, + arm: Rc| { + collect_variant_constructors( + arm_body(arm.clone()), + parent_enum.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + a, + ) + }, + ), + ExprData::ExprIf => { + let then_acc = collect_variant_constructors( + if_then_branch(body.clone()), + parent_enum.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + acc.clone(), + ); + match if_else_branch(body.clone()) { + Some(eb) => collect_variant_constructors( + eb.clone(), + parent_enum.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + then_acc.clone(), + ), + None => then_acc.clone(), + } + } + ExprData::ExprLet => match let_body(body.clone()) { + Some(b) => { + let bname = let_binding_name_at(body.clone(), type_env.source_indices.clone()); + let value_prov = classify_body_provenance( + let_value(body.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + let_prov.clone(), + ); + let new_lp = + v1_rt::rc_map_insert(let_prov.clone(), bname.clone(), value_prov.clone()); + collect_variant_constructors( + b.clone(), + parent_enum.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + new_lp.clone(), + acc.clone(), + ) + } + None => acc.clone(), + }, + ExprData::ExprBlock => { + let stmts = body.children.clone(); + let stmt_count = (stmts.clone().len() as i64); + if (stmt_count.clone() == 0) { + acc.clone() + } else { + { + let final_lp = Rc::new( + stmts + .clone() + .iter() + .cloned() + .take((stmt_count.clone() - 1) as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + let_prov.clone(), + |lp: Rc>>>>, + stmt: Rc| match (*stmt + .expr_data + .clone()) + .clone() + { + ExprData::ExprLet => { + let bname = let_binding_name_at( + stmt.clone(), + type_env.source_indices.clone(), + ); + let vprov = classify_body_provenance( + let_value(stmt.clone()), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + lp.clone(), + ); + v1_rt::rc_map_insert(lp.clone(), bname.clone(), vprov.clone()) + } + _ => lp.clone(), + }, + ); + match stmts + .clone() + .iter() + .cloned() + .skip((stmt_count.clone() - 1) as usize) + .next() + { + Some(last) => collect_variant_constructors( + last.clone(), + parent_enum.clone(), + param_names.clone(), + param_types.clone(), + type_env.clone(), + func_env.clone(), + final_lp.clone(), + acc.clone(), + ), + None => acc.clone(), + } + } + } + } + _ => acc.clone(), + } + }) +} + +pub fn merge_field_prov_maps( + a: Rc>>>>, + b: Rc>>>>, +) -> Rc>>>> { + { + let from_a = Rc::new(v1_rt::map_keys(&a)).iter().cloned().fold( + v1_rt::rc_empty_map::>>>(), + |result: Rc>>>>, + fname: String| match v1_rt::map_get(&a, fname.clone()) { + Some(a_prov) => match v1_rt::map_get(&b, fname.clone()) { + Some(b_prov) => v1_rt::rc_map_insert( + result.clone(), + fname.clone(), + union_prov_maps(a_prov.clone(), b_prov.clone()), + ), + None => v1_rt::rc_map_insert(result.clone(), fname.clone(), a_prov.clone()), + }, + None => result.clone(), + }, + ); + Rc::new(v1_rt::map_keys(&b)).iter().cloned().fold( + from_a.clone(), + |result: Rc>>>>, + fname: String| { + if (v1_rt::map_get(&result, fname.clone()) != None) { + result.clone() + } else { + match v1_rt::map_get(&b, fname.clone()) { + Some(b_prov) => { + v1_rt::rc_map_insert(result.clone(), fname.clone(), b_prov.clone()) + } + None => result.clone(), + } + } + }, + ) + } +} + +pub fn union_prov_maps( + a: Rc>>, + b: Rc>>, +) -> Rc>> { + { + let from_a = Rc::new(v1_rt::map_keys(&a)).iter().cloned().fold( + empty_prov_map(), + |result: Rc>>, key: String| match v1_rt::map_get( + &a, + key.clone(), + ) { + Some(a_rel) => match v1_rt::map_get(&b, key.clone()) { + Some(b_rel) => v1_rt::rc_map_insert( + result.clone(), + key.clone(), + join_sub_value(a_rel.clone(), b_rel.clone()), + ), + None => v1_rt::rc_map_insert(result.clone(), key.clone(), a_rel.clone()), + }, + None => result.clone(), + }, + ); + Rc::new(v1_rt::map_keys(&b)).iter().cloned().fold( + from_a.clone(), + |result: Rc>>, key: String| { + if (v1_rt::map_get(&result, key.clone()) != None) { + result.clone() + } else { + match v1_rt::map_get(&b, key.clone()) { + Some(b_rel) => { + v1_rt::rc_map_insert(result.clone(), key.clone(), b_rel.clone()) + } + None => result.clone(), + } + } + }, + ) + } +} + +pub fn populate_output_provenance( + typed_items: Rc>>, + func_env: Rc, + type_env: Rc, + locals: Rc>>, +) -> Rc { + { + let updated_local = typed_items.clone().iter().cloned().fold( + func_env.local.clone(), + |acc: Rc>>, item: Rc| { + if ((item.params.clone().len() as i64) > 0) { + { + let fn_name = + authored_name_at(type_env.source_indices.clone(), item.clone()); + if (is_child_accessor_in_model(fn_name.clone()) + || is_tree_size_reducing(fn_name.clone())) + { + match item.params.clone().first().cloned() { + Some(first_param) => { + let pname = param_node_name_at( + first_param.clone(), + type_env.source_indices.clone(), + ); + let ptype = resolved_type_name( + first_param.clone(), + type_env.source_indices.clone(), + ); + if ((ptype.clone() != "".to_string()) + && (pname.clone() != "".to_string())) + { + { + let fields = inductive_fields_for( + type_env.clone(), + ptype.clone(), + ); + let list_field = Rc::new({ + let mut __result = Vec::new(); + for f in fields.clone().iter().cloned() { + if match f.shape.clone() { + RecursionShape::ListRecursion => true, + _ => false, + } { + __result.push(f); + } + } + __result + }) + .first() + .cloned(); + match list_field.clone() { + Some(ind_field) => { + let relation = + Rc::new(SubValueRelation::StrictSubValue { + field: ind_field.clone(), + factor: Rc::new( + ShrinkFactor::UnitShrink, + ), + }); + let provenance = + Rc::new(vec![v1_rt::rc_map_insert( + v1_rt::rc_empty_map::< + String, + Rc, + >( + ), + pname.clone(), + relation.clone(), + )]); + match v1_rt::map_get(&acc, fn_name.clone()) { + Some(sig) => v1_rt::rc_map_insert( + acc.clone(), + fn_name.clone(), + Rc::new(ResolvedFuncSig { + name: sig.name.clone(), + params: sig.params.clone(), + inferred: sig.inferred.clone(), + is_async: sig.is_async.clone(), + output_provenance: provenance + .clone(), + variant_provenance: sig + .variant_provenance + .clone(), + }), + ), + None => acc.clone(), + } + } + None => acc.clone(), + } + } + } else { + acc.clone() + } + } + None => acc.clone(), + } + } else { + match item.body.clone() { + Some(body) => { + if !expr_has_self_call( + body.clone(), + fn_name.clone(), + type_env.source_indices.clone(), + ) { + { + let working_env = Rc::new(ResolvedFuncEnv { + name: func_env.name.clone(), + local: acc.clone(), + parents: func_env.parents.clone(), + }); + let provenance = infer_output_provenance( + body.clone(), + item.params.clone(), + type_env.clone(), + locals.clone(), + working_env.clone(), + ); + let variant_prov = + match item.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: rt, + .. + }) => compute_variant_provenance( + body.clone(), + rt.clone(), + item.params.clone(), + type_env.clone(), + working_env.clone(), + ), + _ => v1_rt::rc_empty_map::< + String, + Rc< + HashMap< + String, + Rc< + HashMap< + String, + Rc, + >, + >, + >, + >, + >( + ), + }; + let has_scalar = + ((provenance.clone().len() as i64) > 0); + let has_variant = + ((Rc::new(v1_rt::map_keys(&variant_prov)).len() + as i64) + > 0); + if (has_scalar.clone() || has_variant.clone()) { + match v1_rt::map_get(&acc, fn_name.clone()) { + Some(sig) => v1_rt::rc_map_insert( + acc.clone(), + fn_name.clone(), + Rc::new(ResolvedFuncSig { + name: sig.name.clone(), + params: sig.params.clone(), + inferred: sig.inferred.clone(), + is_async: sig.is_async.clone(), + output_provenance: if has_scalar.clone() + { + provenance.clone() + } else { + sig.output_provenance.clone() + }, + variant_provenance: if has_variant + .clone() + { + variant_prov.clone() + } else { + sig.variant_provenance.clone() + }, + }), + ), + None => acc.clone(), + } + } else { + acc.clone() + } + } + } else { + acc.clone() + } + } + None => acc.clone(), + } + } + } + } else { + acc.clone() + } + }, + ); + Rc::new(ResolvedFuncEnv { + name: func_env.name.clone(), + local: updated_local.clone(), + parents: func_env.parents.clone(), + }) + } +} + +pub fn annotate_descent_evidence( + body: Rc, + fn_name: String, + params: Rc>>, + type_env: Rc, + scope_locals: Rc>>, + func_env: Rc, +) -> Rc { + { + let param_name_map = params.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, p: Rc| { + let pname = param_node_name_at(p.clone(), type_env.source_indices.clone()); + let ptype = resolved_type_name(p.clone(), type_env.source_indices.clone()); + v1_rt::rc_map_insert(acc, pname.clone(), ptype.clone()) + }, + ); + let param_order_list = Rc::new({ + let mut __result = Vec::new(); + for p in params.clone().iter().cloned() { + __result.push(param_node_name_at( + p.clone(), + type_env.source_indices.clone(), + )); + } + __result + }); + let ctx = Rc::new(DescentContext { + fn_name: fn_name.clone(), + param_names: param_name_map.clone(), + param_order: param_order_list.clone(), + type_env: type_env.clone(), + sub_value_vars: v1_rt::rc_empty_map::>(), + size_aliases: v1_rt::rc_empty_map::>(), + scope_locals: scope_locals.clone(), + func_env: func_env.clone(), + per_field_vars: v1_rt::rc_empty_map::>>>( + ), + }); + annotate_descent(body.clone(), ctx.clone()) + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct InferPropertiesResult { + pub props: Rc>>, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct InferTransportResult { + pub transport: Option>, + pub diagnostics: Rc>>, +} + +pub fn infer_property_values( + props: Rc>>, + scope: Rc, +) -> Rc { + { + let results = Rc::new({ + let mut __result = Vec::new(); + for p in props.clone().iter().cloned() { + __result.push({ + let val = field_init_node_value(p.clone()); + let val_result = infer_expr(val.clone(), scope.clone(), None); + ( + Rc::new(Node { + name: p.name.clone(), + span: p.span.clone(), + ident_span: p.ident_span.clone(), + children: Rc::new(vec![val_result.typed.clone()]), + connective: p.connective.clone(), + params: p.params.clone(), + inferred: p.inferred.clone(), + return_cardinality: p.return_cardinality.clone(), + uses: p.uses.clone(), + body: p.body.clone(), + transport: p.transport.clone(), + properties: p.properties.clone(), + type_annotation: p.type_annotation.clone(), + is_self_recursive: p.is_self_recursive.clone(), + has_non_tail_self_call: p.has_non_tail_self_call.clone(), + match_pattern: p.match_pattern.clone(), + expr_data: p.expr_data.clone(), + ident: None, + }), + val_result.diagnostics.clone(), + ) + }); + } + __result + }); + Rc::new(InferPropertiesResult { + props: Rc::new({ + let mut __result = Vec::new(); + for r in results.clone().iter().cloned() { + __result.push(r.0.clone()); + } + __result + }), + diagnostics: Rc::new({ + let mut __result = Vec::new(); + for r in results.clone().iter().cloned() { + __result.extend((*r.1.clone()).iter().cloned()); + } + __result + }), + }) + } +} + +pub fn infer_auth_source_properties( + props: Rc>>, + scope: Rc, +) -> Rc { + { + let results = Rc::new({ + let mut __result = Vec::new(); + for p in props.clone().iter().cloned() { + __result.push( + if (field_init_node_name_at( + p.clone(), + scope.type_env.clone().source_indices.clone(), + ) == "svc_auth_source".to_string()) + { + { + let val = field_init_node_value(p.clone()); + let val_result = infer_expr(val.clone(), scope.clone(), None); + ( + Rc::new(Node { + name: p.name.clone(), + span: p.span.clone(), + ident_span: p.ident_span.clone(), + children: Rc::new(vec![val_result.typed.clone()]), + connective: p.connective.clone(), + params: p.params.clone(), + inferred: p.inferred.clone(), + return_cardinality: p.return_cardinality.clone(), + uses: p.uses.clone(), + body: p.body.clone(), + transport: p.transport.clone(), + properties: p.properties.clone(), + type_annotation: p.type_annotation.clone(), + is_self_recursive: p.is_self_recursive.clone(), + has_non_tail_self_call: p.has_non_tail_self_call.clone(), + match_pattern: p.match_pattern.clone(), + expr_data: p.expr_data.clone(), + ident: None, + }), + val_result.diagnostics.clone(), + ) + } + } else { + (p.clone(), Rc::new(vec![])) + }, + ); + } + __result + }); + Rc::new(InferPropertiesResult { + props: Rc::new({ + let mut __result = Vec::new(); + for r in results.clone().iter().cloned() { + __result.push(r.0.clone()); + } + __result + }), + diagnostics: Rc::new({ + let mut __result = Vec::new(); + for r in results.clone().iter().cloned() { + __result.extend((*r.1.clone()).iter().cloned()); + } + __result + }), + }) + } +} + +pub fn infer_transport_node( + transport: Option>, + scope: Rc, +) -> Rc { + match transport.clone() { + None => Rc::new(InferTransportResult { + transport: None, + diagnostics: Rc::new(vec![]), + }), + Some(t) => { + let prop_result = infer_property_values(t.properties.clone(), scope.clone()); + Rc::new(InferTransportResult { + transport: Some(Rc::new(Node { + name: t.name.clone(), + span: t.span.clone(), + ident_span: t.ident_span.clone(), + children: t.children.clone(), + connective: t.connective.clone(), + params: t.params.clone(), + inferred: t.inferred.clone(), + return_cardinality: t.return_cardinality.clone(), + uses: t.uses.clone(), + body: t.body.clone(), + transport: t.transport.clone(), + properties: prop_result.props.clone(), + type_annotation: t.type_annotation.clone(), + is_self_recursive: t.is_self_recursive.clone(), + has_non_tail_self_call: t.has_non_tail_self_call.clone(), + match_pattern: t.match_pattern.clone(), + expr_data: t.expr_data.clone(), + ident: None, + })), + diagnostics: prop_result.diagnostics.clone(), + }) + } + } +} + +pub fn infer_item(item: Rc, scope: Rc) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + let typed_anno = item.type_annotation.clone(); + let transport_scope = if ((item.params.clone().len() as i64) > 0) { + build_params_scope(scope.clone(), item.params.clone()) + } else { + scope.clone() + }; + let transport_result = + infer_transport_node(item.transport.clone(), transport_scope.clone()); + let typed_transport = transport_result.transport.clone(); + let transport_diags = transport_result.diagnostics.clone(); + let props_result = infer_auth_source_properties(item.properties.clone(), scope.clone()); + let typed_properties = props_result.props.clone(); + let props_diags = props_result.diagnostics.clone(); + if ((item.connective.clone() != Connective::NoConnective) + && (item.transport.clone() == None)) + { + Rc::new(TypedItemResult { + item: Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new({ + let mut __result = Vec::new(); + for c in item.children.clone().iter().cloned() { + __result.push(infer_item(c.clone(), scope.clone()).item.clone()); + } + __result + }), + params: item.params.clone(), + inferred: Some(Rc::new(InferredNode::Resolved { node: unit_type() })), + return_cardinality: item.return_cardinality.clone(), + uses: item.uses.clone(), + body: None, + connective: item.connective.clone(), + transport: typed_transport.clone(), + properties: typed_properties.clone(), + type_annotation: typed_anno.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + diagnostics: v1_rt::concat(transport_diags.clone(), props_diags.clone()), + }) + } else { + if ((item.body.clone() != None) && ((item.params.clone().len() as i64) > 0)) { + { + let fn_scope = build_params_scope(scope.clone(), item.params.clone()); + let fn_scope = item.uses.clone().iter().cloned().fold( + fn_scope.clone(), + |s: Rc, u: Rc| { + extend_scope( + s, + resource_use_name_at( + u.clone(), + scope.type_env.clone().source_indices.clone(), + ), + resource_use_resource(u.clone()), + Rc::new(SubValueRelation::SubValueUnknown), + ) + }, + ); + let fn_decl_name = authored_name_at( + scope.type_env.clone().source_indices.clone(), + item.clone(), + ); + let fn_scope = Rc::new(InferScope { + type_env: fn_scope.type_env.clone(), + func_env: fn_scope.func_env.clone(), + locals: fn_scope.locals.clone(), + body_locals: fn_scope.body_locals.clone(), + match_bound_names: fn_scope.match_bound_names.clone(), + module_name: fn_scope.module_name.clone(), + service_registry: fn_scope.service_registry.clone(), + item_registry: fn_scope.item_registry.clone(), + caller_decl_name: fn_decl_name.clone(), + lambda_param_provenance: fn_scope.lambda_param_provenance.clone(), + }); + let fn_return_expected = if (item.inferred.clone() != None) { + Some(resolved_type(item.clone())) + } else { + None + }; + let body_result = infer_expr( + item.body.clone().clone().unwrap(), + fn_scope.clone(), + fn_return_expected.clone(), + ); + let body_typed = body_result.typed.clone(); + let body_diags = body_result.diagnostics.clone(); + let inferred_ret = if (item.inferred.clone() != None) { + item.inferred.clone() + } else { + body_typed.inferred.clone() + }; + let return_conformance_diags = if (item.inferred.clone() != None) { + v1_rt::concat( + declared_type_conformance_diags( + declared_return_type_node(item.clone()), + resolved_type(body_typed.clone()), + item.body.clone().clone().unwrap().span.clone(), + scope.clone(), + ), + explicit_return_conformance_diags( + declared_return_type_node(item.clone()), + body_typed.clone(), + scope.clone(), + ), + ) + } else { + Rc::new(vec![]) + }; + let is_recursive = expr_has_self_call( + body_typed.clone(), + authored_name_at( + scope.type_env.clone().source_indices.clone(), + item.clone(), + ), + scope.type_env.clone().source_indices.clone(), + ); + let annotated_body = if is_recursive.clone() { + annotate_descent_evidence( + body_typed.clone(), + authored_name_at( + scope.type_env.clone().source_indices.clone(), + item.clone(), + ), + item.params.clone(), + scope.type_env.clone(), + fn_scope.locals.clone(), + scope.func_env.clone(), + ) + } else { + body_typed.clone() + }; + Rc::new(TypedItemResult { + item: Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new({ + let mut __result = Vec::new(); + for c in item.children.clone().iter().cloned() { + __result + .push(infer_item(c.clone(), scope.clone()).item.clone()); + } + __result + }), + params: item.params.clone(), + inferred: inferred_ret.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: item.uses.clone(), + body: Some(annotated_body.clone()), + connective: Connective::NoConnective, + transport: typed_transport.clone(), + properties: typed_properties.clone(), + type_annotation: typed_anno.clone(), + is_self_recursive: is_recursive.clone(), + has_non_tail_self_call: expr_has_non_tail_self_call( + body_typed.clone(), + authored_name_at( + scope.type_env.clone().source_indices.clone(), + item.clone(), + ), + true, + scope.type_env.clone().source_indices.clone(), + ), + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + diagnostics: v1_rt::concat( + v1_rt::concat(transport_diags.clone(), props_diags.clone()), + v1_rt::concat(body_diags.clone(), return_conformance_diags.clone()), + ), + }) + } + } else { + if (((item.body.clone() != None) && ((item.params.clone().len() as i64) == 0)) + && (item.inferred.clone() != None)) + { + { + let fn_decl_name = authored_name_at( + scope.type_env.clone().source_indices.clone(), + item.clone(), + ); + let fn_scope = Rc::new(InferScope { + type_env: scope.type_env.clone(), + func_env: scope.func_env.clone(), + locals: scope.locals.clone(), + body_locals: scope.body_locals.clone(), + match_bound_names: scope.match_bound_names.clone(), + module_name: scope.module_name.clone(), + service_registry: scope.service_registry.clone(), + item_registry: scope.item_registry.clone(), + caller_decl_name: fn_decl_name.clone(), + lambda_param_provenance: scope.lambda_param_provenance.clone(), + }); + let body_result = infer_expr( + item.body.clone().clone().unwrap(), + fn_scope.clone(), + Some(resolved_type(item.clone())), + ); + let body_typed = body_result.typed.clone(); + let body_diags = v1_rt::concat( + body_result.diagnostics.clone(), + v1_rt::concat( + declared_type_conformance_diags( + declared_return_type_node(item.clone()), + resolved_type(body_typed.clone()), + item.body.clone().clone().unwrap().span.clone(), + scope.clone(), + ), + explicit_return_conformance_diags( + declared_return_type_node(item.clone()), + body_typed.clone(), + scope.clone(), + ), + ), + ); + Rc::new(TypedItemResult { + item: Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new(vec![]), + params: Rc::new(vec![]), + inferred: item.inferred.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: Some(body_typed.clone()), + connective: Connective::NoConnective, + transport: typed_transport.clone(), + properties: typed_properties.clone(), + type_annotation: typed_anno.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + diagnostics: v1_rt::concat( + v1_rt::concat(transport_diags.clone(), props_diags.clone()), + body_diags.clone(), + ), + }) + } + } else { + if ((item.body.clone() != None) && ((item.params.clone().len() as i64) == 0)) { + { + let data_expected = if (item.type_annotation.clone() != None) { + Some(item.type_annotation.clone().clone().unwrap()) + } else { + None + }; + let val_result = infer_expr( + item.body.clone().clone().unwrap(), + scope.clone(), + data_expected.clone(), + ); + let val_typed = val_result.typed.clone(); + let val_diags = if (item.type_annotation.clone() != None) { + v1_rt::concat( + val_result.diagnostics.clone(), + declared_type_conformance_diags( + item.type_annotation.clone().clone().unwrap(), + resolved_type(val_typed.clone()), + item.body.clone().clone().unwrap().span.clone(), + scope.clone(), + ), + ) + } else { + val_result.diagnostics.clone() + }; + let inferred_ret = if (item.type_annotation.clone() != None) { + Some(Rc::new(InferredNode::Resolved { + node: item.type_annotation.clone().clone().unwrap(), + })) + } else { + val_typed.inferred.clone() + }; + Rc::new(TypedItemResult { + item: Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new(vec![]), + params: Rc::new(vec![]), + inferred: inferred_ret.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: Some(val_typed.clone()), + connective: Connective::NoConnective, + transport: typed_transport.clone(), + properties: typed_properties.clone(), + type_annotation: typed_anno.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + diagnostics: v1_rt::concat( + v1_rt::concat(transport_diags.clone(), props_diags.clone()), + val_diags.clone(), + ), + }) + } + } else { + if (((item.params.clone().len() as i64) > 0) && (item.body.clone() == None)) + { + Rc::new(TypedItemResult { + item: Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new({ + let mut __result = Vec::new(); + for c in item.children.clone().iter().cloned() { + __result.push( + infer_item(c.clone(), scope.clone()).item.clone(), + ); + } + __result + }), + params: item.params.clone(), + inferred: if (item.inferred.clone() != None) { + item.inferred.clone() + } else { + Some(Rc::new(InferredNode::Resolved { node: unit_type() })) + }, + return_cardinality: item.return_cardinality.clone(), + uses: item.uses.clone(), + body: None, + connective: Connective::NoConnective, + transport: typed_transport.clone(), + properties: typed_properties.clone(), + type_annotation: typed_anno.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + diagnostics: v1_rt::concat( + transport_diags.clone(), + props_diags.clone(), + ), + }) + } else { + Rc::new(TypedItemResult { + item: Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new({ + let mut __result = Vec::new(); + for c in item.children.clone().iter().cloned() { + __result.push( + infer_item(c.clone(), scope.clone()).item.clone(), + ); + } + __result + }), + params: item.params.clone(), + inferred: if (item.inferred.clone() != None) { + item.inferred.clone() + } else { + Some(Rc::new(InferredNode::Resolved { node: unit_type() })) + }, + return_cardinality: item.return_cardinality.clone(), + uses: item.uses.clone(), + body: None, + connective: item.connective.clone(), + transport: typed_transport.clone(), + properties: typed_properties.clone(), + type_annotation: typed_anno.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + diagnostics: v1_rt::concat( + transport_diags.clone(), + props_diags.clone(), + ), + }) + } + } + } + } + } + }) +} + +pub fn infer_items( + items: Rc>>, + scope: Rc, +) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for item in items.clone().iter().cloned() { + __result.push(infer_item(item.clone(), scope.clone())); + } + __result + }) +} + +pub fn is_type_variable_name(name: String) -> bool { + (((((name.clone() == "T".to_string()) || (name.clone() == "K".to_string())) + || (name.clone() == "V".to_string())) + || (name.clone() == "MappedElement".to_string())) + || (name.clone() == "FoldAccumulator".to_string())) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ArgGenericFoldState { + pub results: Rc>>, + pub subst: Rc>>, +} + +pub fn type_node_label( + n: Rc, + source_indices: Rc>>, +) -> String { + { + let authored = authored_name_at(source_indices.clone(), n.clone()); + if (authored.clone() != "".to_string()) { + authored.clone() + } else { + match n.inferred.clone().as_deref().cloned() { + Some(InferredNode::TypeVariable { id: tv_id, .. }) => tv_id.clone(), + _ => n.name.clone(), + } + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct SigParamSplit { + pub value_params: Rc>>, + pub generic_names: Rc>, +} + +pub fn body_shadow_aware_func_sig(scope: Rc, func_name: String) -> Rc { + match v1_rt::map_get(&scope.body_locals.clone(), func_name.clone()) { + Some(_) => Rc::new(FuncSigLookup::FuncSigUnresolved), + None => lookup_func_sig( + scope.func_env.clone(), + scope.type_env.clone(), + func_name.clone(), + ), + } +} + +pub fn split_sig_params( + params: Rc>>, + source_indices: Rc>>, +) -> Rc { + Rc::new(SigParamSplit { + value_params: Rc::new({ + let mut __result = Vec::new(); + for p in params.clone().iter().cloned() { + if !param_is_generic_decl(p.clone(), source_indices.clone()) { + __result.push(p); + } + } + __result + }), + generic_names: Rc::new({ + let mut __result = Vec::new(); + for p in Rc::new({ + let mut __result = Vec::new(); + for p in params.clone().iter().cloned() { + if param_is_generic_decl(p.clone(), source_indices.clone()) { + __result.push(p); + } + } + __result + }) + .iter() + .cloned() + { + __result.push(param_node_name_at(p.clone(), source_indices.clone())); + } + __result + }), + }) +} + +pub fn param_is_generic_decl( + p: Rc, + source_indices: Rc>>, +) -> bool { + { + let pt = param_node_type_expr(p.clone()); + let pname = param_node_name_at(p.clone(), source_indices.clone()); + let tname = type_node_label(pt.clone(), source_indices.clone()); + let type_expr_is_var = match pt.inferred.clone() { + Some(inf) => is_type_variable(inf.clone()), + None => false, + }; + (((((pt.children.clone().len() as i64) == 0) + && (pt.connective.clone() == Connective::NoConnective)) + && (pname.clone() != "".to_string())) + && ((pname.clone() == tname.clone()) + || (type_expr_is_var.clone() && (pname.clone() == pt.name.clone())))) + } +} + +pub fn unify_generics( + mut formal: Rc, + mut actual: Rc, + mut generic_names: Rc>, + mut source_indices: Rc>>, + mut acc: Rc>>, +) -> Rc>> { + loop { + let bind_name = type_node_label(formal.clone(), source_indices.clone()); + let f_bare = (((formal.children.clone().len() as i64) == 0) + && (formal.connective.clone() == Connective::NoConnective)); + if ((f_bare.clone() + || match formal.inferred.clone().as_deref().cloned() { + Some(InferredNode::TypeVariable { id: _, .. }) => true, + _ => false, + }) + && { + let mut __found = false; + for g in generic_names.clone().iter().cloned() { + if (g.clone() == bind_name.clone()) { + __found = true; + break; + } + } + __found + }) + { + match v1_rt::map_get(&acc, bind_name.clone()) { + None => { + break v1_rt::rc_map_insert(acc.clone(), bind_name.clone(), actual.clone()); + } + Some(_) => { + break acc.clone(); + } + } + } else { + if (((formal.children.clone().len() as i64) == 1) + && ((actual.children.clone().len() as i64) == 1)) + { + match formal.children.clone().first().cloned() { + Some(fc) => match actual.children.clone().first().cloned() { + Some(ac) => { + let __tco_0 = fc.clone(); + let __tco_1 = ac.clone(); + formal = __tco_0; + actual = __tco_1; + continue; + } + None => { + break acc.clone(); + } + }, + None => { + break acc.clone(); + } + } + } else { + break acc.clone(); + } + } + } +} + +pub fn should_unify_record_lit_generics( + formal: Rc, + arg_expr: Rc, + generic_names: Rc>, + source_indices: Rc>>, +) -> bool { + match record_lit_expr_optional(arg_expr.clone()) { + None => false, + Some(record_expr) => { + if ((generic_names.clone().len() as i64) == 0) { + false + } else { + if ((formal.children.clone().len() as i64) > 0) { + true + } else { + { + let formal_name = type_node_label(formal.clone(), source_indices.clone()); + let record_name = + type_node_label(record_expr.clone(), source_indices.clone()); + (((formal_name.clone() != "".to_string()) + && (record_name.clone() != "".to_string())) + && (formal_name.clone() == record_name.clone())) + } + } + } + } + } +} + +pub fn unify_record_lit_field_walk( + struct_fields: Rc>>, + record: Rc, + generic_names: Rc>, + scope: Rc, + acc: Rc>>, +) -> Rc>> { + struct_fields.clone().iter().cloned().fold( + acc.clone(), + |st: Rc>>, sf: Rc| { + let field_name = + authored_name_at(scope.type_env.clone().source_indices.clone(), sf.clone()); + match Rc::new({ + let mut __result = Vec::new(); + for fi in record.children.clone().iter().cloned() { + if (field_init_node_name_at( + fi.clone(), + scope.type_env.clone().source_indices.clone(), + ) == field_name.clone()) + { + __result.push(fi); + } + } + __result + }) + .first() + .cloned() + { + Some(fi) => { + let actual_value = field_init_node_value(fi.clone()); + let field_formal = match sf.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), + _ => field_node_type_expr(sf.clone()), + }; + match record_lit_expr_optional(actual_value.clone()) { + Some(nested_record) => unify_record_lit_generics( + field_formal.clone(), + nested_record.clone(), + generic_names.clone(), + scope.clone(), + st.clone(), + ), + None => unify_generics( + field_formal.clone(), + resolved_type(actual_value.clone()), + generic_names.clone(), + scope.type_env.clone().source_indices.clone(), + st.clone(), + ), + } + } + None => st.clone(), + } + }, + ) +} + +pub fn unify_record_lit_generics( + formal: Rc, + record: Rc, + generic_names: Rc>, + scope: Rc, + acc: Rc>>, +) -> Rc>> { + if ((formal.children.clone().len() as i64) == 0) { + { + let formal_name = type_node_label( + formal.clone(), + scope.type_env.clone().source_indices.clone(), + ); + let is_generic_slot = { + let mut __found = false; + for g in generic_names.clone().iter().cloned() { + if (g.clone() == formal_name.clone()) { + __found = true; + break; + } + } + __found + }; + if is_generic_slot.clone() { + unify_generics( + formal.clone(), + resolved_type(record.clone()), + generic_names.clone(), + scope.type_env.clone().source_indices.clone(), + acc.clone(), + ) + } else { + match record_lit_expr_optional(record.clone()) { + Some(record_lit) => { + let record_type_name = type_node_label( + record_lit.clone(), + scope.type_env.clone().source_indices.clone(), + ); + if ((record_type_name.clone() != "".to_string()) + && (formal_name.clone() == record_type_name.clone())) + { + unify_record_lit_field_walk( + record_lit_expected_fields( + Some(record_type_name.clone()), + scope.clone(), + ), + record_lit.clone(), + generic_names.clone(), + scope.clone(), + acc.clone(), + ) + } else { + unify_generics( + formal.clone(), + resolved_type(record.clone()), + generic_names.clone(), + scope.type_env.clone().source_indices.clone(), + acc.clone(), + ) + } + } + None => unify_generics( + formal.clone(), + resolved_type(record.clone()), + generic_names.clone(), + scope.type_env.clone().source_indices.clone(), + acc.clone(), + ), + } + } + } + } else { + { + let type_name = type_node_label( + formal.clone(), + scope.type_env.clone().source_indices.clone(), + ); + unify_record_lit_field_walk( + record_lit_expected_fields(Some(type_name.clone()), scope.clone()), + record.clone(), + generic_names.clone(), + scope.clone(), + acc.clone(), + ) + } + } +} + +pub fn substitute_generics( + n: Rc, + subst: Rc>>, + source_indices: Rc>>, +) -> Rc { + if v1_rt::map_is_empty(&subst) { + n + } else { + substitute_generics_apply(n, subst.clone(), source_indices.clone()) + } +} + +pub fn substitute_generics_apply( + n: Rc, + subst: Rc>>, + source_indices: Rc>>, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match n.inferred.clone().as_deref().cloned() { + Some(InferredNode::TypeVariable { id: tv_id, .. }) => { + match v1_rt::map_get(&subst, tv_id.clone()) { + Some(c) => c.clone(), + None => n.clone(), + } + } + _ => { + let nm = type_node_label(n.clone(), source_indices.clone()); + let is_bare = ((((n.children.clone().len() as i64) == 0) + && (n.connective.clone() == Connective::NoConnective)) + && ((n.params.clone().len() as i64) == 0)); + if is_bare.clone() { + match v1_rt::map_get(&subst, nm.clone()) { + Some(c) => c.clone(), + None => n.clone(), + } + } else { + { + let new_children = Rc::new({ + let mut __result = Vec::new(); + for c in n.children.clone().iter().cloned() { + __result.push(substitute_generics_apply( + c.clone(), + subst.clone(), + source_indices.clone(), + )); + } + __result + }); + let new_params = Rc::new({ + let mut __result = Vec::new(); + for p in n.params.clone().iter().cloned() { + __result.push(substitute_generics_apply( + p.clone(), + subst.clone(), + source_indices.clone(), + )); + } + __result + }); + let new_inferred = match n.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + let new_rt = substitute_generics_apply( + rt.clone(), + subst.clone(), + source_indices.clone(), + ); + if v1_rt::rc_ptr_eq(new_rt.clone(), rt.clone()) { + n.inferred.clone() + } else { + Some(Rc::new(InferredNode::Resolved { + node: new_rt.clone(), + })) + } + } + _ => n.inferred.clone(), + }; + if ((v1_rt::rc_vec_ptr_eq(new_children.clone(), n.children.clone()) + && v1_rt::rc_vec_ptr_eq(new_params.clone(), n.params.clone())) + && (new_inferred.clone() == n.inferred.clone())) + { + n.clone() + } else { + Rc::new(Node { + name: n.name.clone(), + span: n.span.clone(), + ident_span: n.ident_span.clone(), + children: new_children.clone(), + connective: n.connective.clone(), + params: new_params.clone(), + inferred: new_inferred.clone(), + return_cardinality: n.return_cardinality.clone(), + uses: n.uses.clone(), + body: n.body.clone(), + transport: n.transport.clone(), + properties: n.properties.clone(), + type_annotation: n.type_annotation.clone(), + is_self_recursive: n.is_self_recursive.clone(), + has_non_tail_self_call: n.has_non_tail_self_call.clone(), + match_pattern: n.match_pattern.clone(), + expr_data: n.expr_data.clone(), + ident: None, + }) + } + } + } + } + } + }) +} + +pub fn kernel_span(name: String) -> Rc { + Rc::new(SourceSpan { + file: v1_rt::concat( + v1_rt::concat("".to_string(), + ), + start: 0, + end: v1_rt::string_length(&name), + }) +} + +pub fn deps_excluding_leaf_self( + b: Rc, + source_indices: Rc>>, +) -> Rc> { + { + let deps0 = node_type_deps(b.resolved.clone(), source_indices.clone()); + let is_bare_self = ((((b.resolved.clone().connective.clone() + == Connective::NoConnective) + && ((b.resolved.clone().children.clone().len() as i64) == 0)) + && ((deps0.clone().len() as i64) == 1)) + && { + let mut __found = false; + for d in deps0.clone().iter().cloned() { + if (d.clone() == b.name.clone()) { + __found = true; + break; + } + } + __found + }); + if is_bare_self.clone() { + Rc::new(vec![]) + } else { + deps0.clone() + } + } +} + +pub fn compiler_recursive_name_set() -> Rc> { + Rc::new(v1_rt::map_keys(&compiler_recursive_types())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert(acc, name.clone(), true) + }, + ) +} + +pub fn type_env_cache_from_bindings( + bindings: Rc>>, + source_indices: Rc>>, + cycle_set_str: Rc>, +) -> Rc { + { + let str_bindings = Rc::new(v1_rt::map_values(&bindings)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, b: Rc| { + v1_rt::rc_map_insert(acc, b.name.clone(), b.clone()) + }, + ); + let deps_map = Rc::new(v1_rt::map_values(&bindings)).iter().cloned().fold( + v1_rt::rc_empty_map::>>(), + |acc: Rc>>>, b: Rc| { + v1_rt::rc_map_insert( + acc, + b.name.clone(), + deps_excluding_leaf_self(b.clone(), source_indices.clone()), + ) + }, + ); + Rc::new(TypeEnvCache { + deps_map: deps_map.clone(), + str_bindings: str_bindings.clone(), + cycle_set_str: cycle_set_str.clone(), + variant_locals: v1_rt::rc_empty_map::>(), + }) + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ParentCacheRow { + pub import_path: String, + pub cache: Rc, +} + +pub fn union_parent_type_env_caches( + resolved_imports: Rc>>, + parent_index: Rc>>, +) -> Rc { + { + let parent_caches = Rc::new({ + let mut __result = Vec::new(); + for imp in resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(parent) => Rc::new(vec![Rc::new(ParentCacheRow { + import_path: imp.module_path.clone(), + cache: parent.interface.clone().cache.clone(), + })]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + match parent_caches.clone().first().cloned() { + None => Rc::new(GuardedTypeEnvCacheMerge { + cache: empty_type_env_cache(), + conflicts: Rc::new(vec![]), + }), + Some(head) => Rc::new( + parent_caches + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + Rc::new(GuardedTypeEnvCacheMerge { + cache: head.cache.clone(), + conflicts: Rc::new(vec![]), + }), + |acc: Rc, row: Rc| { + merge_type_env_cache_guarded( + acc.cache.clone(), + row.cache.clone(), + row.import_path.clone(), + acc.conflicts.clone(), + ) + }, + ), + } + } +} + +pub fn kernel_coproduct_variant_locals(env: Rc) -> Rc>> { + match env.parents.clone().last().cloned() { + Some(kernel) => Rc::new({ + let mut __sorted: Vec<_> = Rc::new(v1_rt::map_values(&kernel.bindings.clone())) + .iter() + .cloned() + .collect(); + __sorted.sort_by(|a: &Rc, b: &Rc| { + let __ka = (|b: Rc| b.name.clone())(a.clone()); + let __kb = (|b: Rc| b.name.clone())(b.clone()); + __ka.partial_cmp(&__kb).unwrap_or(std::cmp::Ordering::Equal) + }); + __sorted + }) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, binding: Rc| { + let is_coproduct = + (binding.resolved.clone().connective.clone() == Connective::Disj); + if is_coproduct.clone() { + binding + .resolved + .clone() + .children + .clone() + .iter() + .cloned() + .fold( + acc.clone(), + |vacc: Rc>>, child: Rc| { + let child_name = + authored_name_at(env.source_indices.clone(), child.clone()); + match v1_rt::map_get(&vacc, child_name.clone()) { + Some(_prev) => vacc.clone(), + None => v1_rt::rc_map_insert( + vacc.clone(), + child_name.clone(), + Rc::new(TypeBinding { + name: child_name.clone(), + resolved: binding.resolved.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ), + } + }, + ) + } else { + acc.clone() + } + }, + ), + None => v1_rt::rc_empty_map::>(), + } +} + +pub fn merge_kernel_variant_locals_low_priority( + env: Rc, + locals: Rc>>, +) -> Rc>> { + { + let kernel_locals = kernel_coproduct_variant_locals(env.clone()); + Rc::new(v1_rt::map_keys(&kernel_locals)) + .iter() + .cloned() + .fold( + locals.clone(), + |acc: Rc>>, variant_name: String| { + match v1_rt::map_get(&acc, variant_name.clone()) { + Some(_) => acc.clone(), + None => match v1_rt::map_get(&kernel_locals, variant_name.clone()) { + Some(binding) => v1_rt::rc_map_insert( + acc.clone(), + variant_name.clone(), + binding.clone(), + ), + None => acc.clone(), + }, + } + }, + ) + } +} + +pub fn type_env_for_import(module_path: String, parent_env: Rc) -> Rc { + if (module_path.clone() == "std.types".to_string()) { + { + let filtered = Rc::new(v1_rt::map_keys(&parent_env.bindings.clone())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, ident: i64| { + let name = intern_str(parent_env.intern_table.clone(), ident.clone()); + if is_type_variable_name(name.clone()) { + acc.clone() + } else { + match v1_rt::map_get(&parent_env.bindings.clone(), ident.clone()) { + Some(binding) => v1_rt::rc_map_insert( + acc.clone(), + ident.clone(), + binding.clone(), + ), + None => acc.clone(), + } + } + }, + ); + let filtered_str = Rc::new(v1_rt::map_keys(&parent_env.str_bindings.clone())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| { + if is_type_variable_name(name.clone()) { + acc.clone() + } else { + match v1_rt::map_get(&parent_env.str_bindings.clone(), name.clone()) { + Some(binding) => { + v1_rt::rc_map_insert(acc.clone(), name.clone(), binding.clone()) + } + None => acc.clone(), + } + } + }, + ); + let filtered_ancestry = + Rc::new(v1_rt::map_keys(&parent_env.ancestry_str_bindings.clone())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| { + if is_type_variable_name(name.clone()) { + acc.clone() + } else { + match v1_rt::map_get( + &parent_env.ancestry_str_bindings.clone(), + name.clone(), + ) { + Some(binding) => v1_rt::rc_map_insert( + acc.clone(), + name.clone(), + binding.clone(), + ), + None => acc.clone(), + } + } + }, + ); + Rc::new(TypeEnv { + module_path: module_path.clone(), + bindings: filtered.clone(), + str_bindings: filtered_str.clone(), + ancestry_str_bindings: filtered_ancestry.clone(), + parents: parent_env.parents.clone(), + recursive_types: parent_env.recursive_types.clone(), + recursive_type_set: parent_env.recursive_type_set.clone(), + inductive_fields: parent_env.inductive_fields.clone(), + source_indices: parent_env.source_indices.clone(), + intern_table: parent_env.intern_table.clone(), + source_visible_names: parent_env.source_visible_names.clone(), + symbol_index: parent_env.symbol_index.clone(), + }) + } + } else { + parent_env.clone() + } +} + +pub fn interface_env_for_import_note() -> String { + thread_local! { + static CACHED: String = { + "Interface-grain scope parent (S2a move 2 increment B, resolver-graph-major-design.md 7): a dependent's typecheck may read exactly its direct import's exported surface - str_bindings, the flattened ancestry maps, the MERGED inductive_fields/recursive sets (each inductively carries the parent's own ancestry, so one level suffices) - and never the parent's parent-chain env OBJECTS. parents: [] cuts the whole-ancestry retention (the measured ~16.3MiB/module residency class) while every chain consumer stays satisfied: phantom-variant and paramless-generic retries read direct parents' str_bindings (carried), inductive_fields_for reads the merged fields (carried), and the kernel stays the dependent's own last scope parent. Discriminating receipt: transitive_interface_binding_test (green arm = a C-declared record projected through B's exported signature still typechecks in A; red control = a bogus field on the same transitive record still errors).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn interface_env_for_import(module_path: String, parent_env: Rc) -> Rc { + { + let filtered = type_env_for_import(module_path.clone(), parent_env.clone()); + Rc::new(TypeEnv { + module_path: module_path.clone(), + bindings: filtered.bindings.clone(), + str_bindings: filtered.str_bindings.clone(), + ancestry_str_bindings: filtered.ancestry_str_bindings.clone(), + parents: Rc::new(vec![]), + recursive_types: filtered.recursive_types.clone(), + recursive_type_set: filtered.recursive_type_set.clone(), + inductive_fields: filtered.inductive_fields.clone(), + source_indices: filtered.source_indices.clone(), + intern_table: filtered.intern_table.clone(), + source_visible_names: filtered.source_visible_names.clone(), + symbol_index: filtered.symbol_index.clone(), + }) + } +} + +pub fn interface_summary_consumer_note() -> String { + thread_local! { + static CACHED: String = { + "S2a move 2 increment B (resolver-graph-major-design.md §7): build_type_env reads a direct import's ModuleInterface (std.interface_summary carrier + interface-grain env/cache realization) — never the parent's full TypeEnv+TypeEnvCache chains. interface.env is the export surface with parents: [] (ancestry-complete via flattened str_bindings/ancestry maps and merged inductive/recursive sets); interface.cache is the flattened import-union grain (variant_locals stripped — interpretation-local). Consumption still runs interface_env_for_import for importer-specific std.types filtering. Discriminating receipt: transitive_interface_binding_test.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn interface_signature_fingerprint_v0_note() -> String { + thread_local! { + static CACHED: String = { + "Interim v0 export signature fingerprint (export_entry_from_item): name-grain, NOT yet structural type shape. Type/data/service exports fingerprint name + authored_name_at(binding.resolved) under tag v1-interface-sig-v0; fn/func exports fingerprint name + param resolved-type names + return-type authored name under tag v1-interface-fn-sig-v0 (the fn arm landed with the typed-module content key, PR-alpha — before it, fn exports produced NO entry, so a fn-only module's interface_hash was the constant empty rollup and the content key's import term was vacuous; the key's import-term RED control is the discriminating receipt). Two exports whose names and resolved authored-name strings all match still collide even if type STRUCTURE differs; increment-B receipt is binding transitivity (transitive_interface_binding_test), not hash-discriminated deep structure. Structural fingerprint authority: std.interface_summary.interface_summary_v0_dissolution_trigger → export_entry_fingerprint when type-structure hashing lands.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn interface_env_surface(env: Rc) -> Rc { + Rc::new(TypeEnv { + module_path: env.module_path.clone(), + bindings: env.bindings.clone(), + str_bindings: env.str_bindings.clone(), + ancestry_str_bindings: env.ancestry_str_bindings.clone(), + parents: Rc::new(vec![]), + recursive_types: env.recursive_types.clone(), + recursive_type_set: env.recursive_type_set.clone(), + inductive_fields: env.inductive_fields.clone(), + source_indices: env.source_indices.clone(), + intern_table: env.intern_table.clone(), + source_visible_names: env.source_visible_names.clone(), + symbol_index: env.symbol_index.clone(), + }) +} + +pub fn interface_cache_from_module(cache: Rc) -> Rc { + Rc::new(TypeEnvCache { + deps_map: cache.deps_map.clone(), + str_bindings: cache.str_bindings.clone(), + cycle_set_str: cache.cycle_set_str.clone(), + variant_locals: v1_rt::rc_empty_map::>(), + }) +} + +pub fn export_kind_of_item_kind(kind: ItemKind) -> Option { + match kind.clone() { + ItemKind::FnItem => Some(ExportKind::ExportFn), + ItemKind::FuncItem => Some(ExportKind::ExportFn), + ItemKind::TypeItem => Some(ExportKind::ExportType), + ItemKind::DataItem => Some(ExportKind::ExportData), + ItemKind::ServiceItem => Some(ExportKind::ExportService), + ItemKind::OtherItem => None, + } +} + +pub fn fn_signature_fingerprint( + item: Rc, + source_indices: Rc>>, +) -> Rc { + { + let params_acc = item.params.clone().iter().cloned().fold( + content_hash_atom("v1-interface-fn-sig-v0".to_string()), + |acc: Rc, p: Rc| { + content_hash_combine_structural( + acc, + content_hash_atom(resolved_type_name(p.clone(), source_indices.clone())), + ) + }, + ); + match item.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => content_hash_combine_structural( + params_acc.clone(), + content_hash_atom(authored_name_at(source_indices.clone(), rt.clone())), + ), + _ => params_acc.clone(), + } + } +} + +pub fn export_entry_from_item( + item: Rc, + env: Rc, + source_indices: Rc>>, +) -> Option> { + { + let name = authored_name_at(source_indices.clone(), item.clone()); + match export_kind_of_item_kind(item_kind(item.clone())) { + None => None, + Some(kind) => match kind.clone() { + ExportKind::ExportFn => Some(Rc::new(ExportEntry { + name: name.clone(), + kind: kind.clone(), + contract: signature_contract(content_hash_tagged_structural( + "v1-interface-fn-sig-v0".to_string(), + content_hash_combine_structural( + content_hash_atom(name.clone()), + fn_signature_fingerprint(item.clone(), source_indices.clone()), + ), + )), + })), + _ => match v1_rt::map_get(&env.str_bindings.clone(), name.clone()) { + Some(binding) => Some(Rc::new(ExportEntry { + name: name.clone(), + kind: kind.clone(), + contract: signature_contract(content_hash_tagged_structural( + "v1-interface-sig-v0".to_string(), + content_hash_combine_structural( + content_hash_atom(binding.name.clone()), + content_hash_atom(authored_name_at( + source_indices.clone(), + binding.resolved.clone(), + )), + ), + )), + })), + None => None, + }, + }, + } + } +} + +pub fn export_entries_from_module( + module: Rc, + env: Rc, + source_indices: Rc>>, +) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for item in module_items(module.clone()).iter().cloned() { + __result.extend( + (*match export_entry_from_item(item.clone(), env.clone(), source_indices.clone()) { + Some(entry) => Rc::new(vec![entry.clone()]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }) +} + +pub fn build_module_interface( + module_path: String, + module: Rc, + env: Rc, + cache: Rc, + source_indices: Rc>>, +) -> Rc { + { + let exports = + export_entries_from_module(module.clone(), env.clone(), source_indices.clone()); + Rc::new(ModuleInterface { + summary: Rc::new(InterfaceSummary { + module_path: module_path.clone(), + exports: exports.clone(), + interface_hash: interface_summary_rollup(exports.clone()), + }), + env: interface_env_surface(env.clone()), + cache: interface_cache_from_module(cache.clone()), + }) + } +} + +pub fn local_binding_for_item( + item: Rc, + source_indices: Rc>>, +) -> Option> { + if is_namespace_alias_item(item.clone(), source_indices.clone()) { + None + } else { + { + let has_structure = (item.connective.clone() != Connective::NoConnective); + if has_structure.clone() { + { + let type_node = Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: item.children.clone(), + connective: item.connective.clone(), + params: item.params.clone(), + inferred: None, + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: item.properties.clone(), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + Some(Rc::new(TypeBinding { + name: authored_name_at(source_indices.clone(), item.clone()), + resolved: type_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + })) + } + } else { + if ((item.body.clone() != None) && (item.transport.clone() == None)) { + { + let fn_node = Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: item.params.clone(), + inferred: item.inferred.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: item.properties.clone(), + type_annotation: item.type_annotation.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + Some(Rc::new(TypeBinding { + name: authored_name_at(source_indices.clone(), item.clone()), + resolved: fn_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + })) + } + } else { + if (((item.inferred.clone() != None) + && ((item.params.clone().len() as i64) == 0)) + && (item.body.clone() == None)) + { + { + let alias_node = Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: item.inferred.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + Some(Rc::new(TypeBinding { + name: authored_name_at(source_indices.clone(), item.clone()), + resolved: alias_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + })) + } + } else { + if ((item.transport.clone() == None) + && ((item.children.clone().len() as i64) > 0)) + { + { + let ref_node = nominal_ref_node( + authored_name_at(source_indices.clone(), item.clone()), + item.span.clone(), + item.ident_span.clone(), + ); + Some(Rc::new(TypeBinding { + name: authored_name_at(source_indices.clone(), item.clone()), + resolved: ref_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + })) + } + } else { + if (((((item.params.clone().len() as i64) > 0) + && (item.connective.clone() == Connective::NoConnective)) + && (item.body.clone() == None)) + && (item.transport.clone() == None)) + { + { + let bare_node = Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: item.params.clone(), + inferred: item.inferred.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + Some(Rc::new(TypeBinding { + name: authored_name_at( + source_indices.clone(), + item.clone(), + ), + resolved: bare_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + })) + } + } else { + if ((((((item.properties.clone().len() as i64) > 0) + && (item.connective.clone() == Connective::NoConnective)) + && (item.transport.clone() == None)) + && (item.inferred.clone() == None)) + && ((item.params.clone().len() as i64) == 0)) + { + Some(nominal_type_binding(authored_name_at( + source_indices.clone(), + item.clone(), + ))) + } else { + None + } + } + } + } + } + } + } + } +} + +pub fn symbol_index_insert_item( + index: Rc, + module_path: String, + item: Rc, + source_indices: Rc>>, +) -> Rc { + { + let with_decl = if is_namespace_alias_item(item.clone(), source_indices.clone()) { + match namespace_alias_target_path(item.clone(), source_indices.clone()) { + None => index.clone(), + Some(target_path) => { + match symbol_index_lookup(index.clone(), target_path.clone()) { + None => index.clone(), + Some(target_node) => symbol_index_insert_decl( + index.clone(), + module_path.clone(), + namespace_alias_binding_for_target( + item.clone(), + target_node.clone(), + source_indices.clone(), + ), + ), + } + } + } + } else { + match local_binding_for_item(item.clone(), source_indices.clone()) { + None => index.clone(), + Some(binding) => { + symbol_index_insert_decl(index.clone(), module_path.clone(), binding.clone()) + } + } + }; + if ((item.transport.clone() != None) && ((item.children.clone().len() as i64) > 0)) { + symbol_index_insert_service( + with_decl.clone(), + authored_name_at(source_indices.clone(), item.clone()), + module_path.clone(), + item.clone(), + ) + } else { + with_decl.clone() + } + } +} + +pub fn disj_variant_name_count_inc( + counts: Rc>, + name: String, +) -> Rc> { + match v1_rt::map_get(&counts, name.clone()) { + Some(n) => v1_rt::rc_map_insert(counts.clone(), name.clone(), (n.clone() + 1)), + None => v1_rt::rc_map_insert(counts.clone(), name.clone(), 1), + } +} + +pub fn disj_variant_name_counts( + items: Rc>>, + source_indices: Rc>>, +) -> Rc> { + items.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |counts: Rc>, item: Rc| match item.connective.clone() { + Connective::Disj => item.children.clone().iter().cloned().fold( + counts.clone(), + |c: Rc>, child: Rc| { + disj_variant_name_count_inc( + c, + authored_name_at(source_indices.clone(), child.clone()), + ) + }, + ), + _ => counts.clone(), + }, + ) +} + +pub fn census_node_base_note() -> String { + thread_local! { + static CACHED: String = { + "The census reads only the module NODE, so the node list is its true input: one census over two front ends (resolved closures and parse-grade pool fills). ResolvedModule entry points delegate through census_module_nodes.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn census_module_nodes(modules: Rc>>) -> Rc>> { + Rc::new({ + let mut __result = Vec::new(); + for rm in modules.clone().iter().cloned() { + __result.push(rm.module.clone()); + } + __result + }) +} + +pub fn corpus_disj_variant_name_counts_nodes( + module_nodes: Rc>>, + source_indices: Rc>>, +) -> Rc> { + module_nodes.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |counts: Rc>, module_node: Rc| { + module_items(module_node.clone()).iter().cloned().fold( + counts, + |c: Rc>, item: Rc| match item.connective.clone() { + Connective::Disj => item.children.clone().iter().cloned().fold( + c.clone(), + |c2: Rc>, child: Rc| { + disj_variant_name_count_inc( + c2, + authored_name_at(source_indices.clone(), child.clone()), + ) + }, + ), + _ => c.clone(), + }, + ) + }, + ) +} + +pub fn corpus_disj_variant_name_counts( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc> { + corpus_disj_variant_name_counts_nodes( + census_module_nodes(modules.clone()), + source_indices.clone(), + ) +} + +pub fn corpus_item_name_counts_nodes( + module_nodes: Rc>>, + source_indices: Rc>>, +) -> Rc> { + module_nodes.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |counts: Rc>, module_node: Rc| { + module_items(module_node.clone()).iter().cloned().fold( + counts, + |c: Rc>, item: Rc| { + disj_variant_name_count_inc( + c, + authored_name_at(source_indices.clone(), item.clone()), + ) + }, + ) + }, + ) +} + +pub fn corpus_item_name_counts( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc> { + corpus_item_name_counts_nodes(census_module_nodes(modules.clone()), source_indices.clone()) +} + +pub fn symbol_index_insert_unique_disj_variant_aliases( + index: Rc, + module_path: String, + items: Rc>>, + source_indices: Rc>>, + corpus_variant_counts: Rc>, + corpus_item_counts: Rc>, +) -> Rc { + { + let counts = disj_variant_name_counts(items.clone(), source_indices.clone()); + items + .clone() + .iter() + .cloned() + .fold( + index.clone(), + |acc: Rc, item: Rc| match item.connective.clone() { + Connective::Disj => { + let tname = authored_name_at(source_indices.clone(), item.clone()); + item.children.clone().iter().cloned().fold( + acc.clone(), + |a2: Rc, child: Rc| { + let vname = authored_name_at(source_indices.clone(), child.clone()); + let a2_qualified = symbol_index_insert( + a2, + v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat(module_path.clone(), ".".to_string()), + tname.clone(), + ), + ".".to_string(), + ), + vname.clone(), + ), + item.clone(), + ); + match v1_rt::map_get(&counts, vname.clone()) { + Some(1) => { + match v1_rt::map_get(&corpus_variant_counts, vname.clone()) + { + Some(1) => { + if ((v1_rt::map_get( + &corpus_item_counts, + vname.clone(), + ) != None) + || overlay_skips_kernel_name(vname.clone())) + { + symbol_index_insert( + a2_qualified.clone(), + v1_rt::concat( + v1_rt::concat( + module_path.clone(), + ".".to_string(), + ), + vname.clone(), + ), + item.clone(), + ) + } else { + symbol_index_insert_decl( + a2_qualified.clone(), + module_path.clone(), + Rc::new(TypeBinding { + name: vname.clone(), + resolved: item.clone(), + provenance: Rc::new( + SubValueRelation::SubValueUnknown, + ), + }), + ) + } + } + _ => symbol_index_insert( + a2_qualified.clone(), + v1_rt::concat( + v1_rt::concat( + module_path.clone(), + ".".to_string(), + ), + vname.clone(), + ), + item.clone(), + ), + } + } + _ => a2_qualified.clone(), + } + }, + ) + } + _ => acc.clone(), + }, + ) + } +} + +pub fn build_symbol_index_census_raw_nodes( + module_nodes: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let corpus_variant_counts = + corpus_disj_variant_name_counts_nodes(module_nodes.clone(), source_indices.clone()); + let corpus_item_counts = + corpus_item_name_counts_nodes(module_nodes.clone(), source_indices.clone()); + module_nodes.clone().iter().cloned().fold( + empty_symbol_index(), + |index: Rc, module_node: Rc| { + let module_path = authored_name_at(source_indices.clone(), module_node.clone()); + let items = module_items(module_node.clone()); + let with_items = items.clone().iter().cloned().fold( + index, + |acc: Rc, item: Rc| { + symbol_index_insert_item( + acc, + module_path.clone(), + item.clone(), + source_indices.clone(), + ) + }, + ); + symbol_index_insert_unique_disj_variant_aliases( + with_items.clone(), + module_path.clone(), + items.clone(), + source_indices.clone(), + corpus_variant_counts.clone(), + corpus_item_counts.clone(), + ) + }, + ) + } +} + +pub fn build_symbol_index_census_raw( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc { + build_symbol_index_census_raw_nodes( + census_module_nodes(modules.clone()), + source_indices.clone(), + ) +} + +pub fn census_borrowed_sig_resolution_note() -> String { + thread_local! { + static CACHED: String = { + "Borrowed-sig hoist (namespace lane): the census stores raw pre-typecheck fn nodes, so a borrowed generic fn's return leaked bare type-param leaves (T/V/E) and owner-local names into consumers — the local/borrowed asymmetry (locals resolve once per module in resolve_item_types with type params bound as TypeVariables; borrows got the raw node per lookup). Pass 2 resolves each borrowable GENERIC fn signature's return ONCE at census build, in a synthetic env at the OWNER's containment position (module_path = the candidate's declaring module; symbol_index = the completed pass-1 census; type params bound via env_with_type_variable_bindings) — order-independent (resolution reads only the completed raw census, never a partial one), once per decl (never per lookup — the per-lookup variant re-resolved recursive carriers to the depth bound on every call), and staged fail-closed: ANY resolution diagnostic keeps the raw binding, so the consumer-side refusal surface is unchanged (upgraded | raw is a typed frontier, not a widen). Scope: fn sigs with value params (params non-empty; type params may be zero — a NON-generic fn's return can still USE a generic type, e.g. Outcome>, and needs the same owner-position expansion for variant-payload substitution); 0-arg fns and aliases share a census shape (body stripped) and stay raw pending a discriminator.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn census_fn_sig_env( + census: Rc, + module_path: String, + tp_names: Rc>, + source_indices: Rc>>, +) -> Rc { + { + let base = Rc::new(TypeEnv { + module_path: module_path.clone(), + bindings: v1_rt::rc_empty_map::>(), + str_bindings: v1_rt::rc_empty_map::>(), + ancestry_str_bindings: v1_rt::rc_empty_map::>(), + parents: Rc::new(vec![]), + recursive_types: Rc::new(vec![]), + recursive_type_set: v1_rt::rc_empty_map::(), + inductive_fields: v1_rt::rc_empty_map::>>>(), + source_indices: source_indices.clone(), + intern_table: empty_intern_table(), + source_visible_names: v1_rt::rc_empty_map::(), + symbol_index: census.clone(), + }); + env_with_type_variable_bindings(base.clone(), tp_names.clone()) + } +} + +pub fn census_binding_is_borrowable_fn_sig( + binding: Rc, + source_indices: Rc>>, +) -> bool { + { + let node = binding.resolved.clone(); + ((((((node.connective.clone() == Connective::NoConnective) + && ((node.children.clone().len() as i64) == 0)) + && (node.body.clone() == None)) + && (node.transport.clone() == None)) + && (node.inferred.clone() != None)) + && ((node.params.clone().len() as i64) > 0)) + } +} + +pub fn census_qualify_sig_return_binding( + binding: Rc, + module_path: String, + census: Rc, + source_indices: Rc>>, +) -> Rc { + { + let node = binding.resolved.clone(); + let env = census_fn_sig_env( + census.clone(), + module_path.clone(), + Rc::new(vec![]), + source_indices.clone(), + ); + Rc::new(TypeBinding { + name: binding.name.clone(), + resolved: node_with_inferred( + node.clone(), + qualify_borrowed_inferred( + node.inferred.clone(), + module_path.clone(), + env.clone(), + v1_rt::rc_empty_map::(), + ), + ), + provenance: binding.provenance.clone(), + }) + } +} + +pub fn census_upgrade_sig_binding( + binding: Rc, + module_path: String, + census: Rc, + source_indices: Rc>>, + tp_names: Rc>, +) -> Rc { + if ((tp_names.clone().len() as i64) > 0) { + { + let node = binding.resolved.clone(); + match node.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: raw_ret, .. }) => { + let env = census_fn_sig_env( + census.clone(), + module_path.clone(), + tp_names.clone(), + source_indices.clone(), + ); + let ret_result = + resolve_node(raw_ret.clone(), env.clone(), module_path.clone()); + if ((ret_result.diagnostics.clone().len() as i64) == 0) { + { + let preserved = preserve_nominal_brand_on_resolve( + raw_ret.clone(), + ret_result.resolved.clone(), + authored_name_at(source_indices.clone(), raw_ret.clone()), + source_indices.clone(), + ); + Rc::new(TypeBinding { + name: binding.name.clone(), + resolved: node_with_inferred( + node.clone(), + Some(Rc::new(InferredNode::Resolved { + node: preserved.clone(), + })), + ), + provenance: binding.provenance.clone(), + }) + } + } else { + binding.clone() + } + } + _ => binding.clone(), + } + } + } else { + binding.clone() + } +} + +pub fn stamp_field_type_from_decl_params( + field_type: Rc, + serving_decl: Rc, + source_indices: Rc>>, +) -> Rc { + if (((serving_decl.params.clone().len() as i64) == 0) || (field_type.inferred.clone() != None)) + { + field_type.clone() + } else { + { + let is_bare = ((((field_type.children.clone().len() as i64) == 0) + && (field_type.connective.clone() == Connective::NoConnective)) + && ((field_type.params.clone().len() as i64) == 0)); + if is_bare.clone() { + { + let nm = type_node_label(field_type.clone(), source_indices.clone()); + let is_param = Rc::new({ + let mut __result = Vec::new(); + for p in serving_decl.params.clone().iter().cloned() { + __result.push(generic_param_name_at(p.clone(), source_indices.clone())); + } + __result + }) + .iter() + .cloned() + .fold(false, |acc: bool, pn: String| { + (acc || (pn.clone() == nm.clone())) + }); + if is_param.clone() { + node_with_inferred( + field_type.clone(), + Some(Rc::new(InferredNode::TypeVariable { id: nm.clone() })), + ) + } else { + field_type.clone() + } + } + } else { + field_type.clone() + } + } + } +} + +pub fn stamp_type_param_occurrences( + n: Rc, + param_names: Rc>, + source_indices: Rc>>, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + let is_bare = ((((n.children.clone().len() as i64) == 0) + && (n.connective.clone() == Connective::NoConnective)) + && ((n.params.clone().len() as i64) == 0)); + if is_bare.clone() { + if (n.inferred.clone() == None) { + { + let nm = type_node_label(n.clone(), source_indices.clone()); + match v1_rt::map_get(¶m_names, nm.clone()) { + Some(_) => node_with_inferred( + n.clone(), + Some(Rc::new(InferredNode::TypeVariable { id: nm.clone() })), + ), + _ => n.clone(), + } + } + } else { + n.clone() + } + } else { + node_with_children( + n.clone(), + Rc::new({ + let mut __result = Vec::new(); + for c in n.children.clone().iter().cloned() { + __result.push(stamp_type_param_occurrences( + c.clone(), + param_names.clone(), + source_indices.clone(), + )); + } + __result + }), + ) + } + }) +} + +pub fn census_upgrade_type_decl_binding( + binding: Rc, + module_path: String, + census: Rc, + source_indices: Rc>>, +) -> Rc { + { + let node = binding.resolved.clone(); + let param_names = Rc::new({ + let mut __result = Vec::new(); + for p in node.params.clone().iter().cloned() { + __result.push(generic_param_name_at(p.clone(), source_indices.clone())); + } + __result + }); + let excluded = param_names.clone().iter().cloned().fold( + v1_rt::rc_map_insert( + v1_rt::rc_empty_map::(), + binding.name.clone(), + true, + ), + |acc: Rc>, nm: String| { + v1_rt::rc_map_insert(acc, nm.clone(), true) + }, + ); + let env = census_fn_sig_env( + census.clone(), + module_path.clone(), + param_names.clone(), + source_indices.clone(), + ); + Rc::new(TypeBinding { + name: binding.name.clone(), + resolved: qualify_decl_reference_positions( + node.clone(), + module_path.clone(), + env.clone(), + excluded.clone(), + ), + provenance: binding.provenance.clone(), + }) + } +} + +pub fn census_qualify_leaf_binding( + binding: Rc, + module_path: String, + census: Rc, + source_indices: Rc>>, +) -> Rc { + { + let node = binding.resolved.clone(); + let excluded = Rc::new({ + let mut __result = Vec::new(); + for p in node.params.clone().iter().cloned() { + __result.push(generic_param_name_at(p.clone(), source_indices.clone())); + } + __result + }) + .iter() + .cloned() + .fold( + v1_rt::rc_map_insert( + v1_rt::rc_empty_map::(), + binding.name.clone(), + true, + ), + |acc: Rc>, nm: String| { + v1_rt::rc_map_insert(acc, nm.clone(), true) + }, + ); + let env = census_fn_sig_env( + census.clone(), + module_path.clone(), + Rc::new(vec![]), + source_indices.clone(), + ); + Rc::new(TypeBinding { + name: binding.name.clone(), + resolved: node_with_inferred( + node.clone(), + qualify_borrowed_inferred( + node.inferred.clone(), + module_path.clone(), + env.clone(), + excluded.clone(), + ), + ), + provenance: binding.provenance.clone(), + }) + } +} + +pub fn census_upgrade_binding( + binding: Rc, + module_path: String, + census: Rc, + source_indices: Rc>>, +) -> Rc { + if census_binding_is_borrowable_fn_sig(binding.clone(), source_indices.clone()) { + { + let tp_names = fn_type_param_names(binding.resolved.clone(), source_indices.clone()); + if ((tp_names.clone().len() as i64) > 0) { + census_upgrade_sig_binding( + binding.clone(), + module_path.clone(), + census.clone(), + source_indices.clone(), + tp_names.clone(), + ) + } else { + census_qualify_sig_return_binding( + binding.clone(), + module_path.clone(), + census.clone(), + source_indices.clone(), + ) + } + } + } else { + if (binding.resolved.clone().connective.clone() != Connective::NoConnective) { + census_upgrade_type_decl_binding( + binding.clone(), + module_path.clone(), + census.clone(), + source_indices.clone(), + ) + } else { + if (binding.resolved.clone().inferred.clone() != None) { + census_qualify_leaf_binding( + binding.clone(), + module_path.clone(), + census.clone(), + source_indices.clone(), + ) + } else { + binding.clone() + } + } + } +} + +pub fn census_upgrade_type_expr( + raw: Rc, + env: Rc, + module_path: String, + source_indices: Rc>>, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + if ((raw.connective.clone() != Connective::NoConnective) + && ((raw.children.clone().len() as i64) > 0)) + { + { + let fields2 = Rc::new({ + let mut __result = Vec::new(); + for f in raw.children.clone().iter().cloned() { + __result.push(match f.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: ft, .. }) => node_with_inferred( + f.clone(), + Some(Rc::new(InferredNode::Resolved { + node: census_upgrade_type_expr( + ft.clone(), + env.clone(), + module_path.clone(), + source_indices.clone(), + ), + })), + ), + _ => f.clone(), + }); + } + __result + }); + node_with_children(raw.clone(), fields2.clone()) + } + } else { + { + let r = resolve_node(raw.clone(), env.clone(), module_path.clone()); + if ((r.diagnostics.clone().len() as i64) == 0) { + preserve_nominal_brand_on_resolve( + raw.clone(), + r.resolved.clone(), + authored_name_at(source_indices.clone(), raw.clone()), + source_indices.clone(), + ) + } else { + raw.clone() + } + } + } + }) +} + +pub fn census_upgrade_service_item( + item: Rc, + module_path: String, + census: Rc, + source_indices: Rc>>, +) -> Rc { + { + let env = census_fn_sig_env( + census.clone(), + module_path.clone(), + Rc::new(vec![]), + source_indices.clone(), + ); + let ops2 = Rc::new({ + let mut __result = Vec::new(); + for c in item.children.clone().iter().cloned() { + __result.push(match c.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: raw_out, .. }) => node_with_inferred( + c.clone(), + Some(Rc::new(InferredNode::Resolved { + node: census_upgrade_type_expr( + raw_out.clone(), + env.clone(), + module_path.clone(), + source_indices.clone(), + ), + })), + ), + _ => c.clone(), + }); + } + __result + }); + node_with_children(item.clone(), ops2.clone()) + } +} + +pub fn census_with_resolved_fn_sigs( + index: Rc, + source_indices: Rc>>, +) -> Rc { + { + let entry_keys = Rc::new(v1_rt::sorted_map_keys(&index.entries.clone())); + let entries2 = entry_keys.clone().iter().cloned().fold( + index.entries.clone(), + |acc: Rc>>, k: String| match v1_rt::map_get( + &index.entries.clone(), + k.clone(), + ) { + Some(node) => { + let upgraded = census_upgrade_binding( + Rc::new(TypeBinding { + name: qualified_last_segment(k.clone()), + resolved: node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + qualified_all_but_last(k.clone()), + index.clone(), + source_indices.clone(), + ); + if (upgraded.resolved.clone() == node.clone()) { + acc.clone() + } else { + v1_rt::rc_map_insert(acc.clone(), k.clone(), upgraded.resolved.clone()) + } + } + None => acc.clone(), + }, + ); + let bare_keys = Rc::new(v1_rt::sorted_map_keys(&index.global_bare.clone())); + let global2 = bare_keys.clone().iter().cloned().fold( + index.global_bare.clone(), + |acc: Rc>>, k: String| match v1_rt::map_get( + &index.global_bare.clone(), + k.clone(), + ) + .as_deref() + .cloned() + { + Some(GlobalBareLookupState::GlobalBareUniqueBinding { + module_path: mp, + binding: b, + .. + }) => { + let b2 = census_upgrade_binding( + b.clone(), + mp.clone(), + index.clone(), + source_indices.clone(), + ); + if (b2.resolved.clone() == b.resolved.clone()) { + acc.clone() + } else { + v1_rt::rc_map_insert( + acc.clone(), + k.clone(), + Rc::new(GlobalBareLookupState::GlobalBareUniqueBinding { + module_path: mp.clone(), + binding: b2.clone(), + }), + ) + } + } + Some(GlobalBareLookupState::GlobalBareAmbiguousBinding { + candidates: cands, + .. + }) => { + let cands2 = Rc::new({ + let mut __result = Vec::new(); + for c in cands.clone().iter().cloned() { + __result.push(Rc::new(GlobalBareCandidate { + module_path: c.module_path.clone(), + binding: census_upgrade_binding( + c.binding.clone(), + c.module_path.clone(), + index.clone(), + source_indices.clone(), + ), + })); + } + __result + }); + v1_rt::rc_map_insert( + acc.clone(), + k.clone(), + Rc::new(GlobalBareLookupState::GlobalBareAmbiguousBinding { + candidates: cands2.clone(), + }), + ) + } + None => acc.clone(), + }, + ); + let service_keys = Rc::new(v1_rt::sorted_map_keys(&index.services.clone())); + let services2 = service_keys.clone().iter().cloned().fold( + index.services.clone(), + |acc: Rc>>, k: String| match v1_rt::map_get( + &index.services.clone(), + k.clone(), + ) { + Some(sentry) => { + let upgraded = census_upgrade_service_item( + sentry.item.clone(), + sentry.module_path.clone(), + index.clone(), + source_indices.clone(), + ); + if (upgraded.clone() == sentry.item.clone()) { + acc.clone() + } else { + v1_rt::rc_map_insert( + acc.clone(), + k.clone(), + Rc::new(ServiceCensusEntry { + module_path: sentry.module_path.clone(), + item: upgraded.clone(), + }), + ) + } + } + None => acc.clone(), + }, + ); + Rc::new(SymbolIndex { + entries: entries2.clone(), + global_bare: global2.clone(), + services: services2.clone(), + }) + } +} + +pub fn build_symbol_index_census( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let raw = build_symbol_index_census_raw(modules.clone(), source_indices.clone()); + census_with_resolved_fn_sigs(raw.clone(), source_indices.clone()) + } +} + +pub fn census_layering_note() -> String { + thread_local! { + static CACHED: String = { + "Layered census (namespace-resolution-design.md 7.5: fill = whole tree; policy gates lookup, never fill). The closure census is byte-identical to the no-fill build — bare visibility, variant-alias corpus gating, and services stay closure-scoped, so a pool homonym cannot shift what a compiled module's bare names mean (measured on the whole-tree gate: a single whole-pool census vanished bare GET/Persistent/JsonValue across 28 witness rows via the corpus-count gate and unique-to-ambiguous flips). Census-only fill modules are PARSE-GRADE (tokenize + parse, never resolve: fill imports point into the compile closure or another tree view, and resolving fill against a fill-only pool fabricated 797 unresolved-import diagnostics about the view, not the modules) and enter a QUALIFIED-ONLY entries underlay — no bare reach INTO fill is needed because cross-tree references are qualified, the migration direction. The cli_run reconcile additionally underlays each typechecked module's OWN tree-closure bare census (root modules plus import-reached pool modules — gate parity by construction: e.g. dag witnesses' bare LiveTreeDisposition is declared only in v2.std.live_tree but import-reached from the dag tree).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn build_symbol_index_census_nodes( + module_nodes: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let raw = build_symbol_index_census_raw_nodes(module_nodes.clone(), source_indices.clone()); + census_with_resolved_fn_sigs(raw.clone(), source_indices.clone()) + } +} + +pub fn underlay_fill_direction_note() -> String { + thread_local! { + static CACHED: String = { + "Fill composition overlays the CLOSURE onto the shared underlay, never the reverse. Both directions denote the same map (union of key sets, closure wins the intersection); only the cost grain differs — the underlay is a per-index memo, so walking its keys charges every entry O(|whole pool|) for an index that differs by its own closure. Receipt: docs/plans/fill-composition-overlay-direction-receipt.md. Witness: symbol_index_fill_overlay_direction_test.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn symbol_index_with_bare_fill( + closure: Rc, + tree: Rc, +) -> Rc { + { + let global2 = v1_rt::rc_map_merge(tree.global_bare.clone(), closure.global_bare.clone()); + let services2 = v1_rt::rc_map_merge(tree.services.clone(), closure.services.clone()); + Rc::new(SymbolIndex { + entries: closure.entries.clone(), + global_bare: global2.clone(), + services: services2.clone(), + }) + } +} + +pub fn build_symbol_index_qualified_fill( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let raw = modules.clone().iter().cloned().fold( + empty_symbol_index(), + |index: Rc, module_node: Rc| { + let module_path = authored_name_at(source_indices.clone(), module_node.clone()); + let items = module_items(module_node.clone()); + let with_items = items.clone().iter().cloned().fold( + index, + |acc: Rc, item: Rc| match local_binding_for_item( + item.clone(), + source_indices.clone(), + ) { + None => acc.clone(), + Some(binding) => symbol_index_insert( + acc.clone(), + v1_rt::concat( + v1_rt::concat(module_path.clone(), ".".to_string()), + binding.name.clone(), + ), + binding.resolved.clone(), + ), + }, + ); + let counts = disj_variant_name_counts(items.clone(), source_indices.clone()); + items.clone().iter().cloned().fold( + with_items.clone(), + |acc: Rc, item: Rc| match item.connective.clone() { + Connective::Disj => item.children.clone().iter().cloned().fold( + acc.clone(), + |a2: Rc, child: Rc| { + let vname = authored_name_at(source_indices.clone(), child.clone()); + match v1_rt::map_get(&counts, vname.clone()) { + Some(1) => symbol_index_insert( + a2.clone(), + v1_rt::concat( + v1_rt::concat(module_path.clone(), ".".to_string()), + vname.clone(), + ), + item.clone(), + ), + _ => a2.clone(), + } + }, + ), + _ => acc.clone(), + }, + ) + }, + ); + census_with_resolved_fn_sigs(raw.clone(), source_indices.clone()) + } +} + +pub fn symbol_index_with_qualified_fill( + closure: Rc, + fill: Rc, +) -> Rc { + { + let entries2 = v1_rt::rc_map_merge(fill.entries.clone(), closure.entries.clone()); + Rc::new(SymbolIndex { + entries: entries2.clone(), + global_bare: closure.global_bare.clone(), + services: closure.services.clone(), + }) + } +} + +pub fn direct_import_export_precedence_note() -> String { + thread_local! { + static CACHED: String = { + "Direct-selected exports beat transitive leaks (2026-07-16, the #6663 x #6686 main-red). The ancestry union folds each direct import's WHOLE flattened cache (its own exports AND everything it inherited), so a later import's transitively-leaked homonym could overlay an earlier import's OWN export that this module's import statement explicitly selects - import v2.std.algebra { Monoid } lost 'Monoid' to dag-root std.algebra riding v2.std.node's ancestry via std.types, and #6663's field-presence wall read the wrong shape at 28 sites. This overlay re-applies, in import order, each direct import's OWN export surface (interface.env.str_bindings - locals only, never its ancestry) restricted to the names the import statement makes visible (specific_names; is_all = the parent's whole local surface, type-variable names filtered per the std.types precedent). Winner semantics: direct-selected vs transitive leak = direct wins (lexical nearest-wins, the containment ruling one hop out - the sanctioned 1c universe is own declarations UNION direct import lists); direct vs direct = unchanged import-order overlay-wins (the ledgered peer-fork ruling, 2026-07-11: later import wins, conflict stays LEDGERED on binding_forks); leak vs leak = unchanged union winner; KERNEL names are never overridden (overlay_skips_kernel_name: kernel_type_set, the container_type_arity names List/Set/Map/Witness, plus Unit/Optional/Present/Absent) - the kernel scope layer stays positionally above imports per the same ruling, because builtin typing (first, skip, string ops) grounds on kernel identities and the v2 substrate models of those concepts (v2.std.collection List=FreeMonoid, Optional; v2.std.text String) are the known dual-representation debt, resolved corpus-wide by kernel-wins today. Full precedence, nearest first: locals > kernel > direct-selected > transitive union. The fork LEDGER is untouched - rows still record every union conflict; this layer only corrects which binding serves lookups. DISSOLVES WHEN namespace Rule-1 lands (containment tree is the naming authority; imports become parse errors) - the union leak itself disappears and this overlay with it. Receipt: direct_import_precedence_over_transitive_leak_test (green arm = selected name resolves the selected module's shape regardless of import order; red control = the field wall still refuses the true shape's missing fields, with that arm's modules placed so the homonym is census-UNAMBIGUOUS by containment (realleaf under the consumer's own parent, leakleaf under a sibling parent) - a census-ambiguous name stands the wall down BY DESIGN (presence_check_census_gate_note), so without that placement the control asserts a diagnostic the gate exists to suppress and silently measures the gate instead of the overlay; ledger arm = the fork row is still recorded).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn overlay_skips_kernel_name(name: String) -> bool { + (((((is_kernel_type(name.clone()) || is_container_type(name.clone())) + || (name.clone() == "Unit".to_string())) + || (name.clone() == "Optional".to_string())) + || (name.clone() == "Present".to_string())) + || (name.clone() == "Absent".to_string())) +} + +pub fn overlay_direct_import_exports( + ancestry_str_bindings: Rc>>, + resolved_imports: Rc>>, + parent_index: Rc>>, +) -> Rc>> { + resolved_imports.clone().iter().cloned().fold( + ancestry_str_bindings.clone(), + |acc: Rc>>, imp: Rc| match v1_rt::map_get( + &parent_index, + imp.module_path.clone(), + ) { + Some(typed_parent) => { + let export_surface = interface_env_for_import( + imp.module_path.clone(), + typed_parent.interface.clone().env.clone(), + ); + let selected = if imp.is_all.clone() { + Rc::new({ + let mut __result = Vec::new(); + for name in Rc::new(v1_rt::map_keys(&export_surface.str_bindings.clone())) + .iter() + .cloned() + { + if (is_type_variable_name(name.clone()) == false) { + __result.push(name); + } + } + __result + }) + } else { + imp.specific_names.clone() + }; + selected.clone().iter().cloned().fold( + acc.clone(), + |bacc: Rc>>, name: String| { + if overlay_skips_kernel_name(name.clone()) { + bacc.clone() + } else { + match v1_rt::map_get(&export_surface.str_bindings.clone(), name.clone()) + { + Some(binding) => v1_rt::rc_map_insert( + bacc.clone(), + name.clone(), + binding.clone(), + ), + None => bacc.clone(), + } + } + }, + ) + } + None => acc.clone(), + }, + ) +} + +pub fn build_type_env( + module: Rc, + parent_index: Rc>>, + source_indices: Rc>>, + intern_table: Rc, + symbol_index: Rc, +) -> Rc { + { + let source_indices = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold( + source_indices.clone(), + |acc: Rc>>, name: String| { + v1_rt::rc_map_insert( + acc, + v1_rt::concat( + v1_rt::concat("".to_string(), + ), + build_newline_index( + v1_rt::concat( + v1_rt::concat("".to_string(), + ), + name.clone(), + ), + ) + }, + ); + let source_indices = Rc::new(vec![ + "Optional".to_string(), + "Present".to_string(), + "Absent".to_string(), + "value".to_string(), + "none".to_string(), + ]) + .iter() + .cloned() + .fold( + source_indices.clone(), + |acc: Rc>>, name: String| { + v1_rt::rc_map_insert( + acc, + v1_rt::concat( + v1_rt::concat("".to_string(), + ), + build_newline_index( + v1_rt::concat( + v1_rt::concat("".to_string(), + ), + name.clone(), + ), + ) + }, + ); + let intern_table = seed_kernel_intern_table(intern_table.clone()); + let kernel_bindings_base = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + Rc::new(TypeBinding { + name: name.clone(), + resolved: Rc::new(Node { + name: name.clone(), + span: kernel_span(name.clone()), + ident_span: Some(kernel_span(name.clone())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + }, + ); + let unit_span = kernel_span("Unit".to_string()); + let kernel_bindings = v1_rt::rc_map_insert( + kernel_bindings_base.clone(), + intern(intern_table.clone(), "Unit".to_string()).id.clone(), + Rc::new(TypeBinding { + name: "Unit".to_string(), + resolved: Rc::new(Node { + name: "Unit".to_string(), + span: unit_span.clone(), + ident_span: Some(unit_span.clone()), + children: Rc::new(vec![]), + connective: Connective::Conj, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ); + let present_value_field = Rc::new(Node { + name: "value".to_string(), + span: kernel_span("value".to_string()), + ident_span: Some(kernel_span("value".to_string())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: Some(Rc::new(InferredNode::TypeVariable { + id: "present_value".to_string(), + })), + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let present_variant = Rc::new(Node { + name: "Present".to_string(), + span: kernel_span("Present".to_string()), + ident_span: Some(kernel_span("Present".to_string())), + children: Rc::new(vec![present_value_field.clone()]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let absent_variant = Rc::new(Node { + name: "Absent".to_string(), + span: kernel_span("Absent".to_string()), + ident_span: Some(kernel_span("Absent".to_string())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let kernel_optional = Rc::new(Node { + name: "Optional".to_string(), + span: kernel_span("Optional".to_string()), + ident_span: Some(kernel_span("Optional".to_string())), + children: Rc::new(vec![present_variant.clone(), absent_variant.clone()]), + connective: Connective::Disj, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let kernel_bindings = v1_rt::rc_map_insert( + kernel_bindings.clone(), + intern(intern_table.clone(), "Optional".to_string()) + .id + .clone(), + Rc::new(TypeBinding { + name: "Optional".to_string(), + resolved: kernel_optional.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ); + let node_fields = inductive_fields_list_to_map(compiler_inductive_fields()); + let kernel_recursive_types = Rc::new({ + let mut __result = Vec::new(); + for name in Rc::new(v1_rt::map_keys(&compiler_recursive_types())) + .iter() + .cloned() + { + __result.push(intern(intern_table.clone(), name.clone()).id.clone()); + } + __result + }); + let kernel_recursive_type_set = Rc::new(v1_rt::map_keys(&compiler_recursive_types())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + true, + ) + }, + ); + let kernel = Rc::new(TypeEnv { + module_path: "".to_string(), + bindings: kernel_bindings.clone(), + str_bindings: str_bindings_from_bindings(kernel_bindings.clone()), + ancestry_str_bindings: v1_rt::rc_empty_map::>(), + parents: Rc::new(vec![]), + recursive_types: kernel_recursive_types.clone(), + recursive_type_set: kernel_recursive_type_set.clone(), + inductive_fields: node_fields.clone(), + source_indices: source_indices.clone(), + intern_table: intern_table.clone(), + source_visible_names: v1_rt::rc_empty_map::(), + symbol_index: empty_symbol_index(), + }); + let module_name_str = authored_name_at(source_indices.clone(), module.module.clone()); + let import_parents = Rc::new({ + let mut __result = Vec::new(); + for imp in module.resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(typed_parent) => Rc::new(vec![interface_env_for_import( + imp.module_path.clone(), + typed_parent.interface.clone().env.clone(), + )]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let scope_parents = v1_rt::concat(import_parents.clone(), Rc::new(vec![kernel.clone()])); + let import_diags = Rc::new({ + let mut __result = Vec::new(); + for imp in module.resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(_) => Rc::new(vec![]), + None => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::InternalError { + message: v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + "missing parent environment for imported module '" + .to_string(), + imp.module_path.clone(), + ), + "' while typechecking '".to_string(), + ), + module_name_str.clone(), + ), + "'".to_string(), + ), + span: imp.target_module.clone().clone().unwrap().span.clone(), + }), + module_name_str.clone(), + )]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let namespace_alias_diags = Rc::new({ + let mut __result = Vec::new(); + for item in module_items(module.module.clone()).iter().cloned() { + __result.extend( + (*if is_namespace_alias_item(item.clone(), source_indices.clone()) { + match namespace_alias_target_path(item.clone(), source_indices.clone()) { + None => Rc::new(vec![]), + Some(target_path) => { + match symbol_index_lookup(symbol_index.clone(), target_path.clone()) + { + Some(_) => Rc::new(vec![]), + None => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::UnresolvedType { + name: target_path.clone(), + span: item.span.clone(), + }), + module_name_str.clone(), + )]), + } + } + } + } else { + Rc::new(vec![]) + }) + .iter() + .cloned(), + ); + } + __result + }); + let local_bindings = module_items(module.module.clone()).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, item: Rc| { + if is_namespace_alias_item(item.clone(), source_indices.clone()) { + match namespace_alias_target_path(item.clone(), source_indices.clone()) { + None => acc.clone(), + Some(target_path) => { + match symbol_index_lookup(symbol_index.clone(), target_path.clone()) { + None => acc.clone(), + Some(target_node) => { + let binding = namespace_alias_binding_for_target( + item.clone(), + target_node.clone(), + source_indices.clone(), + ); + v1_rt::rc_map_insert( + acc.clone(), + intern(intern_table.clone(), binding.name.clone()) + .id + .clone(), + binding.clone(), + ) + } + } + } + } + } else { + match local_binding_for_item(item.clone(), source_indices.clone()) { + Some(binding) => v1_rt::rc_map_insert( + acc.clone(), + intern(intern_table.clone(), binding.name.clone()) + .id + .clone(), + binding.clone(), + ), + None => acc.clone(), + } + } + }, + ); + let param_bindings = module_items(module.module.clone()).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, item: Rc| { + let is_type_decl = match v1_rt::map_get( + &local_bindings, + intern( + intern_table.clone(), + authored_name_at(source_indices.clone(), item.clone()), + ) + .id + .clone(), + ) { + Some(_) => true, + None => false, + }; + if ((((item.params.clone().len() as i64) > 0) && is_type_decl.clone()) + && (item.body.clone() == None)) + { + { + let result = item.params.clone().iter().cloned().fold( + acc.clone(), + |pacc: Rc>>, p: Rc| { + v1_rt::rc_map_insert( + pacc, + intern( + intern_table.clone(), + authored_name_at(source_indices.clone(), p.clone()), + ) + .id + .clone(), + nominal_type_binding(authored_name_at( + source_indices.clone(), + p.clone(), + )), + ) + }, + ); + result.clone() + } + } else { + acc.clone() + } + }, + ); + let local_name_set = Rc::new(v1_rt::map_keys(&local_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, ident: i64| { + v1_rt::rc_map_insert(acc, ident.clone(), true) + }, + ); + let all_local_bindings = + v1_rt::rc_map_merge(local_bindings.clone(), param_bindings.clone()); + let kernel_cache = type_env_cache_from_bindings( + kernel_bindings.clone(), + source_indices.clone(), + compiler_recursive_name_set(), + ); + let import_union = + union_parent_type_env_caches(module.resolved_imports.clone(), parent_index.clone()); + let import_cache = import_union.cache.clone(); + let binding_forks = import_union.conflicts.clone(); + let ancestry_cache = if ((module.resolved_imports.clone().len() as i64) == 1) { + import_cache.clone() + } else { + merge_type_env_cache(import_cache.clone(), kernel_cache.clone()) + }; + let local_deps_map = Rc::new(v1_rt::map_values(&all_local_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>>(), + |acc: Rc>>>, b: Rc| { + v1_rt::rc_map_insert( + acc, + b.name.clone(), + deps_excluding_leaf_self(b.clone(), source_indices.clone()), + ) + }, + ); + let local_str_bindings = Rc::new(v1_rt::map_values(&all_local_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, b: Rc| { + v1_rt::rc_map_insert(acc, b.name.clone(), b.clone()) + }, + ); + let all_deps_map = + v1_rt::rc_map_merge(ancestry_cache.deps_map.clone(), local_deps_map.clone()); + let new_cycle_names = + detect_type_cycles_kahn(all_deps_map.clone(), local_str_bindings.clone()); + let new_cycle_set_str = new_cycle_names.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert(acc, name.clone(), true) + }, + ); + let cycle_set_str = v1_rt::rc_map_merge( + v1_rt::rc_map_merge( + ancestry_cache.cycle_set_str.clone(), + new_cycle_set_str.clone(), + ), + compiler_recursive_name_set(), + ); + let cycle_set = Rc::new({ + let mut __result = Vec::new(); + for name in Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) + .iter() + .cloned() + { + __result.push(intern(intern_table.clone(), name.clone()).id.clone()); + } + __result + }); + let cross_type_set = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + true, + ) + }, + ); + let cycle_set_for_inductive = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) + .iter() + .cloned() + .fold(v1_rt::rc_empty_set::<_>(), |acc: _, name: String| { + v1_rt::rc_set_insert(acc, name.clone()) + }); + let local_inductive_fields = build_item_inductive_fields( + module_items(module.module.clone()), + cycle_set_for_inductive.clone(), + source_indices.clone(), + ); + let parent_inductive_fields = match scope_parents.clone().first().cloned() { + Some(head_parent) => Rc::new( + scope_parents + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + head_parent.inductive_fields.clone(), + |acc: Rc>>>>, parent: Rc| { + merge_inductive_fields(acc, parent.inductive_fields.clone()) + }, + ), + None => v1_rt::rc_empty_map::>>>(), + }; + let merged_inductive_fields = merge_inductive_fields( + parent_inductive_fields.clone(), + local_inductive_fields.clone(), + ); + let ancestry_str_bindings = overlay_direct_import_exports( + ancestry_cache.str_bindings.clone(), + module.resolved_imports.clone(), + parent_index.clone(), + ); + let svn_local = Rc::new(v1_rt::map_keys(&local_str_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, n: String| { + v1_rt::rc_map_insert(acc, n.clone(), true) + }, + ); + let svn_kernel = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold( + svn_local.clone(), + |acc: Rc>, n: String| { + v1_rt::rc_map_insert(acc, n.clone(), true) + }, + ); + let source_visible_names = module.resolved_imports.clone().iter().cloned().fold( + svn_kernel.clone(), + |acc: Rc>, imp: Rc| { + if imp.is_all.clone() { + match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(parent_mod) => { + let a1 = Rc::new(v1_rt::map_keys( + &parent_mod + .interface + .clone() + .env + .clone() + .str_bindings + .clone(), + )) + .iter() + .cloned() + .fold( + acc.clone(), + |x: Rc>, n: String| { + v1_rt::rc_map_insert(x, n.clone(), true) + }, + ); + Rc::new(v1_rt::map_keys( + &parent_mod + .interface + .clone() + .env + .clone() + .ancestry_str_bindings + .clone(), + )) + .iter() + .cloned() + .fold( + a1.clone(), + |x: Rc>, n: String| { + v1_rt::rc_map_insert(x, n.clone(), true) + }, + ) + } + None => acc.clone(), + } + } else { + imp.specific_names.clone().iter().cloned().fold( + acc.clone(), + |x: Rc>, n: String| { + v1_rt::rc_map_insert(x, n.clone(), true) + }, + ) + } + }, + ); + let unresolved_env = Rc::new(TypeEnv { + module_path: module_name_str.clone(), + bindings: all_local_bindings.clone(), + str_bindings: local_str_bindings.clone(), + ancestry_str_bindings: ancestry_str_bindings.clone(), + parents: scope_parents.clone(), + recursive_types: cycle_set.clone(), + recursive_type_set: cross_type_set.clone(), + inductive_fields: merged_inductive_fields.clone(), + source_indices: source_indices.clone(), + intern_table: intern_table.clone(), + source_visible_names: source_visible_names.clone(), + symbol_index: symbol_index.clone(), + }); + let resolved = resolve_env_bindings( + unresolved_env.clone(), + module_name_str.clone(), + local_name_set.clone(), + all_deps_map.clone(), + ); + let resolved_env_out = resolved.env.clone(); + let resolved_diags = resolved.diagnostics.clone(); + let final_env = Rc::new(TypeEnv { + module_path: module_name_str.clone(), + bindings: resolved_env_out.bindings.clone(), + str_bindings: resolved_env_out.str_bindings.clone(), + ancestry_str_bindings: resolved_env_out.ancestry_str_bindings.clone(), + parents: scope_parents.clone(), + recursive_types: resolved_env_out.recursive_types.clone(), + recursive_type_set: resolved_env_out.recursive_type_set.clone(), + inductive_fields: resolved_env_out.inductive_fields.clone(), + source_indices: resolved_env_out.source_indices.clone(), + intern_table: intern_table.clone(), + source_visible_names: source_visible_names.clone(), + symbol_index: resolved_env_out.symbol_index.clone(), + }); + let cache_str_bindings = v1_rt::rc_map_merge( + final_env.ancestry_str_bindings.clone(), + final_env.str_bindings.clone(), + ); + let type_env_cache = Rc::new(TypeEnvCache { + deps_map: all_deps_map.clone(), + str_bindings: cache_str_bindings.clone(), + cycle_set_str: cycle_set_str.clone(), + variant_locals: v1_rt::rc_empty_map::>(), + }); + Rc::new(BuildTypeEnvResult { + env: final_env.clone(), + cache: type_env_cache.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat(import_diags.clone(), namespace_alias_diags.clone()), + resolved_diags.clone(), + ), + binding_forks: binding_forks.clone(), + }) + } +} + +pub fn build_type_env_unresolved( + module: Rc, + parent_index: Rc>>, + source_indices: Rc>>, + intern_table: Rc, +) -> Rc { + { + let intern_table = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold(intern_table.clone(), |t: Rc, name: String| { + intern(t, name.clone()).table.clone() + }); + let intern_table = Rc::new(vec!["Optional".to_string()]) + .iter() + .cloned() + .fold(intern_table.clone(), |t: Rc, name: String| { + intern(t, name.clone()).table.clone() + }); + let zero_span = no_span(); + let kernel_bindings = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + Rc::new(TypeBinding { + name: name.clone(), + resolved: Rc::new(Node { + name: name.clone(), + span: kernel_span(name.clone()), + ident_span: Some(kernel_span(name.clone())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + }, + ); + let present_value_field = Rc::new(Node { + name: "value".to_string(), + span: kernel_span("value".to_string()), + ident_span: Some(kernel_span("value".to_string())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: Some(Rc::new(InferredNode::TypeVariable { + id: "present_value".to_string(), + })), + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let present_variant = Rc::new(Node { + name: "Present".to_string(), + span: kernel_span("Present".to_string()), + ident_span: Some(kernel_span("Present".to_string())), + children: Rc::new(vec![present_value_field.clone()]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let absent_variant = Rc::new(Node { + name: "Absent".to_string(), + span: kernel_span("Absent".to_string()), + ident_span: Some(kernel_span("Absent".to_string())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let kernel_optional = Rc::new(Node { + name: "Optional".to_string(), + span: kernel_span("Optional".to_string()), + ident_span: Some(kernel_span("Optional".to_string())), + children: Rc::new(vec![present_variant.clone(), absent_variant.clone()]), + connective: Connective::Disj, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let kernel_bindings = v1_rt::rc_map_insert( + kernel_bindings.clone(), + intern(intern_table.clone(), "Optional".to_string()) + .id + .clone(), + Rc::new(TypeBinding { + name: "Optional".to_string(), + resolved: kernel_optional.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ); + let kernel = Rc::new(TypeEnv { + module_path: "".to_string(), + bindings: kernel_bindings.clone(), + str_bindings: str_bindings_from_bindings(kernel_bindings.clone()), + ancestry_str_bindings: v1_rt::rc_empty_map::>(), + parents: Rc::new(vec![]), + recursive_types: Rc::new(vec![]), + recursive_type_set: v1_rt::rc_empty_map::(), + inductive_fields: v1_rt::rc_empty_map::>>>(), + source_indices: source_indices.clone(), + intern_table: intern_table.clone(), + source_visible_names: v1_rt::rc_empty_map::(), + symbol_index: empty_symbol_index(), + }); + let module_name_str = authored_name_at(source_indices.clone(), module.module.clone()); + let import_parents = Rc::new({ + let mut __result = Vec::new(); + for imp in module.resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(typed_parent) => Rc::new(vec![interface_env_for_import( + imp.module_path.clone(), + typed_parent.interface.clone().env.clone(), + )]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let scope_parents = v1_rt::concat(import_parents.clone(), Rc::new(vec![kernel.clone()])); + let local_bindings = module_items(module.module.clone()).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, item: Rc| { + if is_namespace_alias_item(item.clone(), source_indices.clone()) { + acc.clone() + } else { + { + let item_ident = intern( + intern_table.clone(), + authored_name_at(source_indices.clone(), item.clone()), + ) + .id + .clone(); + let has_structure = (item.connective.clone() != Connective::NoConnective); + if has_structure.clone() { + { + let type_node = Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: item.children.clone(), + connective: item.connective.clone(), + params: Rc::new(vec![]), + inferred: None, + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + v1_rt::rc_map_insert( + acc.clone(), + item_ident.clone(), + Rc::new(TypeBinding { + name: authored_name_at( + source_indices.clone(), + item.clone(), + ), + resolved: type_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + } + } else { + if (((item.inferred.clone() != None) + && ((item.params.clone().len() as i64) == 0)) + && (item.body.clone() == None)) + { + { + let alias_node = Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: item.inferred.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + v1_rt::rc_map_insert( + acc.clone(), + item_ident.clone(), + Rc::new(TypeBinding { + name: authored_name_at( + source_indices.clone(), + item.clone(), + ), + resolved: alias_node.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + } + } else { + if ((item.transport.clone() == None) + && ((item.children.clone().len() as i64) > 0)) + { + { + let ref_node = nominal_ref_node( + authored_name_at(source_indices.clone(), item.clone()), + item.span.clone(), + item.ident_span.clone(), + ); + v1_rt::rc_map_insert( + acc.clone(), + item_ident.clone(), + Rc::new(TypeBinding { + name: authored_name_at( + source_indices.clone(), + item.clone(), + ), + resolved: ref_node.clone(), + provenance: Rc::new( + SubValueRelation::SubValueUnknown, + ), + }), + ) + } + } else { + if ((((((item.properties.clone().len() as i64) > 0) + && (item.connective.clone() == Connective::NoConnective)) + && (item.transport.clone() == None)) + && (item.inferred.clone() == None)) + && ((item.params.clone().len() as i64) == 0)) + { + v1_rt::rc_map_insert( + acc.clone(), + item_ident.clone(), + nominal_type_binding(authored_name_at( + source_indices.clone(), + item.clone(), + )), + ) + } else { + acc.clone() + } + } + } + } + } + } + }, + ); + let kernel_cache = type_env_cache_from_bindings( + kernel_bindings.clone(), + source_indices.clone(), + compiler_recursive_name_set(), + ); + let import_cache = + union_parent_type_env_caches(module.resolved_imports.clone(), parent_index.clone()) + .cache + .clone(); + let ancestry_cache = if ((module.resolved_imports.clone().len() as i64) == 1) { + import_cache.clone() + } else { + merge_type_env_cache(import_cache.clone(), kernel_cache.clone()) + }; + let local_deps_map = Rc::new(v1_rt::map_values(&local_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>>(), + |acc: Rc>>>, b: Rc| { + v1_rt::rc_map_insert( + acc, + b.name.clone(), + deps_excluding_leaf_self(b.clone(), source_indices.clone()), + ) + }, + ); + let local_str_bindings = Rc::new(v1_rt::map_values(&local_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, b: Rc| { + v1_rt::rc_map_insert(acc, b.name.clone(), b.clone()) + }, + ); + let all_deps_map = + v1_rt::rc_map_merge(ancestry_cache.deps_map.clone(), local_deps_map.clone()); + let new_cycle_names = + detect_type_cycles_kahn(all_deps_map.clone(), local_str_bindings.clone()); + let new_cycle_set_str = new_cycle_names.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert(acc, name.clone(), true) + }, + ); + let cycle_set_str = v1_rt::rc_map_merge( + v1_rt::rc_map_merge( + ancestry_cache.cycle_set_str.clone(), + new_cycle_set_str.clone(), + ), + compiler_recursive_name_set(), + ); + let cycle_set = Rc::new({ + let mut __result = Vec::new(); + for name in Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) + .iter() + .cloned() + { + __result.push(intern(intern_table.clone(), name.clone()).id.clone()); + } + __result + }); + let cross_type_set = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + true, + ) + }, + ); + let cycle_set_for_inductive = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) + .iter() + .cloned() + .fold(v1_rt::rc_empty_set::<_>(), |acc: _, name: String| { + v1_rt::rc_set_insert(acc, name.clone()) + }); + let local_inductive_fields = build_item_inductive_fields( + module_items(module.module.clone()), + cycle_set_for_inductive.clone(), + source_indices.clone(), + ); + let parent_inductive_fields = match scope_parents.clone().first().cloned() { + Some(head_parent) => Rc::new( + scope_parents + .clone() + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ) + .iter() + .cloned() + .fold( + head_parent.inductive_fields.clone(), + |acc: Rc>>>>, parent: Rc| { + merge_inductive_fields(acc, parent.inductive_fields.clone()) + }, + ), + None => v1_rt::rc_empty_map::>>>(), + }; + let merged_inductive_fields = merge_inductive_fields( + parent_inductive_fields.clone(), + local_inductive_fields.clone(), + ); + let ancestry_str_bindings = ancestry_cache.str_bindings.clone(); + let visible_str_bindings = + v1_rt::rc_map_merge(ancestry_str_bindings.clone(), local_str_bindings.clone()); + let unresolved_env = Rc::new(TypeEnv { + module_path: module_name_str.clone(), + bindings: local_bindings.clone(), + str_bindings: local_str_bindings.clone(), + ancestry_str_bindings: ancestry_str_bindings.clone(), + parents: scope_parents.clone(), + recursive_types: cycle_set.clone(), + recursive_type_set: cross_type_set.clone(), + inductive_fields: merged_inductive_fields.clone(), + source_indices: source_indices.clone(), + intern_table: intern_table.clone(), + source_visible_names: v1_rt::rc_empty_map::(), + symbol_index: empty_symbol_index(), + }); + let type_env_cache = Rc::new(TypeEnvCache { + deps_map: all_deps_map.clone(), + str_bindings: visible_str_bindings.clone(), + cycle_set_str: cycle_set_str.clone(), + variant_locals: v1_rt::rc_empty_map::>(), + }); + Rc::new(BuildTypeEnvResult { + env: unresolved_env.clone(), + cache: type_env_cache.clone(), + diagnostics: Rc::new(vec![]), + binding_forks: Rc::new(vec![]), + }) + } +} + +pub fn build_item_info( + item: Rc, + source_indices: Rc>>, + module_name: String, +) -> Rc { + { + let kind = item_kind(item.clone()); + let res_names = Rc::new({ + let mut __result = Vec::new(); + for u in item.uses.clone().iter().cloned() { + __result.push(resource_use_name_at(u.clone(), source_indices.clone())); + } + __result + }); + let item_name_str = authored_name_at(source_indices.clone(), item.clone()); + match kind.clone() { + ItemKind::FuncItem => Rc::new(ItemInfo { + name: item_name_str.clone(), + module_name: module_name.clone(), + kind: kind.clone(), + service_names: if (item.body.clone() == None) { + Rc::new(vec![]) + } else { + collect_typed_service_calls( + item.body.clone().clone().unwrap(), + source_indices.clone(), + ) + }, + resource_names: res_names.clone(), + params: item.params.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + }), + ItemKind::FnItem => Rc::new(ItemInfo { + name: item_name_str.clone(), + module_name: module_name.clone(), + kind: kind.clone(), + service_names: if (item.body.clone() == None) { + Rc::new(vec![]) + } else { + collect_typed_service_calls( + item.body.clone().clone().unwrap(), + source_indices.clone(), + ) + }, + resource_names: res_names.clone(), + params: item.params.clone(), + is_self_recursive: if (item.body.clone() == None) { + false + } else { + expr_has_self_call( + item.body.clone().clone().unwrap(), + item_name_str.clone(), + source_indices.clone(), + ) + }, + has_non_tail_self_call: if (item.body.clone() == None) { + false + } else { + expr_has_non_tail_self_call( + item.body.clone().clone().unwrap(), + item_name_str.clone(), + true, + source_indices.clone(), + ) + }, + }), + _ => Rc::new(ItemInfo { + name: item_name_str.clone(), + module_name: module_name.clone(), + kind: kind.clone(), + service_names: Rc::new(vec![]), + resource_names: res_names.clone(), + params: item.params.clone(), + is_self_recursive: false, + has_non_tail_self_call: false, + }), + } + } +} + +pub fn analyze_item(item: Rc, env: Rc, module_name: String) -> Rc { + { + let resolved = resolve_item_types(item.clone(), env.clone(), module_name.clone()); + let ritem = resolved.item.clone(); + let is_func = ((ritem.params.clone().len() as i64) > 0); + let is_zero_arg_func = ((((ritem.params.clone().len() as i64) == 0) + && (ritem.inferred.clone() != None)) + && (ritem.body.clone() != None)); + let func_sig = if (is_func.clone() || is_zero_arg_func.clone()) { + { + let declared_rt = if (ritem.inferred.clone() != None) { + Some(resolved_type(ritem.clone())) + } else { + None + }; + Some(Rc::new(DeclaredFuncSig { + name: authored_name_at(env.source_indices.clone(), ritem.clone()), + params: ritem.params.clone(), + inferred: declared_rt.clone(), + is_async: ((ritem.uses.clone().len() as i64) > 0), + output_provenance: Rc::new(vec![]), + variant_provenance: v1_rt::rc_empty_map::< + String, + Rc>>>>, + >(), + })) + } + } else { + None + }; + let svc_entries = + if ((ritem.transport.clone() != None) && ((ritem.children.clone().len() as i64) > 0)) { + Rc::new({ + let mut __result = Vec::new(); + for c in ritem.children.clone().iter().cloned() { + __result.push(service_op_entry(c.clone(), env.source_indices.clone())); + } + __result + }) + } else { + Rc::new(vec![]) + }; + let svc_local = + if ((ritem.transport.clone() != None) && ((ritem.children.clone().len() as i64) > 0)) { + { + let root = namespace_root_from_properties( + ritem.properties.clone(), + authored_name_at(env.source_indices.clone(), ritem.clone()), + env.source_indices.clone(), + ); + Some(nominal_type_binding(root.clone())) + } + } else { + None + }; + Rc::new(ItemContribution { + resolved_item: ritem.clone(), + resolve_diagnostics: resolved.diagnostics.clone(), + func_sig: func_sig.clone(), + svc_entries: svc_entries.clone(), + svc_local: svc_local.clone(), + item_info: build_item_info( + ritem.clone(), + env.source_indices.clone(), + module_name.clone(), + ), + }) + } +} + +pub fn fold_module_contributions( + mut remaining: Rc>>, + mut resolved_items: Rc>>, + mut func_sigs: Rc>>, + mut svc_registry: Rc>>>>, + mut svc_locals: Rc>>, + mut item_registry: Rc>>, + mut diag_chunks: Rc>>>>, + mut source_indices: Rc>>, +) -> Rc { + loop { + match remaining.clone().first().cloned() { + None => { + break Rc::new(LocalContributionState { + resolved_items: resolved_items.clone(), + func_sigs: func_sigs.clone(), + svc_registry: svc_registry.clone(), + svc_locals: svc_locals.clone(), + item_registry: item_registry.clone(), + diag_chunks: diag_chunks.clone(), + }); + } + Some(contribution) => { + let next_func_sigs = match contribution.func_sig.clone() { + Some(sig) => { + v1_rt::rc_map_insert(func_sigs.clone(), sig.name.clone(), sig.clone()) + } + None => func_sigs.clone(), + }; + let next_svc_registry = if ((contribution.svc_entries.clone().len() as i64) > 0) { + v1_rt::rc_map_insert( + svc_registry.clone(), + authored_name_at( + source_indices.clone(), + contribution.resolved_item.clone(), + ), + contribution.svc_entries.clone(), + ) + } else { + svc_registry.clone() + }; + let next_svc_locals = match contribution.svc_local.clone() { + Some(binding) => v1_rt::rc_map_insert( + svc_locals.clone(), + binding.name.clone(), + binding.clone(), + ), + None => svc_locals.clone(), + }; + { + let __tco_0 = Rc::new( + remaining + .iter() + .cloned() + .skip(1 as usize) + .collect::>(), + ); + let __tco_1 = + v1_rt::rc_list_push(resolved_items, contribution.resolved_item.clone()); + let __tco_2 = next_func_sigs.clone(); + let __tco_3 = next_svc_registry.clone(); + let __tco_4 = next_svc_locals.clone(); + let __tco_5 = v1_rt::rc_map_insert( + item_registry, + contribution.item_info.clone().name.clone(), + contribution.item_info.clone(), + ); + let __tco_6 = + v1_rt::rc_list_push(diag_chunks, contribution.resolve_diagnostics.clone()); + remaining = __tco_0; + resolved_items = __tco_1; + func_sigs = __tco_2; + svc_registry = __tco_3; + svc_locals = __tco_4; + item_registry = __tco_5; + diag_chunks = __tco_6; + continue; + } + } + } + } +} + +pub fn constructor_binding_authority() -> String { + thread_local! { + static CACHED: String = { + "Constructor-owner ruling (§1c): a module's constructor namespace is FLAT — its own coproduct declarations plus its DIRECT imports' contributions, never transitive ancestry. Each arm name binds to its owning coproduct NODE (the binding edge carries the owner; no name re-lookup, so the owner need not be name-visible). One arm name bound to two DIFFERENT owners in one file = VariantCollision at env construction (the per-file wall); the same declaration reached via two import paths is one owner, not a collision. Kernel coproduct arms (Optional/Witness/...) merge low-priority afterwards, prelude semantics.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn insert_variant_owner_checked( + state: Rc, + arm_name: String, + owner: Rc, + source_indices: Rc>>, + module_name: String, +) -> Rc { + match v1_rt::map_get(&state.locals.clone(), arm_name.clone()) { + Some(prev) => { + let prev_name = authored_name_at(source_indices.clone(), prev.resolved.clone()); + let owner_name = authored_name_at(source_indices.clone(), owner.clone()); + let same_owner = (((prev_name.clone() == owner_name.clone()) + && (prev.resolved.clone().span.clone().file.clone() + == owner.span.clone().file.clone())) + && (prev.resolved.clone().span.clone().start.clone() + == owner.span.clone().start.clone())); + if same_owner.clone() { + state.clone() + } else { + Rc::new(VariantFoldState { + locals: state.locals.clone(), + collision_errors: v1_rt::concat( + state.collision_errors.clone(), + Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::VariantCollision { + variant: arm_name.clone(), + enum1: prev_name.clone(), + enum2: owner_name.clone(), + span: owner.span.clone(), + }), + module_name.clone(), + )]), + ), + }) + } + } + None => Rc::new(VariantFoldState { + locals: v1_rt::rc_map_insert( + state.locals.clone(), + arm_name.clone(), + Rc::new(TypeBinding { + name: arm_name.clone(), + resolved: owner.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ), + collision_errors: state.collision_errors.clone(), + }), + } +} + +pub fn bind_coproduct_item_arms( + state: Rc, + item: Rc, + source_indices: Rc>>, + module_name: String, +) -> Rc { + item.children.clone().iter().cloned().fold( + state.clone(), + |vacc: Rc, child: Rc| { + insert_variant_owner_checked( + vacc, + authored_name_at(source_indices.clone(), child.clone()), + item.clone(), + source_indices.clone(), + module_name.clone(), + ) + }, + ) +} + +pub fn build_local_variants( + items: Rc>>, + source_indices: Rc>>, + module_name: String, + init: Rc, +) -> Rc { + items + .clone() + .iter() + .cloned() + .fold(init.clone(), |acc: Rc, item: Rc| { + let item_is_coproduct = (item.connective.clone() == Connective::Disj); + if item_is_coproduct.clone() { + bind_coproduct_item_arms( + acc.clone(), + item.clone(), + source_indices.clone(), + module_name.clone(), + ) + } else { + acc.clone() + } + }) +} + +pub fn merge_global_bare_variant_locals_cost_note() -> String { + thread_local! { + static CACHED: String = { + "Cost shape (bare-minimum-cost, DESIGN 6): the census-eligible variant-owner pairs depend only on global_bare and the name-census si — whole-closure facts identical for every module — so build_global_bare_variant_locals computes them ONCE per closure in typecheck_with_census_extra and the base map threads down realize_module -> typecheck_module -> build_module_context. The former per-module shape rescanned the whole census and re-inserted every eligible pair into every module's locals: 464 modules x 12,554 census keys = 5.8M iterations and 1.29M persistent-map inserts = 31s of the host_effect_realize entry compile (typecheck-perf investigation, 2026-07-31; PR 7398 landed build_global_bare_variant_locals beside the per-module fold but never wired it). map_merge(base, state.locals) is value-identical to the old fold: overlay wins on collision exactly as the old skip-if-present arm kept state's binding, and the old checked-insert collision arm was unreachable (presence was checked before insert), so the global merge contributed zero collision errors then and now. Fidelity of the hoisted si: authored_name_at reads names identically under the raw closure source_indices and the kernel-augmented env.source_indices (kernel spans compute the same name in both arms; non-kernel misses fall back to node.name in both), and the census owners all live in closure files, so eligibility is unchanged.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn merge_global_bare_variant_locals( + state: Rc, + global_variant_base: Rc>>, +) -> Rc { + Rc::new(VariantFoldState { + locals: v1_rt::rc_map_merge(global_variant_base.clone(), state.locals.clone()), + collision_errors: state.collision_errors.clone(), + }) +} + +pub fn build_global_bare_census( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc>> { + build_symbol_index_census(modules.clone(), source_indices.clone()) + .global_bare + .clone() +} + +pub fn build_global_bare_variant_locals( + global_bare: Rc>>, + source_indices: Rc>>, +) -> Rc>> { + Rc::new(v1_rt::map_keys(&global_bare)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| match v1_rt::map_get( + &global_bare, + name.clone(), + ) + .as_deref() + .cloned() + { + Some(GlobalBareLookupState::GlobalBareUniqueBinding { binding, .. }) => { + let owner = binding.resolved.clone(); + if ((owner.connective.clone() == Connective::Disj) + && has_child_named(owner.clone(), name.clone(), source_indices.clone())) + { + v1_rt::rc_map_insert( + acc.clone(), + name.clone(), + Rc::new(TypeBinding { + name: name.clone(), + resolved: owner.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + } else { + acc.clone() + } + } + _ => acc.clone(), + }, + ) +} + +pub fn reexport_chain_authority() -> String { + thread_local! { + static CACHED: String = { + "A module re-exports its specific-name imports (get_exported_names in v1.compiler.resolve), so `import proxy { B }` where proxy itself imports B is an EXPLICIT import under the §1c ruling — the binder follows the specific-name chain to the defining module's coproduct (the import DAG is acyclic, so the recursion terminates; a chain hop that dead-ends binds nothing and the use site fails closed as UnresolvedType). Glob (is_all) imports bind the target's OWN coproduct arms only — glob re-export pass-through is not modeled here, matching get_exported_names which excludes is_all imports from the export surface.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn empty_variant_export_surface() -> Rc { + Rc::new(VariantExportSurface { + arm_owners: v1_rt::rc_empty_map::>(), + enum_items: v1_rt::rc_empty_map::>(), + }) +} + +pub fn add_coproduct_to_variant_surface( + acc: Rc, + item: Rc, + source_indices: Rc>>, +) -> Rc { + { + let enum_items = v1_rt::rc_map_insert( + acc.enum_items.clone(), + authored_name_at(source_indices.clone(), item.clone()), + item.clone(), + ); + let arm_owners = item.children.clone().iter().cloned().fold( + acc.arm_owners.clone(), + |arms: Rc>>, child: Rc| { + v1_rt::rc_map_insert( + arms, + authored_name_at(source_indices.clone(), child.clone()), + item.clone(), + ) + }, + ); + Rc::new(VariantExportSurface { + arm_owners: arm_owners.clone(), + enum_items: enum_items.clone(), + }) + } +} + +pub fn collect_own_variant_export_surface( + items: Rc>>, + source_indices: Rc>>, +) -> Rc { + items.clone().iter().cloned().fold( + empty_variant_export_surface(), + |acc: Rc, item: Rc| { + let item_is_coproduct = (item.connective.clone() == Connective::Disj); + if item_is_coproduct.clone() { + add_coproduct_to_variant_surface(acc.clone(), item.clone(), source_indices.clone()) + } else { + acc.clone() + } + }, + ) +} + +pub fn merge_name_from_proxy_surface( + acc: Rc, + proxy: Rc, + name: String, +) -> Rc { + { + let with_arm = match v1_rt::map_get(&proxy.arm_owners.clone(), name.clone()) { + Some(owner) => Rc::new(VariantExportSurface { + arm_owners: v1_rt::rc_map_insert( + acc.arm_owners.clone(), + name.clone(), + owner.clone(), + ), + enum_items: acc.enum_items.clone(), + }), + None => acc.clone(), + }; + match v1_rt::map_get(&proxy.enum_items.clone(), name.clone()) { + Some(item) => Rc::new(VariantExportSurface { + arm_owners: with_arm.arm_owners.clone(), + enum_items: v1_rt::rc_map_insert( + with_arm.enum_items.clone(), + name.clone(), + item.clone(), + ), + }), + None => with_arm.clone(), + } + } +} + +pub fn reexport_variant_surface_fragment( + imp: Rc, + surfaces: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let proxy_path = import_module_path_at(imp.clone(), source_indices.clone()); + match v1_rt::map_get(&surfaces, proxy_path.clone()) { + None => empty_variant_export_surface(), + Some(proxy) => import_specific_names_at(imp.clone(), source_indices.clone()) + .iter() + .cloned() + .fold( + empty_variant_export_surface(), + |acc: Rc, name: String| { + merge_name_from_proxy_surface(acc, proxy.clone(), name.clone()) + }, + ), + } + } +} + +pub fn merge_variant_surface_fragments( + acc: Rc, + frag: Rc, +) -> Rc { + Rc::new(VariantExportSurface { + arm_owners: v1_rt::rc_map_merge(acc.arm_owners.clone(), frag.arm_owners.clone()), + enum_items: v1_rt::rc_map_merge(acc.enum_items.clone(), frag.enum_items.clone()), + }) +} + +pub fn build_variant_export_surface( + tm: Rc, + surfaces: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let own = collect_own_variant_export_surface(tm.items.clone(), source_indices.clone()); + let reexports = Rc::new({ + let mut __result = Vec::new(); + for imp in module_imports(tm.module.clone()).iter().cloned() { + if !import_is_all(imp.clone()) { + __result.push(imp); + } + } + __result + }) + .iter() + .cloned() + .fold( + empty_variant_export_surface(), + |acc: Rc, imp: Rc| { + merge_variant_surface_fragments( + acc, + reexport_variant_surface_fragment( + imp.clone(), + surfaces.clone(), + source_indices.clone(), + ), + ) + }, + ); + Rc::new(VariantExportSurface { + arm_owners: v1_rt::rc_map_merge(reexports.arm_owners.clone(), own.arm_owners.clone()), + enum_items: v1_rt::rc_map_merge(reexports.enum_items.clone(), own.enum_items.clone()), + }) + } +} + +pub fn bind_imported_name_from_surface( + state: Rc, + surface: Rc, + name: String, + source_indices: Rc>>, + module_name: String, +) -> Rc { + { + let after_enum = match v1_rt::map_get(&surface.enum_items.clone(), name.clone()) { + Some(item) => bind_coproduct_item_arms( + state.clone(), + item.clone(), + source_indices.clone(), + module_name.clone(), + ), + None => state.clone(), + }; + match v1_rt::map_get(&surface.arm_owners.clone(), name.clone()) { + Some(owner) => insert_variant_owner_checked( + after_enum.clone(), + name.clone(), + owner.clone(), + source_indices.clone(), + module_name.clone(), + ), + None => after_enum.clone(), + } + } +} + +pub fn build_imported_variants( + resolved_imports: Rc>>, + parent_index: Rc>>, + variant_surfaces: Rc>>, + source_indices: Rc>>, + module_name: String, + init: Rc, +) -> Rc { + resolved_imports.clone().iter().cloned().fold( + init.clone(), + |acc: Rc, imp: Rc| { + let with_glob = if imp.is_all.clone() { + { + let source_items = match v1_rt::map_get(&parent_index, imp.module_path.clone()) + { + Some(parent_tm) => parent_tm.items.clone(), + None => Rc::new(vec![]), + }; + source_items.clone().iter().cloned().fold( + acc.clone(), + |iacc: Rc, item: Rc| { + let item_is_coproduct = (item.connective.clone() == Connective::Disj); + if item_is_coproduct.clone() { + bind_coproduct_item_arms( + iacc.clone(), + item.clone(), + source_indices.clone(), + module_name.clone(), + ) + } else { + iacc.clone() + } + }, + ) + } + } else { + acc.clone() + }; + imp.specific_names.clone().iter().cloned().fold( + with_glob.clone(), + |nacc: Rc, name: String| { + let surface = match v1_rt::map_get(&variant_surfaces, imp.module_path.clone()) { + Some(s) => s.clone(), + None => empty_variant_export_surface(), + }; + bind_imported_name_from_surface( + nacc, + surface.clone(), + name.clone(), + source_indices.clone(), + module_name.clone(), + ) + }, + ) + }, + ) +} + +pub fn build_module_context( + contributions: Rc>>, + parent_index: Rc>>, + variant_surfaces: Rc>>, + resolved_imports: Rc>>, + env: Rc, + module_name: String, + global_variant_base: Rc>>, +) -> Rc { + { + let local = fold_module_contributions( + contributions.clone(), + Rc::new(vec![]), + v1_rt::rc_empty_map::>(), + v1_rt::rc_empty_map::>>>(), + v1_rt::rc_empty_map::>(), + v1_rt::rc_empty_map::>(), + Rc::new(vec![]), + env.source_indices.clone(), + ); + let local_variant_fold = build_local_variants( + local.resolved_items.clone(), + env.source_indices.clone(), + module_name.clone(), + Rc::new(VariantFoldState { + locals: v1_rt::rc_empty_map::>(), + collision_errors: Rc::new(vec![]), + }), + ); + let variant_fold = merge_global_bare_variant_locals( + build_imported_variants( + resolved_imports.clone(), + parent_index.clone(), + variant_surfaces.clone(), + env.source_indices.clone(), + module_name.clone(), + local_variant_fold.clone(), + ), + global_variant_base.clone(), + ); + let variant_collision_errors = variant_fold.collision_errors.clone(); + let env_variant_locals = + merge_kernel_variant_locals_low_priority(env.clone(), variant_fold.locals.clone()); + let census_scope = Rc::new(v1_rt::map_keys(&env.symbol_index.clone().services.clone())) + .iter() + .cloned() + .fold( + Rc::new(InferScopeComponents { + svc_registry: v1_rt::rc_empty_map::>>>(), + svc_locals: v1_rt::rc_empty_map::>(), + }), + |acc: Rc, sname: String| match v1_rt::map_get( + &env.symbol_index.clone().services.clone(), + sname.clone(), + ) { + Some(sentry) => { + let sitem = sentry.item.clone(); + let entries = Rc::new({ + let mut __result = Vec::new(); + for c in sitem.children.clone().iter().cloned() { + __result.push(Rc::new(OpEntry { + name: authored_name_at(env.source_indices.clone(), c.clone()), + outputs: inferred_to_outputs( + qualify_borrowed_inferred( + c.inferred.clone(), + sentry.module_path.clone(), + env.clone(), + v1_rt::rc_empty_map::(), + ), + c.span.clone(), + env.source_indices.clone(), + ), + params: c.params.clone(), + })); + } + __result + }); + let root = namespace_root_from_properties( + sitem.properties.clone(), + sname.clone(), + env.source_indices.clone(), + ); + Rc::new(InferScopeComponents { + svc_registry: v1_rt::rc_map_insert( + acc.svc_registry.clone(), + sname.clone(), + entries.clone(), + ), + svc_locals: v1_rt::rc_map_insert( + acc.svc_locals.clone(), + root.clone(), + nominal_type_binding(root.clone()), + ), + }) + } + None => acc.clone(), + }, + ); + let merged_scope = merge_scope_from_imports( + resolved_imports.clone(), + parent_index.clone(), + env.clone(), + v1_rt::rc_map_merge( + census_scope.svc_registry.clone(), + local.svc_registry.clone(), + ), + v1_rt::rc_map_merge(census_scope.svc_locals.clone(), local.svc_locals.clone()), + ); + let parent_envs = Rc::new({ + let mut __result = Vec::new(); + for imp in resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { + Some(typed_parent) => Rc::new(vec![typed_parent.func_env.clone()]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let resolve_result = resolve_func_sigs( + local.func_sigs.clone(), + parent_envs.clone(), + local.resolved_items.clone(), + module_name.clone(), + env.source_indices.clone(), + ); + let all_locals = Rc::new(v1_rt::map_values(&merged_scope.svc_locals.clone())) + .iter() + .cloned() + .fold( + env_variant_locals.clone(), + |acc: Rc>>, binding: Rc| { + v1_rt::rc_map_insert(acc, binding.name.clone(), binding.clone()) + }, + ); + Rc::new(ModuleContext { + resolved_items: local.resolved_items.clone(), + func_env: resolve_result.func_env.clone(), + svc_registry: merged_scope.svc_registry.clone(), + locals: all_locals.clone(), + variant_locals: env_variant_locals.clone(), + item_registry: local.item_registry.clone(), + diagnostics: v1_rt::concat( + v1_rt::concat( + Rc::new({ + let mut __result = Vec::new(); + for c in local.diag_chunks.clone().iter().cloned() { + __result.extend((*c.clone()).iter().cloned()); + } + __result + }), + resolve_result.diagnostics.clone(), + ), + variant_collision_errors.clone(), + ), + }) + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TypecheckModuleResult { + pub typed: Rc, + pub diagnostics: Rc>>, + pub binding_forks: Rc>>, +} + +pub fn typecheck_module( + resolved: Rc, + parent_index: Rc>>, + variant_surfaces: Rc>>, + source_indices: Rc>>, + intern_table: Rc, + symbol_index: Rc, + global_variant_base: Rc>>, +) -> Rc { + { + let env_result = build_type_env( + resolved.clone(), + parent_index.clone(), + source_indices.clone(), + intern_table.clone(), + symbol_index.clone(), + ); + let env = env_result.env.clone(); + let env_cache = env_result.cache.clone(); + let env_diags = env_result.diagnostics.clone(); + let env_errors = Rc::new({ + let mut __result = Vec::new(); + for d in env_diags.clone().iter().cloned() { + if is_error_diagnostic(d.diagnostic.clone()) { + __result.push(d); + } + } + __result + }); + let seed_diags = builtin_kernel_seed_diagnostics(); + if ((env_errors.clone().len() as i64) > 0) { + return Rc::new(TypecheckModuleResult { + typed: Rc::new(TypedModule { + module: resolved.module.clone(), + items: Rc::new(vec![]), + type_env: env.clone(), + type_env_cache: env_cache.clone(), + interface: build_module_interface( + authored_name_at(source_indices.clone(), resolved.module.clone()), + resolved.module.clone(), + env.clone(), + env_cache.clone(), + source_indices.clone(), + ), + func_env: Rc::new(ResolvedFuncEnv { + name: authored_name_at(source_indices.clone(), resolved.module.clone()), + local: v1_rt::rc_empty_map::>(), + parents: Rc::new(vec![]), + }), + item_registry: v1_rt::rc_empty_map::>(), + occurrence_transport: Some(resolved.occurrence_transport.clone()), + }), + diagnostics: v1_rt::concat(env_diags.clone(), seed_diags.clone()), + binding_forks: env_result.binding_forks.clone(), + }); + } + let resolved_module_name = + authored_name_at(source_indices.clone(), resolved.module.clone()); + let contributions = Rc::new({ + let mut __result = Vec::new(); + for item in module_items(resolved.module.clone()).iter().cloned() { + __result.push(analyze_item( + item.clone(), + env.clone(), + resolved_module_name.clone(), + )); + } + __result + }); + let ctx = build_module_context( + contributions.clone(), + parent_index.clone(), + variant_surfaces.clone(), + resolved.resolved_imports.clone(), + env.clone(), + resolved_module_name.clone(), + global_variant_base.clone(), + ); + let data_locals = ctx.resolved_items.clone().iter().cloned().fold( + ctx.locals.clone(), + |acc: Rc>>, item: Rc| { + if ((((item.body.clone() != None) && ((item.params.clone().len() as i64) == 0)) + && (item.inferred.clone() == None)) + && (item.type_annotation.clone() != None)) + { + v1_rt::rc_map_insert( + acc.clone(), + authored_name_at(source_indices.clone(), item.clone()), + Rc::new(TypeBinding { + name: authored_name_at(source_indices.clone(), item.clone()), + resolved: item.type_annotation.clone().clone().unwrap(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + } else { + acc.clone() + } + }, + ); + let infer_scope = Rc::new(InferScope { + type_env: env.clone(), + func_env: ctx.func_env.clone(), + locals: data_locals.clone(), + body_locals: v1_rt::rc_empty_map::(), + match_bound_names: v1_rt::rc_empty_map::(), + module_name: resolved_module_name.clone(), + service_registry: ctx.svc_registry.clone(), + item_registry: ctx.item_registry.clone(), + caller_decl_name: "".to_string(), + lambda_param_provenance: v1_rt::rc_empty_map::>(), + }); + let typed_item_results = infer_items(ctx.resolved_items.clone(), infer_scope.clone()); + let typed_items = Rc::new({ + let mut __result = Vec::new(); + for tir in typed_item_results.clone().iter().cloned() { + __result.push(tir.item.clone()); + } + __result + }); + let infer_diags = Rc::new({ + let mut __result = Vec::new(); + for tir in typed_item_results.clone().iter().cloned() { + __result.extend((*tir.diagnostics.clone()).iter().cloned()); + } + __result + }); + let updated_func_env = populate_output_provenance( + typed_items.clone(), + ctx.func_env.clone(), + env.clone(), + data_locals.clone(), + ); + let reannotated_items = Rc::new({ + let mut __result = Vec::new(); + for item in typed_items.clone().iter().cloned() { + __result.push( + if (item.is_self_recursive.clone() && (item.body.clone() != None)) { + Rc::new(Node { + name: item.name.clone(), + span: item.span.clone(), + ident_span: item.ident_span.clone(), + children: item.children.clone(), + params: item.params.clone(), + inferred: item.inferred.clone(), + return_cardinality: item.return_cardinality.clone(), + uses: item.uses.clone(), + body: Some(annotate_descent_evidence( + item.body.clone().clone().unwrap(), + authored_name_at(source_indices.clone(), item.clone()), + item.params.clone(), + env.clone(), + data_locals.clone(), + updated_func_env.clone(), + )), + connective: item.connective.clone(), + transport: item.transport.clone(), + properties: item.properties.clone(), + type_annotation: item.type_annotation.clone(), + is_self_recursive: item.is_self_recursive.clone(), + has_non_tail_self_call: item.has_non_tail_self_call.clone(), + match_pattern: item.match_pattern.clone(), + expr_data: item.expr_data.clone(), + ident: None, + }) + } else { + item.clone() + }, + ); + } + __result + }); + let module_type_env_cache = Rc::new(TypeEnvCache { + deps_map: env_cache.deps_map.clone(), + str_bindings: env_cache.str_bindings.clone(), + cycle_set_str: env_cache.cycle_set_str.clone(), + variant_locals: ctx.variant_locals.clone(), + }); + let typed_base = module_node( + resolved_module_name.clone(), + module_imports(resolved.module.clone()), + ctx.resolved_items.clone(), + resolved.module.clone().span.clone(), + ); + let typed_module = Rc::new(Node { + ident_span: resolved.module.clone().ident_span.clone(), + ..(*typed_base.clone()).clone() + }); + Rc::new(TypecheckModuleResult { + typed: Rc::new(TypedModule { + module: typed_module.clone(), + items: reannotated_items.clone(), + type_env: env.clone(), + type_env_cache: module_type_env_cache.clone(), + interface: build_module_interface( + resolved_module_name.clone(), + typed_module.clone(), + env.clone(), + module_type_env_cache.clone(), + source_indices.clone(), + ), + func_env: updated_func_env.clone(), + item_registry: ctx.item_registry.clone(), + occurrence_transport: Some(resolved.occurrence_transport.clone()), + }), + diagnostics: frontier_occurrence_budget_checked( + resolved_module_name.clone(), + resolved.module.clone().span.clone(), + v1_rt::concat( + v1_rt::concat( + v1_rt::concat(env_diags.clone(), ctx.diagnostics.clone()), + infer_diags.clone(), + ), + seed_diags.clone(), + ), + ), + binding_forks: env_result.binding_forks.clone(), + }) + } +} + +pub fn typecheck_module_isolated( + resolved: Rc, + parent_index: Rc>>, + source_indices: Rc>>, + intern_table: Rc, +) -> Rc { + typecheck_module( + resolved.clone(), + parent_index.clone(), + v1_rt::rc_empty_map::>(), + source_indices.clone(), + intern_table.clone(), + empty_symbol_index(), + v1_rt::rc_empty_map::>(), + ) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EnvResolveResult { + pub env: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BindingResult { + pub binding: Rc, + pub diagnostics: Rc>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BindingsAccum { + pub bindings: Rc>>, + pub str_bindings: Rc>>, + pub diagnostics: Rc>>, +} + +pub fn resolve_env_bindings( + env: Rc, + module_name: String, + local_names: Rc>, + deps_map: Rc>>>, +) -> Rc { + { + let remaining = Rc::new({ + let mut __result = Vec::new(); + for b in Rc::new({ + let mut __result = Vec::new(); + for b in Rc::new(v1_rt::map_values(&env.bindings.clone())) + .iter() + .cloned() + { + if v1_rt::map_contains_key( + &local_names, + intern(env.intern_table.clone(), b.name.clone()).id.clone(), + ) { + __result.push(b); + } + } + __result + }) + .iter() + .cloned() + { + __result.push(b.name.clone()); + } + __result + }); + topo_resolve_types( + remaining.clone(), + env.clone(), + module_name.clone(), + Rc::new(vec![]), + local_names.clone(), + deps_map.clone(), + (remaining.clone().len() as i64), + ) + } +} + +pub fn topo_resolve_types( + mut remaining: Rc>, + mut env: Rc, + mut module_name: String, + mut diagnostics: Rc>>, + mut local_names: Rc>, + mut deps_map: Rc>>>, + mut fuel: i64, +) -> Rc { + loop { + if ((remaining.clone().len() as i64) == 0) { + return Rc::new(EnvResolveResult { + env: env.clone(), + diagnostics: diagnostics.clone(), + }); + } + let remaining_set = remaining + .clone() + .iter() + .cloned() + .fold(v1_rt::rc_empty_set::<_>(), |acc: _, name: String| { + v1_rt::rc_set_insert(acc, name.clone()) + }); + let ready = Rc::new({ + let mut __result = Vec::new(); + for name in remaining.clone().iter().cloned() { + if match v1_rt::map_get(&deps_map, name.clone()) { + Some(deps) => { + let mut __all = true; + for dep in deps.clone().iter().cloned() { + if !((((is_kernel_type(dep.clone()) + || (dep.clone() == "None".to_string())) + || (dep.clone() == "".to_string())) + || is_recursive_type_by_name(env.clone(), dep.clone())) + || (v1_rt::set_contains(&remaining_set, dep.clone()) == false)) + { + __all = false; + break; + } + } + __all + } + None => true, + } { + __result.push(name); + } + } + __result + }); + if ((ready.clone().len() as i64) == 0) { + { + let stuck_accum = remaining.clone().iter().cloned().fold( + Rc::new(BindingsAccum { + bindings: env.bindings.clone(), + str_bindings: env.str_bindings.clone(), + diagnostics: Rc::new(vec![]), + }), + |acc: Rc, name: String| { + let ident = intern(env.intern_table.clone(), name.clone()).id.clone(); + match v1_rt::map_get(&env.bindings.clone(), ident.clone()) { + Some(binding) => { + let pre = binding.resolved.clone(); + let result = + resolve_node(pre.clone(), env.clone(), module_name.clone()); + let resolved = preserve_nominal_brand_on_resolve( + pre.clone(), + result.resolved.clone(), + binding.name.clone(), + env.source_indices.clone(), + ); + let updated_binding = Rc::new(TypeBinding { + name: name.clone(), + resolved: resolved.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }); + Rc::new(BindingsAccum { + bindings: v1_rt::rc_map_insert( + acc.bindings.clone(), + ident.clone(), + updated_binding.clone(), + ), + str_bindings: v1_rt::rc_map_insert( + acc.str_bindings.clone(), + name.clone(), + updated_binding.clone(), + ), + diagnostics: v1_rt::concat( + acc.diagnostics.clone(), + result.diagnostics.clone(), + ), + }) + } + None => acc.clone(), + } + }, + ); + return Rc::new(EnvResolveResult { + env: Rc::new(TypeEnv { + module_path: env.module_path.clone(), + bindings: stuck_accum.bindings.clone(), + str_bindings: stuck_accum.str_bindings.clone(), + ancestry_str_bindings: env.ancestry_str_bindings.clone(), + parents: env.parents.clone(), + recursive_types: env.recursive_types.clone(), + recursive_type_set: env.recursive_type_set.clone(), + inductive_fields: env.inductive_fields.clone(), + source_indices: env.source_indices.clone(), + intern_table: env.intern_table.clone(), + source_visible_names: env.source_visible_names.clone(), + symbol_index: env.symbol_index.clone(), + }), + diagnostics: v1_rt::concat( + diagnostics.clone(), + stuck_accum.diagnostics.clone(), + ), + }); + } + } + let ready_accum = ready.clone().iter().cloned().fold( + Rc::new(BindingsAccum { + bindings: env.bindings.clone(), + str_bindings: env.str_bindings.clone(), + diagnostics: Rc::new(vec![]), + }), + |acc: Rc, name: String| { + let ident = intern(env.intern_table.clone(), name.clone()).id.clone(); + match v1_rt::map_get(&env.bindings.clone(), ident.clone()) { + Some(binding) => { + let pre = binding.resolved.clone(); + let result = resolve_node(pre.clone(), env.clone(), module_name.clone()); + let resolved = preserve_nominal_brand_on_resolve( + pre.clone(), + result.resolved.clone(), + binding.name.clone(), + env.source_indices.clone(), + ); + let updated_binding = Rc::new(TypeBinding { + name: name.clone(), + resolved: resolved.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }); + Rc::new(BindingsAccum { + bindings: v1_rt::rc_map_insert( + acc.bindings.clone(), + ident.clone(), + updated_binding.clone(), + ), + str_bindings: v1_rt::rc_map_insert( + acc.str_bindings.clone(), + name.clone(), + updated_binding.clone(), + ), + diagnostics: v1_rt::concat( + acc.diagnostics.clone(), + result.diagnostics.clone(), + ), + }) + } + None => acc.clone(), + } + }, + ); + let ready_set = ready.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert(acc, name.clone(), true) + }, + ); + let next_remaining = Rc::new({ + let mut __result = Vec::new(); + for name in remaining.clone().iter().cloned() { + if (emit_map_has(ready_set.clone(), name.clone()) == false) { + __result.push(name); + } + } + __result + }); + { + let __tco_0 = next_remaining.clone(); + let __tco_1 = Rc::new(TypeEnv { + module_path: env.module_path.clone(), + bindings: ready_accum.bindings.clone(), + str_bindings: ready_accum.str_bindings.clone(), + ancestry_str_bindings: env.ancestry_str_bindings.clone(), + parents: env.parents.clone(), + recursive_types: env.recursive_types.clone(), + recursive_type_set: env.recursive_type_set.clone(), + inductive_fields: env.inductive_fields.clone(), + source_indices: env.source_indices.clone(), + intern_table: env.intern_table.clone(), + source_visible_names: env.source_visible_names.clone(), + symbol_index: env.symbol_index.clone(), + }); + let __tco_2 = v1_rt::concat(diagnostics, ready_accum.diagnostics.clone()); + let __tco_3 = (fuel - 1); + remaining = __tco_0; + env = __tco_1; + diagnostics = __tco_2; + fuel = __tco_3; + continue; + } + } +} + +pub fn collect_parent_envs( + resolved: Rc, + module_index: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let modules = Rc::new({ + let mut __result = Vec::new(); + for imp in resolved.resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&module_index, imp.module_path.clone()) { + Some(typed) => Rc::new(vec![typed.clone()]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let resolved_mod_name = authored_name_at(source_indices.clone(), resolved.module.clone()); + let diagnostics = Rc::new({ + let mut __result = Vec::new(); + for imp in resolved.resolved_imports.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&module_index, imp.module_path.clone()) { + Some(_) => Rc::new(vec![]), + None => Rc::new(vec![make_error_node( + Rc::new(CompilerDiagnostic::InternalError { + message: v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + v1_rt::concat( + "missing parent environment for imported module '" + .to_string(), + imp.module_path.clone(), + ), + "' while ordering '".to_string(), + ), + resolved_mod_name.clone(), + ), + "'".to_string(), + ), + span: imp.target_module.clone().clone().unwrap().span.clone(), + }), + resolved_mod_name.clone(), + )]), + }) + .iter() + .cloned(), + ); + } + __result + }); + Rc::new(ParentModulesResult { + modules: modules.clone(), + diagnostics: diagnostics.clone(), + }) + } +} + +pub fn variant_has_positional_payload_shape( + variant: Rc, + source_indices: Rc>>, +) -> bool { + (((variant.children.clone().len() as i64) == 1) + && match variant.children.clone().first().cloned() { + Some(f) => (field_node_name_at(f.clone(), source_indices.clone()) == "0".to_string()), + None => false, + }) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EnumVariantShapeSets { + pub fielded: Rc>, + pub positional_payload: Rc>, +} + +pub fn enum_variant_shape_sets_for_item( + acc: Rc, + item: Rc, + si: Rc>>, + type_summaries: Rc>>, +) -> Rc { + { + let item_name = authored_name_at(si.clone(), item.clone()); + let is_enum = match v1_rt::map_get(&type_summaries, item_name.clone()) { + Some(summary) => match (*summary.repr.clone()).clone() { + TypeRepr::EnumRepr { unit_only: _, .. } => true, + _ => false, + }, + None => false, + }; + if is_enum.clone() { + item.children.clone().iter().cloned().fold( + acc, + |vacc: Rc, variant: Rc| { + let qualified = v1_rt::concat( + v1_rt::concat(item_name.clone(), "::".to_string()), + authored_name_at(si.clone(), variant.clone()), + ); + let is_positional_payload = + variant_has_positional_payload_shape(variant.clone(), si.clone()); + let has_fields = ((variant.children.clone().len() as i64) > 0); + if is_positional_payload.clone() { + Rc::new(EnumVariantShapeSets { + fielded: vacc.fielded.clone(), + positional_payload: v1_rt::rc_set_insert( + vacc.positional_payload.clone(), + qualified.clone(), + ), + }) + } else { + if has_fields.clone() { + Rc::new(EnumVariantShapeSets { + fielded: v1_rt::rc_set_insert( + vacc.fielded.clone(), + qualified.clone(), + ), + positional_payload: vacc.positional_payload.clone(), + }) + } else { + vacc.clone() + } + } + }, + ) + } else { + acc + } + } +} + +pub fn build_enum_variant_shape_sets( + modules: Rc>>, + type_summaries: Rc>>, +) -> Rc { + modules.clone().iter().cloned().fold( + Rc::new(EnumVariantShapeSets { + fielded: v1_rt::rc_empty_set::(), + positional_payload: v1_rt::rc_empty_set::(), + }), + |acc: Rc, m: Rc| { + m.items.clone().iter().cloned().fold( + acc, + |inner: Rc, item: Rc| { + enum_variant_shape_sets_for_item( + inner, + item.clone(), + m.type_env.clone().source_indices.clone(), + type_summaries.clone(), + ) + }, + ) + }, + ) +} + +pub fn build_emit_graph_info(modules: Rc>>) -> Rc { + { + let init = Rc::new(EmitInfoBuildState { + type_summaries: v1_rt::rc_empty_map::>(), + type_decl_items: v1_rt::rc_empty_map::>(), + fn_decl_items: v1_rt::rc_empty_map::>(), + }); + let built_raw = modules.clone().iter().cloned().fold( + init.clone(), + |state: Rc, typed_module: Rc| { + typed_module.items.clone().iter().cloned().fold( + state, + |inner_state: Rc, item: Rc| { + add_emit_item_summary( + inner_state, + item.clone(), + typed_module.type_env.clone().source_indices.clone(), + ) + }, + ) + }, + ); + let built = Rc::new(EmitInfoBuildState { + type_summaries: close_fn_fields(built_raw.type_summaries.clone()), + type_decl_items: built_raw.type_decl_items.clone(), + fn_decl_items: built_raw.fn_decl_items.clone(), + }); + let all_recursive = modules.clone().iter().cloned().fold( + v1_rt::rc_empty_set::<_>(), + |acc: _, m: Rc| { + Rc::new(v1_rt::map_keys( + &m.type_env.clone().recursive_type_set.clone(), + )) + .iter() + .cloned() + .fold(acc, |inner: _, ident: i64| { + v1_rt::rc_set_insert( + inner, + intern_str(m.type_env.clone().intern_table.clone(), ident.clone()), + ) + }) + }, + ); + let variant_shapes = + build_enum_variant_shape_sets(modules.clone(), built.type_summaries.clone()); + let vtoe = derive_variant_to_enum(built.type_summaries.clone()); + Rc::new(EmitGraphInfo { + type_summaries: built.type_summaries.clone(), + type_decl_items: built.type_decl_items.clone(), + fn_decl_items: built.fn_decl_items.clone(), + recursive_type_set: all_recursive.clone(), + fielded_variants: variant_shapes.fielded.clone(), + positional_payload_variants: variant_shapes.positional_payload.clone(), + shared_types: v1_rt::rc_empty_set::(), + ownership_index: v1_rt::rc_empty_map::>>(), + movable: v1_rt::rc_empty_set::(), + variant_to_enum: vtoe.clone(), + owned_bindings: v1_rt::rc_empty_set::(), + read_only_params_index: v1_rt::rc_empty_map::>>(), + read_only_params: v1_rt::rc_empty_set::(), + clone_bounded_type_params: v1_rt::rc_empty_map::>>(), + map_key_required_type_names: v1_rt::rc_empty_set::(), + clone_impl_required_type_params: v1_rt::rc_empty_map::>>(), + fn_generic_param_names: Rc::new(vec![]), + fn_type_env: empty_type_env(), + fn_return_type: None, + }) + } +} + +pub fn seed_kernel_intern_table(intern_table: Rc) -> Rc { + { + let intern_table = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold(intern_table.clone(), |t: Rc, name: String| { + intern(t, name.clone()).table.clone() + }); + let intern_table = Rc::new(vec![ + "Optional".to_string(), + "Present".to_string(), + "Absent".to_string(), + "value".to_string(), + "none".to_string(), + ]) + .iter() + .cloned() + .fold(intern_table.clone(), |t: Rc, name: String| { + intern(t, name.clone()).table.clone() + }); + Rc::new(v1_rt::map_keys(&compiler_recursive_types())) + .iter() + .cloned() + .fold(intern_table.clone(), |t: Rc, name: String| { + intern(t, name.clone()).table.clone() + }) + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RealizeState { + pub module_index: Rc>>, + pub variant_surfaces: Rc>>, + pub item_registry: Rc>>, + pub diags_by_name: Rc>>>>, +} + +pub fn typecheck( + graph: Rc, + source_indices: Rc>>, + intern_table: Rc, +) -> Rc { + typecheck_with_census_extra( + graph.clone(), + source_indices.clone(), + intern_table.clone(), + Rc::new(vec![]), + source_indices.clone(), + ) +} + +pub fn typecheck_with_census_extra( + graph: Rc, + source_indices: Rc>>, + intern_table: Rc, + census_fill_modules: Rc>>, + census_si: Rc>>, +) -> Rc { + { + let intern_table = seed_kernel_intern_table(intern_table.clone()); + let resolved_by_name = graph.modules.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, rm: Rc| { + v1_rt::rc_map_insert( + acc, + authored_name_at(source_indices.clone(), rm.module.clone()), + rm.clone(), + ) + }, + ); + let symbol_index = symbol_index_with_qualified_fill( + build_symbol_index_census(graph.modules.clone(), census_si.clone()), + build_symbol_index_qualified_fill(census_fill_modules.clone(), census_si.clone()), + ); + let global_variant_base = build_global_bare_variant_locals( + symbol_index.global_bare.clone(), + source_indices.clone(), + ); + let state = graph.modules.clone().iter().cloned().fold( + Rc::new(RealizeState { + module_index: v1_rt::rc_empty_map::>(), + variant_surfaces: v1_rt::rc_empty_map::>(), + item_registry: v1_rt::rc_empty_map::>(), + diags_by_name: v1_rt::rc_empty_map::>>>(), + }), + |st: Rc, rm: Rc| { + realize_module( + authored_name_at(source_indices.clone(), rm.module.clone()), + resolved_by_name.clone(), + st, + source_indices.clone(), + intern_table.clone(), + symbol_index.clone(), + global_variant_base.clone(), + ) + }, + ); + let modules = Rc::new({ + let mut __result = Vec::new(); + for rm in graph.modules.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get( + &state.module_index.clone(), + authored_name_at(source_indices.clone(), rm.module.clone()), + ) { + Some(typed) => Rc::new(vec![typed.clone()]), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }); + let diag_chunks = Rc::new({ + let mut __result = Vec::new(); + for rm in graph.modules.clone().iter().cloned() { + __result.push( + match v1_rt::map_get( + &state.diags_by_name.clone(), + authored_name_at(source_indices.clone(), rm.module.clone()), + ) { + Some(d) => d.clone(), + None => Rc::new(vec![]), + }, + ); + } + __result + }); + let expanded_registry = + expand_transitive_services(modules.clone(), state.item_registry.clone(), 5); + Rc::new(TypedGraph { + modules: modules.clone(), + item_registry: expanded_registry.clone(), + diagnostics: Rc::new({ + let mut __result = Vec::new(); + for c in diag_chunks.clone().iter().cloned() { + __result.extend((*c.clone()).iter().cloned()); + } + __result + }), + }) + } +} + +pub fn realize_module( + name: String, + resolved_by_name: Rc>>, + state: Rc, + source_indices: Rc>>, + intern_table: Rc, + symbol_index: Rc, + global_variant_base: Rc>>, +) -> Rc { + stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { + match v1_rt::map_get(&state.module_index.clone(), name.clone()) { + Some(_) => state, + None => match v1_rt::map_get(&resolved_by_name, name.clone()) { + None => state, + Some(resolved) => { + let dep_state = resolved.resolved_imports.clone().iter().cloned().fold( + state, + |st: Rc, imp: Rc| { + realize_module( + imp.module_path.clone(), + resolved_by_name.clone(), + st, + source_indices.clone(), + intern_table.clone(), + symbol_index.clone(), + global_variant_base.clone(), + ) + }, + ); + let parent_result = collect_parent_envs( + resolved.clone(), + dep_state.module_index.clone(), + source_indices.clone(), + ); + let tc_result = typecheck_module( + resolved.clone(), + dep_state.module_index.clone(), + dep_state.variant_surfaces.clone(), + source_indices.clone(), + intern_table.clone(), + symbol_index.clone(), + global_variant_base.clone(), + ); + let typed = tc_result.typed.clone(); + let typed_path = authored_name_at(source_indices.clone(), typed.module.clone()); + Rc::new(RealizeState { + module_index: v1_rt::rc_map_insert( + dep_state.module_index.clone(), + typed_path.clone(), + typed.clone(), + ), + variant_surfaces: v1_rt::rc_map_insert( + dep_state.variant_surfaces.clone(), + typed_path.clone(), + build_variant_export_surface( + typed.clone(), + dep_state.variant_surfaces.clone(), + source_indices.clone(), + ), + ), + item_registry: v1_rt::rc_map_merge( + dep_state.item_registry.clone(), + typed.item_registry.clone(), + ), + diags_by_name: v1_rt::rc_map_insert( + dep_state.diags_by_name.clone(), + typed_path.clone(), + v1_rt::concat( + parent_result.diagnostics.clone(), + tc_result.diagnostics.clone(), + ), + ), + }) + } + }, + } + }) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct StrBindingsRewireAccum { + pub str_bindings: Rc>>, + pub ancestry_str_bindings: Rc>>, +} + +pub fn import_module_path_at( + imp: Rc, + source_indices: Rc>>, +) -> String { + authored_name_at(source_indices.clone(), imp.clone()) +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ExportIndexModuleAccum { + pub index: Rc>>, + pub seen_names: Rc>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ExportedTypeRelationBuild { + pub by_name: Rc>>, + pub by_module: Rc>>>, +} + +pub fn export_index_canonical_is_the_fold_element_note() -> String { + thread_local! { + static CACHED: String = { + "§6 bare-minimum cost, same receipt as module_exported_type_names_cost_note. The export-index module walk's canonical binding was `filter(bindings |> map_values, b => b.name == name) |> first` — a rescan of the WHOLE binding map (with a fresh Vec allocation) once per distinct name, i.e. O(|bindings|^2) per module per closure assembly. It is dead work by construction: the enclosing fold walks THAT SAME map_values sequence in order, and seen_names skips every repeat, so the first element whose name matches is always the fold's own current element. `canonical = binding` is therefore the identical value, not an approximation of it — the order both expressions read is one traversal of one map value, so the equality does not depend on map_values being stable ACROSS runs (§5941 determinism), only on the two reads of the same value agreeing, which the rewrite removes the need for entirely.".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn export_index_module_state( + acc: Rc>>, + m: Rc, +) -> Rc { + Rc::new(v1_rt::map_values(&m.type_env.clone().bindings.clone())) + .iter() + .cloned() + .fold( + Rc::new(ExportIndexModuleAccum { + index: acc.clone(), + seen_names: v1_rt::rc_empty_map::(), + }), + |state: Rc, binding: Rc| { + let name = binding.name.clone(); + if v1_rt::map_contains_key(&state.seen_names.clone(), name.clone()) { + state.clone() + } else { + { + let canonical = binding.clone(); + let seen_names = + v1_rt::rc_map_insert(state.seen_names.clone(), name.clone(), true); + let index = match v1_rt::map_get(&state.index.clone(), name.clone()) { + None => v1_rt::rc_map_insert( + state.index.clone(), + name.clone(), + Rc::new(TypeNameExportFacts { + exporter_count: 1, + canonical_binding: Some(canonical.clone()), + }), + ), + Some(facts) => v1_rt::rc_map_insert( + state.index.clone(), + name.clone(), + Rc::new(TypeNameExportFacts { + exporter_count: (facts.exporter_count.clone() + 1), + canonical_binding: Some(canonical.clone()), + }), + ), + }; + Rc::new(ExportIndexModuleAccum { + index: index.clone(), + seen_names: seen_names.clone(), + }) + } + } + }, + ) +} + +pub fn export_index_merge_module_both( + acc: Rc, + m: Rc, + source_indices: Rc>>, +) -> Rc { + { + let state = export_index_module_state(acc.by_name.clone(), m.clone()); + Rc::new(ExportedTypeRelationBuild { + by_name: state.index.clone(), + by_module: v1_rt::rc_map_insert( + acc.by_module.clone(), + authored_name_at(source_indices.clone(), m.module.clone()), + state.seen_names.clone(), + ), + }) + } +} + +pub fn build_export_indexes( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc { + modules.clone().iter().cloned().fold( + Rc::new(ExportedTypeRelationBuild { + by_name: v1_rt::rc_empty_map::>(), + by_module: v1_rt::rc_empty_map::>>(), + }), + |acc: Rc, m: Rc| { + export_index_merge_module_both(acc, m.clone(), source_indices.clone()) + }, + ) +} + +pub fn module_exported_type_names_cost_note() -> String { + thread_local! { + static CACHED: String = { + "Cost shape (§6 bare-minimum cost, floor batch-3 receipt 2026-07-25): the type names a module exports is ONE derived fact — a set — and both consumers in rewire_type_env_import_str_binding_identity read it. Before this row it existed twice: the caller's per-module `local_names` fold, and `module_exports_type_name`, a LINEAR SCAN (map_values allocates a Vec of every binding, then filters by name) re-run once per (consumer module x inherited key x direct import). Measured on 79 discovery entries: that pass alone was 191.1s of a 331.9s resolve wall (99% of all rewire time, 2.4s/entry) while the other two rewire passes together cost 1.8s. Hoisting the set per module and testing membership made the per-name exporter count O(direct imports) instead of O(direct imports x |parent bindings|), with no change to the predicate it computes. That per-name scan is itself now gone: direct_import_exporter_counts accumulates the whole relation in one traversal of the same sets and rewire_canonical_rewrites reads it by key, so the pass no longer pays a scan per candidate name at all. The caller reads its own row out of the SAME index rather than re-folding it (review 42566) — the Absent arm computes the true value from this one authority, so it is a structurally-unreachable fallback that is still honest, never a fabricated default (DESIGN section 5).".to_string() + }; + } + CACHED.with(|c: &String| c.clone()) +} + +pub fn module_exported_type_names(m: Rc) -> Rc> { + Rc::new(v1_rt::map_values(&m.type_env.clone().bindings.clone())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, b: Rc| { + v1_rt::rc_map_insert(acc, b.name.clone(), true) + }, + ) +} + +pub fn direct_import_export_name_sets( + m: Rc, + export_name_index: Rc>>>, + source_indices: Rc>>, +) -> Rc>>> { + Rc::new({ + let mut __result = Vec::new(); + for imp in module_imports(m.module.clone()).iter().cloned() { + __result.extend( + (*{ + let path = import_module_path_at(imp.clone(), source_indices.clone()); + match v1_rt::map_get(&export_name_index, path.clone()) { + Some(names) => Rc::new(vec![names.clone()]), + None => Rc::new(vec![]), + } + }) + .iter() + .cloned(), + ); + } + __result + }) +} + +pub fn direct_import_exporter_counts( + import_export_names: Rc>>>, +) -> Rc> { + import_export_names.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, names: Rc>| { + Rc::new(v1_rt::map_keys(&names)).iter().cloned().fold( + acc, + |inner: Rc>, name: String| match v1_rt::map_get( + &inner, + name.clone(), + ) { + Some(seen) => { + v1_rt::rc_map_insert(inner.clone(), name.clone(), (seen.clone() + 1)) + } + None => v1_rt::rc_map_insert(inner.clone(), name.clone(), 1), + }, + ) + }, + ) +} + +pub fn direct_import_exporter_count_of( + exporter_counts: Rc>, + name: String, +) -> i64 { + match v1_rt::map_get(&exporter_counts, name.clone()) { + Some(n) => n.clone(), + None => 0, + } +} + +pub fn rewire_canonical_rewrites( + type_name_index: Rc>>, + exporter_counts: Rc>, + local_names: Rc>, + inherited_keys: Rc>, +) -> Rc>> { + inherited_keys.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| match v1_rt::map_get( + &type_name_index, + name.clone(), + ) { + None => acc.clone(), + Some(facts) => { + if ((v1_rt::map_contains_key(&local_names, name.clone()) + || (direct_import_exporter_count_of(exporter_counts.clone(), name.clone()) + > 1)) + || (facts.exporter_count.clone() > 1)) + { + acc.clone() + } else { + match facts.canonical_binding.clone() { + Some(canonical) => { + v1_rt::rc_map_insert(acc.clone(), name.clone(), canonical.clone()) + } + None => acc.clone(), + } + } + } + }, + ) +} + +pub fn rewire_str_binding_overlay( + str_bindings: Rc>>, + rewrites: Rc>>, +) -> Rc>> { + Rc::new(v1_rt::map_keys(&rewrites)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| match v1_rt::map_get( + &str_bindings, + name.clone(), + ) { + Some(_) => match v1_rt::map_get(&rewrites, name.clone()) { + Some(canonical) => { + v1_rt::rc_map_insert(acc.clone(), name.clone(), canonical.clone()) + } + None => acc.clone(), + }, + None => acc.clone(), + }, + ) +} + +pub fn rewire_type_env_import_str_binding_identity( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc>> { + { + let export_indexes = build_export_indexes(modules.clone(), source_indices.clone()); + let type_name_index = export_indexes.by_name.clone(); + let export_name_index = export_indexes.by_module.clone(); + Rc::new({ + let mut __result = Vec::new(); + for m in modules.clone().iter().cloned() { + __result.push({ + let local_names = match v1_rt::map_get( + &export_name_index, + authored_name_at(source_indices.clone(), m.module.clone()), + ) { + Some(names) => names.clone(), + None => module_exported_type_names(m.clone()), + }; + let import_export_names = direct_import_export_name_sets( + m.clone(), + export_name_index.clone(), + source_indices.clone(), + ); + let exporter_counts = + direct_import_exporter_counts(import_export_names.clone()); + let ancestry_keys = Rc::new(v1_rt::map_keys( + &m.type_env.clone().ancestry_str_bindings.clone(), + )); + let str_keys = + Rc::new(v1_rt::map_keys(&m.type_env.clone().str_bindings.clone())); + let inherited_keys = v1_rt::concat(ancestry_keys.clone(), str_keys.clone()); + let rewrites = rewire_canonical_rewrites( + type_name_index.clone(), + exporter_counts.clone(), + local_names.clone(), + inherited_keys.clone(), + ); + let rewired = Rc::new(StrBindingsRewireAccum { + str_bindings: v1_rt::rc_map_merge( + m.type_env.clone().str_bindings.clone(), + rewire_str_binding_overlay( + m.type_env.clone().str_bindings.clone(), + rewrites.clone(), + ), + ), + ancestry_str_bindings: v1_rt::rc_map_merge( + m.type_env.clone().ancestry_str_bindings.clone(), + rewrites.clone(), + ), + }); + Rc::new(TypedModule { + module: m.module.clone(), + items: m.items.clone(), + type_env: Rc::new(TypeEnv { + module_path: m.type_env.clone().module_path.clone(), + bindings: m.type_env.clone().bindings.clone(), + str_bindings: rewired.str_bindings.clone(), + ancestry_str_bindings: rewired.ancestry_str_bindings.clone(), + parents: m.type_env.clone().parents.clone(), + recursive_types: m.type_env.clone().recursive_types.clone(), + recursive_type_set: m.type_env.clone().recursive_type_set.clone(), + inductive_fields: m.type_env.clone().inductive_fields.clone(), + source_indices: m.type_env.clone().source_indices.clone(), + intern_table: m.type_env.clone().intern_table.clone(), + source_visible_names: m.type_env.clone().source_visible_names.clone(), + symbol_index: m.type_env.clone().symbol_index.clone(), + }), + type_env_cache: m.type_env_cache.clone(), + interface: m.interface.clone(), + func_env: m.func_env.clone(), + item_registry: m.item_registry.clone(), + occurrence_transport: m.occurrence_transport.clone(), + }) + }); + } + __result + }) + } +} + +pub fn compiler_kernel_type_env( + source_indices: Rc>>, + intern_table: Rc, +) -> Rc { + { + let kernel_bindings_base = Rc::new(v1_rt::map_keys(&kernel_type_set())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + Rc::new(TypeBinding { + name: name.clone(), + resolved: Rc::new(Node { + name: name.clone(), + span: kernel_span(name.clone()), + ident_span: Some(kernel_span(name.clone())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ) + }, + ); + let unit_span = kernel_span("Unit".to_string()); + let kernel_bindings = v1_rt::rc_map_insert( + kernel_bindings_base.clone(), + intern(intern_table.clone(), "Unit".to_string()).id.clone(), + Rc::new(TypeBinding { + name: "Unit".to_string(), + resolved: Rc::new(Node { + name: "Unit".to_string(), + span: unit_span.clone(), + ident_span: Some(unit_span.clone()), + children: Rc::new(vec![]), + connective: Connective::Conj, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ); + let present_value_field = Rc::new(Node { + name: "value".to_string(), + span: kernel_span("value".to_string()), + ident_span: Some(kernel_span("value".to_string())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: Some(Rc::new(InferredNode::TypeVariable { + id: "present_value".to_string(), + })), + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let present_variant = Rc::new(Node { + name: "Present".to_string(), + span: kernel_span("Present".to_string()), + ident_span: Some(kernel_span("Present".to_string())), + children: Rc::new(vec![present_value_field.clone()]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let absent_variant = Rc::new(Node { + name: "Absent".to_string(), + span: kernel_span("Absent".to_string()), + ident_span: Some(kernel_span("Absent".to_string())), + children: Rc::new(vec![]), + connective: Connective::NoConnective, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let kernel_optional = Rc::new(Node { + name: "Optional".to_string(), + span: kernel_span("Optional".to_string()), + ident_span: Some(kernel_span("Optional".to_string())), + children: Rc::new(vec![present_variant.clone(), absent_variant.clone()]), + connective: Connective::Disj, + params: Rc::new(vec![]), + inferred: None, + return_cardinality: Cardinality::Required, + uses: Rc::new(vec![]), + body: None, + transport: None, + properties: Rc::new(vec![]), + type_annotation: None, + is_self_recursive: false, + has_non_tail_self_call: false, + match_pattern: None, + expr_data: Rc::new(ExprData::NoExprData), + ident: None, + }); + let kernel_bindings = v1_rt::rc_map_insert( + kernel_bindings.clone(), + intern(intern_table.clone(), "Optional".to_string()) + .id + .clone(), + Rc::new(TypeBinding { + name: "Optional".to_string(), + resolved: kernel_optional.clone(), + provenance: Rc::new(SubValueRelation::SubValueUnknown), + }), + ); + let node_fields = inductive_fields_list_to_map(compiler_inductive_fields()); + let kernel_recursive_types = Rc::new({ + let mut __result = Vec::new(); + for name in Rc::new(v1_rt::map_keys(&compiler_recursive_types())) + .iter() + .cloned() + { + __result.push(intern(intern_table.clone(), name.clone()).id.clone()); + } + __result + }); + let kernel_recursive_type_set = Rc::new(v1_rt::map_keys(&compiler_recursive_types())) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, name: String| { + v1_rt::rc_map_insert( + acc, + intern(intern_table.clone(), name.clone()).id.clone(), + true, + ) + }, + ); + Rc::new(TypeEnv { + module_path: "".to_string(), + bindings: kernel_bindings.clone(), + str_bindings: str_bindings_from_bindings(kernel_bindings.clone()), + ancestry_str_bindings: v1_rt::rc_empty_map::>(), + parents: Rc::new(vec![]), + recursive_types: kernel_recursive_types.clone(), + recursive_type_set: kernel_recursive_type_set.clone(), + inductive_fields: node_fields.clone(), + source_indices: source_indices.clone(), + intern_table: intern_table.clone(), + source_visible_names: v1_rt::rc_empty_map::(), + symbol_index: empty_symbol_index(), + }) + } +} + +pub fn rewire_type_env_parent_links( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc>> { + { + let index = modules.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, m: Rc| { + v1_rt::rc_map_insert( + acc, + authored_name_at(source_indices.clone(), m.module.clone()), + m.clone(), + ) + }, + ); + let shared_kernel = match Rc::new({ + let mut __result = Vec::new(); + for m in modules.clone().iter().cloned() { + __result.extend( + (*match m.type_env.clone().parents.clone().last().cloned() { + Some(kernel) => { + if v1_rt::map_is_empty(&kernel.bindings.clone()) { + Rc::new(vec![]) + } else { + Rc::new(vec![kernel.clone()]) + } + } + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }) + .first() + .cloned() + { + Some(kernel) => kernel.clone(), + None => match modules.clone().first().cloned() { + Some(m) => compiler_kernel_type_env( + source_indices.clone(), + m.type_env.clone().intern_table.clone(), + ), + None => compiler_kernel_type_env(source_indices.clone(), empty_intern_table()), + }, + }; + Rc::new({ + let mut __result = Vec::new(); + for m in modules.clone().iter().cloned() { + __result.push({ + let import_parents = Rc::new({ + let mut __result = Vec::new(); + for imp in module_imports(m.module.clone()).iter().cloned() { + __result.extend( + (*{ + let path = + import_module_path_at(imp.clone(), source_indices.clone()); + match v1_rt::map_get(&index, path.clone()) { + Some(parent) => Rc::new(vec![interface_env_for_import( + path.clone(), + parent.type_env.clone(), + )]), + None => Rc::new(vec![]), + } + }) + .iter() + .cloned(), + ); + } + __result + }); + Rc::new(TypedModule { + module: m.module.clone(), + items: m.items.clone(), + type_env: Rc::new(TypeEnv { + module_path: m.type_env.clone().module_path.clone(), + bindings: m.type_env.clone().bindings.clone(), + str_bindings: m.type_env.clone().str_bindings.clone(), + ancestry_str_bindings: m.type_env.clone().ancestry_str_bindings.clone(), + parents: v1_rt::concat( + import_parents.clone(), + Rc::new(vec![shared_kernel.clone()]), + ), + recursive_types: m.type_env.clone().recursive_types.clone(), + recursive_type_set: m.type_env.clone().recursive_type_set.clone(), + inductive_fields: m.type_env.clone().inductive_fields.clone(), + source_indices: m.type_env.clone().source_indices.clone(), + intern_table: m.type_env.clone().intern_table.clone(), + source_visible_names: m.type_env.clone().source_visible_names.clone(), + symbol_index: m.type_env.clone().symbol_index.clone(), + }), + type_env_cache: m.type_env_cache.clone(), + interface: m.interface.clone(), + func_env: m.func_env.clone(), + item_registry: m.item_registry.clone(), + occurrence_transport: m.occurrence_transport.clone(), + }) + }); + } + __result + }) + } +} + +pub fn rewire_func_env_parent_links( + modules: Rc>>, + source_indices: Rc>>, +) -> Rc>> { + { + let index = modules.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, m: Rc| { + v1_rt::rc_map_insert( + acc, + authored_name_at(source_indices.clone(), m.module.clone()), + m.clone(), + ) + }, + ); + Rc::new({ + let mut __result = Vec::new(); + for m in modules.clone().iter().cloned() { + __result.push({ + let parents = Rc::new({ + let mut __result = Vec::new(); + for imp in module_imports(m.module.clone()).iter().cloned() { + __result.extend( + (*{ + let path = + import_module_path_at(imp.clone(), source_indices.clone()); + match v1_rt::map_get(&index, path.clone()) { + Some(parent) => Rc::new(vec![parent.func_env.clone()]), + None => Rc::new(vec![]), + } + }) + .iter() + .cloned(), + ); + } + __result + }); + Rc::new(TypedModule { + module: m.module.clone(), + items: m.items.clone(), + type_env: m.type_env.clone(), + type_env_cache: m.type_env_cache.clone(), + interface: m.interface.clone(), + func_env: Rc::new(ResolvedFuncEnv { + name: m.func_env.clone().name.clone(), + local: m.func_env.clone().local.clone(), + parents: flatten_parent_envs(parents.clone()), + }), + item_registry: m.item_registry.clone(), + occurrence_transport: m.occurrence_transport.clone(), + }) + }); + } + __result + }) + } +} + +pub fn reconcile( + graph: Rc, + source_indices: Rc>>, + intern_table: Rc, +) -> Rc { + reconcile_with_census_extra( + graph.clone(), + source_indices.clone(), + intern_table.clone(), + Rc::new(vec![]), + source_indices.clone(), + ) +} + +pub fn reconcile_with_census_extra( + graph: Rc, + source_indices: Rc>>, + intern_table: Rc, + census_fill_modules: Rc>>, + census_si: Rc>>, +) -> Rc { + { + let typed = typecheck_with_census_extra( + graph.clone(), + source_indices.clone(), + intern_table.clone(), + census_fill_modules.clone(), + census_si.clone(), + ); + let modules = rewire_type_env_parent_links(typed.modules.clone(), source_indices.clone()); + let modules = + rewire_type_env_import_str_binding_identity(modules.clone(), source_indices.clone()); + let modules = rewire_func_env_parent_links(modules.clone(), source_indices.clone()); + let emit_info = build_emit_graph_info(modules.clone()); + Rc::new(ResolvedGraph { + modules: modules.clone(), + item_registry: typed.item_registry.clone(), + diagnostics: typed.diagnostics.clone(), + emit_graph_info: emit_info.clone(), + }) + } +} diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index ac7a097192b..257025e4802 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -1711,6 +1711,15 @@ pub fn record_lit_fields_from_expected( } } +pub fn field_declared_type_node(sf: Rc) -> Rc { + match sf.inferred.as_deref() { + Some(InferredNode::Resolved { node: rt }) => { + preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + } + _ => field_node_type_expr(sf.clone()), + } +} + pub fn record_lit_instantiated_fields( type_name: Option, expected: Option>, @@ -1758,7 +1767,9 @@ match exp.children.clone().iter().cloned().skip(pair.0.clone() as usize).next() inferred: Some(Rc::new( InferredNode::Resolved { node: substitute_generics( - field_node_type_expr(sf.clone()), + field_declared_type_node( + sf.clone(), + ), subst.clone(), scope .type_env @@ -9861,15 +9872,7 @@ pub fn infer_record_lit_structural( .first() .cloned() { - Some(sf) => { - let ft = match sf.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => { - preserve_outer_optional_cardinality(sf.clone(), rt.clone()) - } - _ => field_node_type_expr(sf.clone()), - }; - Some(ft.clone()) - } + Some(sf) => Some(field_declared_type_node(sf.clone())), None => None, }; let field_expected = match field_declared_type.clone() { From 40401707e5465f3d8fc38ffe84998efc0faa3dae Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 18:22:07 +0000 Subject: [PATCH 09/17] Drop stray backup file --- .patched_infer_backup.rs | 21414 ------------------------------------- 1 file changed, 21414 deletions(-) delete mode 100644 .patched_infer_backup.rs diff --git a/.patched_infer_backup.rs b/.patched_infer_backup.rs deleted file mode 100644 index e05b724cef1..00000000000 --- a/.patched_infer_backup.rs +++ /dev/null @@ -1,21414 +0,0 @@ -// Generated by v1 compiler -- do not edit. -// Source module: v1.compiler.infer - -use self::DescentSizeExpr::*; -pub use crate::extdeps_container_oci_digest::{ - oci_other_digest_algorithm, oci_other_digest_encoded, -}; -pub use crate::std_algebra::AlgebraFieldTemplate; -use crate::std_algebra::CollectionSizeEffect::ShrinkEffect; -pub use crate::std_algebra::{CollectionSizeEffect, FreeMonoid}; -pub use crate::std_coercion::{dag_can_cast, is_dag_cast_domain_type}; -pub use crate::std_computation::ShrinkFactor; -use crate::std_computation::ShrinkFactor::{ConstantShrink, ProportionalShrink, UnitShrink}; -use crate::std_content_hash::ContentHash::*; -pub use crate::std_content_hash::{ - content_hash_atom, content_hash_combine_structural, content_hash_tagged_structural, - content_hash_validate_lower_hex_length, -}; -pub use crate::std_content_hash::{ContentHash, Fnv1a64Structural}; -pub use crate::std_dissolution::DissolutionCondition; -use crate::std_dissolution::DissolutionCondition::*; -pub use crate::std_dissolution::{dissolution_description, unbound_dissolution}; -use crate::std_induction::RecursionShape::{ - DirectRecursion, ListRecursion, MapValueRecursion, OptionalRecursion, SetRecursion, -}; -use crate::std_induction::SubValueRelation::{ - ArithmeticDescent, IteratedSubValue, MixedTop, NonIncreasingValue, PreservedValue, - StrictAxisErased, StrictSubValue, SubValueUnknown, -}; -pub use crate::std_induction::{ - compose_sub_value, compose_sub_value_relations, join_sub_value, meet_sub_value, - sub_value_to_evidence, -}; -pub use crate::std_induction::{InductiveField, RecursionShape, SubValueRelation}; -use crate::std_interface_summary::ExportKind::{ExportData, ExportFn, ExportService, ExportType}; -pub use crate::std_interface_summary::{interface_summary_rollup, signature_contract}; -pub use crate::std_interface_summary::{ExportEntry, ExportKind, InterfaceSummary}; -pub use crate::std_node::{compiler_inductive_fields, compiler_recursive_types}; -pub use crate::std_occurrence_identity::OccurrenceId; -use crate::std_syntax::BinOp::Add; -use crate::std_syntax::BinOp::{And, Div, Eq, Ge, Gt, Le, Lt, Mod, Mul, Ne, NullCoalesce, Or, Sub}; -use crate::std_syntax::LiteralValue::LitStr; -use crate::std_syntax::LiteralValue::{LitBool, LitFloat, LitInt, LitNull}; -pub use crate::std_syntax::{BinOp, LiteralValue}; -pub use crate::std_termination::PositiveDescentAmount; -use crate::std_termination::PositiveDescentAmount::OneStep; -pub use crate::std_termination::{ - positive_descent_amount_from_positive_int, proportional_divisor_from_int_at_least_two, -}; -pub use crate::std_types::{container_param_name, is_kernel_type, kernel_type_set}; -pub use crate::std_types::{NonEmptyStr, SourceSpan}; -pub use crate::v1_compiler_infer_access::AccessCheckResultNode; -pub use crate::v1_compiler_infer_access::{check_index_access_node, check_slice_access_node}; -pub use crate::v1_compiler_infer_cycle::detect_type_cycles_kahn; -use crate::v1_compiler_infer_emit_info::TypeRepr::{EnumRepr, StructRepr}; -pub use crate::v1_compiler_infer_emit_info::{ - add_emit_item_summary, build_enum_field_summaries, build_struct_field_summaries, - close_fn_fields, derive_variant_to_enum, empty_emit_graph_info, empty_type_env, - lookup_emit_type_summary, -}; -pub use crate::v1_compiler_infer_emit_info::{ - EmitGraphInfo, EmitInfoBuildState, TypeRepr, TypeSummary, -}; -use crate::v1_compiler_infer_env::GlobalBareLookupState::{ - GlobalBareAmbiguousBinding, GlobalBareUniqueBinding, -}; -pub use crate::v1_compiler_infer_env::{ - bare_name_miss_diagnostic, binding_declares_name, empty_symbol_index, empty_type_env_cache, - env_with_type_variable_bindings, global_bare_is_ambiguous, - global_bare_strict_ambiguity_candidates, inductive_fields_for, inductive_fields_list_to_map, - is_recursive_type, is_recursive_type_by_name, listed_import_required_bare_call_blocked, - lookup_binding_by_name, lookup_type, lookup_type_by_name, lookup_type_for, - merge_inductive_fields, merge_type_env_cache, merge_type_env_cache_guarded, node_with_children, - node_with_inferred, put_inductive_field, put_inductive_field_cross, qualified_all_but_last, - qualify_borrowed_inferred, qualify_borrowed_type_names, qualify_decl_reference_positions, - str_bindings_from_bindings, symbol_index_insert, symbol_index_insert_decl, - symbol_index_insert_service, symbol_index_lookup, -}; -pub use crate::v1_compiler_infer_env::{ - GlobalBareCandidate, GlobalBareLookupState, GuardedTypeEnvCacheMerge, ServiceCensusEntry, - SymbolIndex, TypeBinding, TypeEnv, TypeEnvCache, TypeEnvCacheMergeConflict, -}; -use crate::v1_compiler_infer_items::ItemKind::{ - DataItem, FnItem, FuncItem, OtherItem, ServiceItem, TypeItem, -}; -pub use crate::v1_compiler_infer_items::{inferred_to_outputs, item_kind}; -pub use crate::v1_compiler_infer_items::{ - ItemInfo, ItemKind, ModuleInterface, ResolvedGraph, TypedGraph, TypedModule, -}; -use crate::v1_compiler_infer_lookup::ConstructorDeclarationLookup::{ - AdmissionBearingDeclarationUnavailable, ExactConstructorDeclaration, - NotAdmissionBearingReference, -}; -use crate::v1_compiler_infer_lookup::DeclarationLookupFailure::DeclarationNotIndexedAtQualifiedName; -use crate::v1_compiler_infer_lookup::DeclaredArgContract::{ - ContractKnown, ContractUnavailable, MethodUnresolved, -}; -pub use crate::v1_compiler_infer_lookup::{ - declared_arg_types_for_method, field_summary_for_type, func_decl_binding_for_call, - func_sig_if_resolved, global_bare_callable_node, lookup_coproduct_common_field_node, - lookup_field_type_node, lookup_func_sig, lookup_in_scope, lookup_structural_method, - map_key_type_in_env, map_value_type_in_env, product_field_result_type, - resolve_known_method_node, resolve_method_receiver_type, resolve_scrutinee_type_node, - set_element_type_in_env, -}; -pub use crate::v1_compiler_infer_lookup::{ - ConstructorDeclarationLookup, DeclarationLookupFailure, DeclaredArgContract, - ExactDeclarationIdentity, KnownMethodResolution, -}; -pub use crate::v1_compiler_infer_method::{ - builtin_kernel_seed_diagnostics, infer_builtin_call_type, resolve_builtin_call_type, -}; -use crate::v1_compiler_infer_patterns::PatternSubject::*; -pub use crate::v1_compiler_infer_patterns::{ - check_match_exhaustiveness, expand_scrut_type_for_variant_lookup, lookup_field_in_variant, - lookup_result_subject, lookup_variant_in_type, pattern_binding_type, - pattern_subject_from_inferred, pattern_subject_from_node, -}; -pub use crate::v1_compiler_infer_patterns::{NodeLookupResult, PatternSubject}; -pub use crate::v1_compiler_infer_resolve::{ - fn_type_param_names, is_user_generic_use_site, peel_nominal_alias_identity, - preserve_nominal_brand_on_resolve, resolve_generic_use_decl, resolve_item_types, resolve_node, -}; -pub use crate::v1_compiler_infer_resolve::{ItemResolveResult, NodeResolveResult}; -pub use crate::v1_compiler_infer_service::{ - check_service_field_access_node, check_service_method_call_node, collect_called_func_names, - collect_typed_service_calls, expand_transitive_services, extract_typed_service_name, - is_typed_service_call_receiver, service_op_entry, -}; -pub use crate::v1_compiler_infer_service::{OpEntry, ServiceMethodResult, UniqueAccum}; -use crate::v1_compiler_infer_sigs::FuncSigLookup::{ - FuncSigAmbiguous, FuncSigResolved, FuncSigUnresolved, -}; -pub use crate::v1_compiler_infer_sigs::{flatten_parent_envs, resolve_func_sigs}; -pub use crate::v1_compiler_infer_sigs::{ - FuncSigLookup, ResolveFuncSigsResult, ResolvedFuncEnv, ResolvedFuncSig, -}; -pub use crate::v1_compiler_infer_types::KernelTypeBuild; -pub use crate::v1_compiler_infer_types::{ - bare_map_node, bare_set_node, callable_inferred, callable_return_type, child_type_node, - emit_map_has, extract_optional_inner_node, for_each_element_type_node, infer_binop_type_node, - infer_literal_node, is_declared_container_alias_spelling, is_fully_resolved, - is_type_expr_annotation, kernel_profile_lookup, make_callable_type, make_container_type, - method_receiver_element_node, node_is_collection, node_is_element_collection, - node_is_keyed_collection, node_is_set_collection, node_type_compatible, node_type_deps, - node_type_equals, node_type_shape, nominal_type_ref, normalize_access_type_node, - prefer_specific_type, resolve_type_variables_from_template, resolved_type, - structural_carrier_template_name, template_return_has_variables, - template_return_is_receiver_self, -}; -pub use crate::v1_compiler_resolve::{ModuleGraph, ResolvedImport, ResolvedModule}; -use crate::v1_rt; -use crate::v1_rt::{VecCompat, VecJoin}; -use crate::v1_std_core::CallSemantics::{ - FunctionValueCallSemantics, LookupCallSemantics, PlainCallSemantics, -}; -use crate::v1_std_core::Cardinality::{CardOptional, Required}; -use crate::v1_std_core::CompilerDiagnostic::{ - AmbiguousReference, BareNoneNotAdmittedByFieldType, CallArgumentDuplicate, - CallArgumentNameUnknown, CallNamedArgOnFunctionValue, CallPositionalDeficit, - CallPositionalSurplus, ConstructorCallAdmissionRefused, FieldNotFound, - FrontierOccurrenceBudgetExceeded, InternalError, MethodExistenceFrontierAdmitted, - MethodExistenceUndecided, MethodNotFound, MissingField, OptionalCastNotEliminated, - ReceiverTypeUnestablished, SoleConstructorViolation, TypeMismatch, UnresolvedType, - VariantCollision, -}; -use crate::v1_std_core::Connective::{Arrow, Conj, Disj, NoConnective}; -use crate::v1_std_core::ExprData::{ - ExprBinOp, ExprBlock, ExprCall, ExprCast, ExprError, ExprFieldAccess, ExprForEach, ExprIf, - ExprIndex, ExprLambda, ExprLet, ExprListLit, ExprLiteral, ExprMatch, ExprMethodCall, - ExprRecordLit, ExprReturn, ExprSlice, ExprStringInterp, ExprUnaryOp, ExprVar, NoExprData, -}; -use crate::v1_std_core::ExprErrorKind::{ - CensusHeadsBodyStripped, InternalExprError, ParseRecoveryError, SemanticExprError, -}; -use crate::v1_std_core::FieldAccessStyle::{ - EnumAccessor, OptionalUnwrap, StoredField, TupleFirst, TupleSecond, -}; -use crate::v1_std_core::FieldValueShape::{OptionalValue, PlainValue}; -use crate::v1_std_core::InferredNode::{CompilerError, Resolved, TypeVariable}; -use crate::v1_std_core::MatchPattern::{Bind, VariantPattern, Wildcard}; -use crate::v1_std_core::MethodSemantics::{ - AlgebraMethodSemantics, PlainMethodSemantics, ServiceMethodSemantics, -}; -use crate::v1_std_core::StringPart::{Interpolation, Text}; -use crate::v1_std_core::UnaryOpKind::{Neg, Not}; -use crate::v1_std_core::VarBindingKind::{ - FunctionValueBinding, LocalValueBinding, MatchBoundBinding, VariantValueBinding, -}; -pub use crate::v1_std_core::{ - arg_name_at, arg_value, arm_body, arm_guard, arm_pattern, authored_name_at, binop_left, - binop_right, bool_type, build_newline_index, cast_expr, cast_target, container_expected_arity, - decl_ref_coords_label, default_ident_span, diagnostic_frontier_occurrence_key, - diagnostic_to_span, empty_intern_table, error_type, expr_call_func_at, - expr_has_non_tail_self_call, expr_has_self_call, expr_literal_int_optional, - expr_literal_string_optional, expr_method_name_at, expr_var_name_at, field_access_base, - field_access_field_at, field_access_spine, field_binding_name_at, field_binding_pattern, - field_init_node_name_at, field_init_node_value, field_node_name_at, field_node_type_expr, - find_child_named, find_property_string, float_type, fn_admit_callers, foreach_body, - foreach_collection, foreach_variable_at, generic_param_name_at, has_child_named, has_inferred, - if_condition, if_else_branch, if_then_branch, import_is_all, import_specific_names_at, - index_base, index_expr, int_type, intern, intern_str, is_child_accessor_in_model, - is_compiler_error, is_container_type, is_error_diagnostic, is_property_contraction, - is_tree_size_reducing, lambda_body, lambda_param_names_at, let_binding_name_at, let_body, - let_value, local_transport_node, make_arg_node, make_arm_node, make_error_node, - make_expr_error_node, make_expr_node, make_field_binding_node, make_field_init_node, - make_interp_part_node, make_named_expr_node, make_param_node, make_text_part_node, - make_transport_node, map_children, match_arm_nodes, match_scrutinee, method_arg_nodes, - method_receiver, module_imports, module_items, module_node, no_span, node_name_span, none_type, - param_node_default_value, param_node_name_at, param_node_type_expr, - preserve_outer_optional_cardinality, qualified_last_segment, record_lit_expr_optional, - record_lit_named_field_value_optional, record_lit_type_name_at, resource_use_name_at, - resource_use_resource, return_value, slice_base, slice_end, slice_start, string_type, - type_name_compatible, unaryop_operand, unit_type, with_optional_cardinality, - with_required_cardinality, -}; -pub use crate::v1_std_core::{expr_is_any_literal, expr_literal_symbol_optional}; -pub use crate::v1_std_core::{ - CallSemantics, Cardinality, CompilerDiagnostic, Connective, DeclRefCoords, DeclaredFuncEnv, - DeclaredFuncSig, ErrorNode, ExprData, ExprErrorKind, FieldAccessSpine, FieldAccessStyle, - FieldSummary, FieldValueShape, FrontierOccurrenceKey, InferredNode, InternTable, MatchPattern, - MethodSemantics, NewlineIndex, Node, StringPart, UnaryOpKind, VarBindingKind, -}; -use crate::NonEmptyBTreeSet; -use crate::NonEmptyVec; -use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; -use std::rc::Rc; - -pub fn is_witness_type_name(name: String) -> bool { - ((name.clone() == "Witness".to_string()) || (name.clone() == "witness".to_string())) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ItemContribution { - pub resolved_item: Rc, - pub resolve_diagnostics: Rc>>, - pub func_sig: Option>, - pub svc_entries: Rc>>, - pub svc_local: Option>, - pub item_info: Rc, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ModuleContext { - pub resolved_items: Rc>>, - pub func_env: Rc, - pub svc_registry: Rc>>>>, - pub locals: Rc>>, - pub variant_locals: Rc>>, - pub item_registry: Rc>>, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct VariantFoldState { - pub locals: Rc>>, - pub collision_errors: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct VariantExportSurface { - pub arm_owners: Rc>>, - pub enum_items: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct TypeNameExportFacts { - pub exporter_count: i64, - pub canonical_binding: Option>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct InferScope { - pub type_env: Rc, - pub func_env: Rc, - pub locals: Rc>>, - pub body_locals: Rc>, - pub match_bound_names: Rc>, - pub module_name: String, - pub service_registry: Rc>>>>, - pub item_registry: Rc>>, - pub lambda_param_provenance: Rc>>, - pub caller_decl_name: String, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct InferResult { - pub typed: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BlockInferState { - pub scope: Rc, - pub diag_chunks: Rc>>>>, - pub last_type: Rc, - pub typed_stmts: Rc>>, -} - -pub fn infer_block_stmts( - mut remaining: Rc>>, - mut remaining_count: i64, - mut scope: Rc, - mut typed_stmts: Rc>>, - mut diag_chunks: Rc>>>>, - mut last_type: Rc, - mut expected: Option>, -) -> Rc { - loop { - match remaining.clone().first().cloned() { - None => { - break Rc::new(BlockInferState { - scope: scope.clone(), - diag_chunks: diag_chunks.clone(), - last_type: last_type.clone(), - typed_stmts: typed_stmts.clone(), - }); - } - Some(stmt) => { - let is_last = (remaining_count.clone() == 1); - let stmt_expected = if is_last.clone() { - expected.clone() - } else { - None - }; - let stmt_result = infer_expr(stmt.clone(), scope.clone(), stmt_expected.clone()); - let stmt_typed = stmt_result.typed.clone(); - let stmt_diags = stmt_result.diagnostics.clone(); - let stmt_rt = resolved_type(stmt_typed.clone()); - let next_scope = - scope_after_stmt_node(stmt.clone(), stmt_rt.clone(), scope.clone()); - { - let __tco_0 = Rc::new( - remaining - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - let __tco_1 = (remaining_count - 1); - let __tco_2 = next_scope.clone(); - let __tco_3 = v1_rt::rc_list_push(typed_stmts, stmt_typed.clone()); - let __tco_4 = v1_rt::rc_list_push(diag_chunks, stmt_diags.clone()); - let __tco_5 = stmt_rt.clone(); - remaining = __tco_0; - remaining_count = __tco_1; - scope = __tco_2; - typed_stmts = __tco_3; - diag_chunks = __tco_4; - last_type = __tco_5; - continue; - } - } - } - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct TypedItemResult { - pub item: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ArmInferResult { - pub typed_arm: Rc, - pub diagnostics: Rc>>, - pub body_type: Rc, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct PatternScopeResult { - pub scope: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct StringPartInferResult { - pub typed_part: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ArgInferResult { - pub typed_arg: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct FieldInferResult { - pub typed_field: Rc, - pub infer_result: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BuildTypeEnvResult { - pub env: Rc, - pub cache: Rc, - pub diagnostics: Rc>>, - pub binding_forks: Rc>>, -} - -pub fn binding_forks_channel_note() -> String { - thread_local! { - static CACHED: String = { - "Out-of-band binding-fork ledger channel (S2a move 2 increment B; lane ruling REVISED 2026-07-11: NOVELTY, not TREE, is the refusal axis). A binding fork is one name reaching a module from two peer imports with DIFFERENT bindings. A PRE-EXISTING fork (present on main) is already resolved there by import-order overlay-wins and every real consumer gets that winner, so refusing it retroactively is a REGRESSION (breaks working resolution, makes this PR pay pre-existing corpus debt), NOT a fail-open being closed. So ALL pre-existing forks - same-tree AND cross-tree - are LEDGERED here, keeping the pre-cut overlay-wins winner (behavior-preserving); NONE ride the diagnostics channel (consumers read diagnostics as compile cleanliness). This is the SANCTIONED declared-interim: loud + typed + counted (the floor prints a partitioned count line per run, cli_run reconcile_with_typed_cache) + dissolution-named (std consolidation / namespace Rule-1 terminal) = the std-consolidation worklist, strictly better than main's SILENT overlay-wins. TREE only labels the dissolution partition (same-tree = homonym/fork within one tree; cross-tree = v1-seed-vs-v2 migration debt). The actual WALL is novelty-refusal - hard-refuse a fork a PR NEWLY introduces - implemented as a separate per-PR gate comparing this ledger against a drift-gated baseline receipt (follow-up work item), NOT an in-run refusal (that would double floor cost by re-resolving main's ledger).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ParentModulesResult { - pub modules: Rc>>, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct CycleDetectState { - pub recursive_names: Rc>, - pub global_visited: Rc>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct InferScopeComponents { - pub svc_registry: Rc>>>>, - pub svc_locals: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct LocalContributionState { - pub resolved_items: Rc>>, - pub func_sigs: Rc>>, - pub svc_registry: Rc>>>>, - pub svc_locals: Rc>>, - pub item_registry: Rc>>, - pub diag_chunks: Rc>>>>, -} - -pub fn merge_scope_from_imports( - mut remaining: Rc>>, - mut parent_index: Rc>>, - mut env: Rc, - mut svc_registry: Rc>>>>, - mut svc_locals: Rc>>, -) -> Rc { - loop { - match remaining.clone().first().cloned() { - None => { - break Rc::new(InferScopeComponents { - svc_registry: svc_registry.clone(), - svc_locals: svc_locals.clone(), - }); - } - Some(imp) => match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(typed_parent) => { - let parent_result = typed_parent.items.clone().iter().cloned().fold( - Rc::new(InferScopeComponents { - svc_registry: svc_registry.clone(), - svc_locals: svc_locals.clone(), - }), - |acc: Rc, titem: Rc| { - if ((titem.transport.clone() != None) - && ((titem.children.clone().len() as i64) > 0)) - { - { - let entries = Rc::new({ - let mut __result = Vec::new(); - for c in titem.children.clone().iter().cloned() { - __result.push(Rc::new(OpEntry { - name: authored_name_at( - env.source_indices.clone(), - c.clone(), - ), - outputs: inferred_to_outputs( - c.inferred.clone(), - c.span.clone(), - env.source_indices.clone(), - ), - params: c.params.clone(), - })); - } - __result - }); - let root = namespace_root_from_properties( - titem.properties.clone(), - authored_name_at(env.source_indices.clone(), titem.clone()), - env.source_indices.clone(), - ); - Rc::new(InferScopeComponents { - svc_registry: v1_rt::rc_map_insert( - acc.svc_registry.clone(), - authored_name_at( - env.source_indices.clone(), - titem.clone(), - ), - entries.clone(), - ), - svc_locals: v1_rt::rc_map_insert( - acc.svc_locals.clone(), - root.clone(), - nominal_type_binding(root.clone()), - ), - }) - } - } else { - if (((((titem.body.clone() != None) - && ((titem.params.clone().len() as i64) == 0)) - && (titem.transport.clone() == None)) - && (titem.connective.clone() == Connective::NoConnective)) - && (titem.inferred.clone() != None)) - { - Rc::new(InferScopeComponents { - svc_registry: acc.svc_registry.clone(), - svc_locals: v1_rt::rc_map_insert( - acc.svc_locals.clone(), - authored_name_at( - env.source_indices.clone(), - titem.clone(), - ), - Rc::new(TypeBinding { - name: authored_name_at( - env.source_indices.clone(), - titem.clone(), - ), - resolved: resolved_type(titem.clone()), - provenance: Rc::new( - SubValueRelation::SubValueUnknown, - ), - }), - ), - }) - } else { - acc.clone() - } - } - }, - ); - { - let __tco_0 = Rc::new( - remaining - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - let __tco_1 = parent_result.svc_registry.clone(); - let __tco_2 = parent_result.svc_locals.clone(); - remaining = __tco_0; - svc_registry = __tco_1; - svc_locals = __tco_2; - continue; - } - } - None => { - let __tco_0 = Rc::new( - remaining - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - remaining = __tco_0; - continue; - } - }, - } - } -} - -pub fn nominal_leaf_type(name: String) -> Rc { - nominal_type_ref(name.clone()) -} - -pub fn nominal_type_binding(name: String) -> Rc { - Rc::new(TypeBinding { - name: name.clone(), - resolved: nominal_leaf_type(name.clone()), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct FieldRecursionResult { - pub shape: RecursionShape, - pub element_type: String, -} - -pub fn classify_field_recursion( - field_node: Rc, - parent_name: String, - recursive_type_set: Rc>, - source_indices: Rc>>, -) -> Option> { - { - let type_expr = match field_node.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), - _ => field_node_type_expr(field_node.clone()), - }; - let field_type_name = authored_name_at(source_indices.clone(), type_expr.clone()); - if (field_type_name.clone() == parent_name.clone()) { - match field_node.return_cardinality.clone() { - Cardinality::CardOptional => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::OptionalRecursion, - element_type: parent_name.clone(), - })), - _ => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::DirectRecursion, - element_type: parent_name.clone(), - })), - } - } else { - if is_container_type(field_type_name.clone()) { - { - let arity = match container_expected_arity(field_type_name.clone()) { - Some(a) => a.clone(), - None => 0, - }; - let value_index = if (arity.clone() == 2) { 1 } else { 0 }; - let value_type = match type_expr - .children - .clone() - .iter() - .cloned() - .skip(value_index.clone() as usize) - .next() - { - Some(t) => authored_name_at(source_indices.clone(), t.clone()), - None => "".to_string(), - }; - let is_recursive_element = ((value_type.clone() == parent_name.clone()) - || v1_rt::set_contains(&recursive_type_set, value_type.clone())); - if is_recursive_element.clone() { - { - let elem = if (value_type.clone() == parent_name.clone()) { - parent_name.clone() - } else { - value_type.clone() - }; - match field_type_name.clone().as_str() { - "List" => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::ListRecursion, - element_type: elem.clone(), - })), - "Set" => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::SetRecursion, - element_type: elem.clone(), - })), - "Map" => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::MapValueRecursion, - element_type: elem.clone(), - })), - _ => None, - } - } - } else { - None - } - } - } else { - if v1_rt::set_contains(&recursive_type_set, field_type_name.clone()) { - match field_node.return_cardinality.clone() { - Cardinality::CardOptional => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::OptionalRecursion, - element_type: field_type_name.clone(), - })), - _ => Some(Rc::new(FieldRecursionResult { - shape: RecursionShape::DirectRecursion, - element_type: field_type_name.clone(), - })), - } - } else { - None - } - } - } - } -} - -pub fn collect_fields_inductive( - fields: Rc>>, - parent_name: String, - variant_name: String, - recursive_type_set: Rc>, - acc: Rc>>>>, - source_indices: Rc>>, -) -> Rc>>>> { - fields.clone().iter().cloned().fold( - acc.clone(), - |field_acc: Rc>>>>, field_node: Rc| { - match classify_field_recursion( - field_node.clone(), - parent_name.clone(), - recursive_type_set.clone(), - source_indices.clone(), - ) { - Some(result) => put_inductive_field_cross( - field_acc.clone(), - parent_name.clone(), - variant_name.clone(), - authored_name_at(source_indices.clone(), field_node.clone()), - result.shape.clone(), - result.element_type.clone(), - ), - None => field_acc.clone(), - } - }, - ) -} - -pub fn collect_item_inductive_fields( - item: Rc, - recursive_type_set: Rc>, - source_indices: Rc>>, -) -> Rc>>>> { - { - let item_name = authored_name_at(source_indices.clone(), item.clone()); - match item.connective.clone() { - Connective::Disj => item.children.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>>>(), - |variant_acc: Rc>>>>, - variant_node: Rc| { - collect_fields_inductive( - variant_node.children.clone(), - item_name.clone(), - authored_name_at(source_indices.clone(), variant_node.clone()), - recursive_type_set.clone(), - variant_acc, - source_indices.clone(), - ) - }, - ), - Connective::Conj => collect_fields_inductive( - item.children.clone(), - item_name.clone(), - "".to_string(), - recursive_type_set.clone(), - v1_rt::rc_empty_map::>>>(), - source_indices.clone(), - ), - _ => v1_rt::rc_empty_map::>>>(), - } - } -} - -pub fn build_item_inductive_fields( - items: Rc>>, - recursive_type_set: Rc>, - source_indices: Rc>>, -) -> Rc>>>> { - items.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>>>(), - |acc: Rc>>>>, item: Rc| { - merge_inductive_fields( - acc, - collect_item_inductive_fields( - item.clone(), - recursive_type_set.clone(), - source_indices.clone(), - ), - ) - }, - ) -} - -pub fn nominal_ref_node( - name: String, - span: Rc, - ident_span: Option>, -) -> Rc { - Rc::new(Node { - name: name.clone(), - span: span.clone(), - ident_span: ident_span.clone(), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: Some(Rc::new(InferredNode::Resolved { - node: nominal_leaf_type(name.clone()), - })), - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }) -} - -pub fn resolved_callable_type(func_params: Rc>>, ret: Rc) -> Rc { - make_callable_type(func_params.clone(), ret.clone()) -} - -pub fn namespace_root_from_properties( - properties: Rc>>, - name: String, - source_indices: Rc>>, -) -> String { - match Rc::new({ - let mut __result = Vec::new(); - for p in properties.clone().iter().cloned() { - if (field_init_node_name_at(p.clone(), source_indices.clone()) - == "namespace_root".to_string()) - { - __result.push(p); - } - } - __result - }) - .first() - .cloned() - { - Some(ns_prop) => match expr_literal_string_optional(field_init_node_value(ns_prop.clone())) - { - Some(root) => root.clone(), - None => name, - }, - None => name, - } -} - -pub fn namespace_alias_target_path( - item: Rc, - source_indices: Rc>>, -) -> Option { - find_property_string( - item.properties.clone(), - "namespace_alias_target".to_string(), - source_indices.clone(), - ) -} - -pub fn is_namespace_alias_item( - item: Rc, - source_indices: Rc>>, -) -> bool { - match namespace_alias_target_path(item.clone(), source_indices.clone()) { - Some(_) => true, - None => false, - } -} - -pub fn namespace_alias_binding_for_target( - item: Rc, - target_node: Rc, - source_indices: Rc>>, -) -> Rc { - Rc::new(TypeBinding { - name: authored_name_at(source_indices.clone(), item.clone()), - resolved: target_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }) -} - -pub fn expr_span(texpr: Rc) -> Rc { - texpr.span.clone() -} - -pub fn ok_infer(texpr: Rc) -> Rc { - Rc::new(InferResult { - typed: texpr.clone(), - diagnostics: Rc::new(vec![]), - }) -} - -pub fn semantic_expr_error_node(message: String, span: Rc) -> Rc { - make_expr_error_node( - ExprErrorKind::SemanticExprError, - message.clone(), - span.clone(), - ) -} - -pub fn internal_expr_error_node(message: String, span: Rc) -> Rc { - make_expr_error_node( - ExprErrorKind::InternalExprError, - message.clone(), - span.clone(), - ) -} - -pub fn lookup_variant_parent_enum(scope: Rc, name: String) -> Option { - match v1_rt::map_get(&scope.locals.clone(), name.clone()) { - Some(binding) => match lookup_type_for(scope.type_env.clone(), binding.resolved.clone()) { - Some(parent) => { - let is_coproduct = (parent.connective.clone() == Connective::Disj); - if is_coproduct.clone() { - if has_child_named( - parent.clone(), - name.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(authored_name_at( - scope.type_env.clone().source_indices.clone(), - binding.resolved.clone(), - )) - } else { - None - } - } else { - None - } - } - None => None, - }, - None => None, - } -} - -pub fn expected_variant_owner_instantiation( - expected: Option>, - name: String, - scope: Rc, -) -> Option> { - match expected.clone() { - Some(exp) => { - let exp_enum = - expand_scrut_type_for_variant_lookup(exp.clone(), scope.type_env.clone()); - match find_child_named( - exp_enum.clone(), - name.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(_) => Some(exp_enum.clone()), - None => None, - } - } - None => None, - } -} - -pub fn variant_reference_inferred_node( - expected: Option>, - name: String, - owner_name: String, - scope: Rc, - fallback: Rc, -) -> Rc { - match expected.clone() { - Some(exp) => { - if ((exp.return_cardinality.clone() == Cardinality::Required) - && (authored_name_at(scope.type_env.clone().source_indices.clone(), exp.clone()) - == owner_name.clone())) - { - match expected_variant_owner_instantiation( - expected.clone(), - name.clone(), - scope.clone(), - ) { - Some(_) => exp.clone(), - None => fallback, - } - } else { - fallback - } - } - None => fallback, - } -} - -pub fn variant_owner_node(scope: Rc, name: String) -> Option> { - if v1_rt::contains(name.clone(), ".".to_string()) { - match symbol_index_lookup(scope.type_env.clone().symbol_index.clone(), name.clone()) { - Some(resolved) => { - if ((resolved.connective.clone() == Connective::Disj) - && has_child_named( - resolved.clone(), - qualified_last_segment(name.clone()), - scope.type_env.clone().source_indices.clone(), - )) - { - Some(resolved.clone()) - } else { - None - } - } - None => None, - } - } else { - match v1_rt::map_get(&scope.locals.clone(), name.clone()) { - Some(binding) => { - match lookup_type_for(scope.type_env.clone(), binding.resolved.clone()) { - Some(owner) => { - let owner_is_coproduct = (owner.connective.clone() == Connective::Disj); - if owner_is_coproduct.clone() { - if has_child_named( - owner.clone(), - name.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(owner.clone()) - } else { - None - } - } else { - None - } - } - None => None, - } - } - None => None, - } - } -} - -pub fn infer_var_binding_kind(scope: Rc, name: String) -> Rc { - match lookup_variant_parent_enum(scope.clone(), name.clone()) { - Some(parent_enum) => Rc::new(VarBindingKind::VariantValueBinding { - parent_enum: parent_enum.clone(), - }), - None => match v1_rt::map_get(&scope.locals.clone(), name.clone()) { - Some(_) => { - if v1_rt::map_has(&scope.match_bound_names.clone(), name.clone()) { - Rc::new(VarBindingKind::MatchBoundBinding) - } else { - Rc::new(VarBindingKind::LocalValueBinding) - } - } - None => Rc::new(VarBindingKind::FunctionValueBinding), - }, - } -} - -pub fn inference_error( - message: String, - span: Rc, - module_name: String, -) -> Rc { - make_error_node( - Rc::new(CompilerDiagnostic::InternalError { - message: message.clone(), - span: span.clone(), - }), - module_name.clone(), - ) -} - -pub fn ambiguous_reference_refusal( - name: String, - candidates: Rc>, - span: Rc, - scope: Rc, -) -> Rc { - Rc::new(InferResult { - typed: semantic_expr_error_node( - v1_rt::concat( - v1_rt::concat("ambiguous reference '".to_string(), name.clone()), - "'".to_string(), - ), - span.clone(), - ), - diagnostics: Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::AmbiguousReference { - name: name.clone(), - candidates: candidates.clone(), - span: span.clone(), - }), - scope.module_name.clone(), - )]), - }) -} - -pub fn constructor_reference_admission_enforced() -> bool { - true -} - -pub fn constructor_reference_admission_frontier_note() -> String { - thread_local! { - static CACHED: String = { - "Counted v1 seed realization for ConstructorReferenceAdmission (Horn 3, msg_968d6c24): unified infer construction-admission beside sole_constructor record-literal refusal. Dissolves when compiler_frontier_row_04_infer self-emits CargoGreen and v2 infer is the production typecheck path (^migrate_when_closure_self_emits_cargo_green).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn constructor_reference_admission_enforced_now() -> bool { - constructor_reference_admission_enforced() -} - -pub fn decl_ref_coords_equal(a: Rc, b: Rc) -> bool { - ((a.module_path.clone() == b.module_path.clone()) - && (a.decl_name.clone() == b.decl_name.clone())) -} - -pub fn caller_decl_coords(scope: Rc) -> Option> { - if (scope.caller_decl_name.clone() == "".to_string()) { - None - } else { - Some(Rc::new(DeclRefCoords { - module_path: scope.module_name.clone(), - decl_name: scope.caller_decl_name.clone(), - })) - } -} - -pub fn declaration_lookup_failure_label(cause: Rc) -> String { - match (*cause.clone()).clone() { - DeclarationLookupFailure::DeclarationNotIndexedAtQualifiedName { - qualified_name: qn, - .. - } => v1_rt::concat( - v1_rt::concat("no declaration is indexed at '".to_string(), qn.clone()), - "'".to_string(), - ), - } -} - -pub fn constructor_call_admission_diags( - callee_name: String, - scope: Rc, - span: Rc, -) -> Rc>> { - if !constructor_reference_admission_enforced_now() { - Rc::new(vec![]) - } else { - match (*func_decl_binding_for_call(scope.func_env.clone(), scope.type_env.clone(), callee_name.clone())).clone() { - ConstructorDeclarationLookup::ExactConstructorDeclaration { identity, declaration: declaration_node, .. } => match fn_admit_callers(declaration_node.clone(), scope.type_env.clone().source_indices.clone()) { - Some(permitted) => match caller_decl_coords(scope.clone()) { - Some(caller) => if { let mut __found = false; for p in permitted.clone().iter().cloned() { if decl_ref_coords_equal(p.clone(), caller.clone()) { __found = true; break; } } __found } { - Rc::new(vec![]) - } else { - Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::ConstructorCallAdmissionRefused { - constructor_module_path: identity.owner_module_path.clone(), - constructor_decl_name: identity.decl_name.clone(), - caller_module_path: caller.module_path.clone(), - caller_decl_name: caller.decl_name.clone(), - permitted_callers: Rc::new({ let mut __result = Vec::new(); for p in permitted.clone().iter().cloned() { __result.push(decl_ref_coords_label(p.clone())); } __result }), - span: span.clone(), -}), scope.module_name.clone())]) - }, - None => Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::ConstructorCallAdmissionRefused { - constructor_module_path: identity.owner_module_path.clone(), - constructor_decl_name: identity.decl_name.clone(), - caller_module_path: scope.module_name.clone(), - caller_decl_name: "".to_string(), - permitted_callers: Rc::new({ let mut __result = Vec::new(); for p in permitted.clone().iter().cloned() { __result.push(decl_ref_coords_label(p.clone())); } __result }), - span: span.clone(), -}), scope.module_name.clone())]), -}, - None => Rc::new(vec![]), -}, - ConstructorDeclarationLookup::NotAdmissionBearingReference => Rc::new(vec![]), - ConstructorDeclarationLookup::AdmissionBearingDeclarationUnavailable { identity, cause, .. } => Rc::new(vec![inference_error(v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat("constructor reference admission cannot establish the declaration identity of '".to_string(), identity.decl_name.clone()), "' owned by '".to_string()), identity.owner_module_path.clone()), "': ".to_string()), declaration_lookup_failure_label(cause.clone())), " -- refusing rather than reading admission facts off a resolved value node".to_string()), span.clone(), scope.module_name.clone())]), -} - } -} - -pub fn constructor_reference_admission_refusal( - callee_name: String, - span: Rc, - scope: Rc, -) -> Rc { - Rc::new(InferResult { - typed: semantic_expr_error_node( - v1_rt::concat( - v1_rt::concat( - "constructor call admission refused for '".to_string(), - callee_name.clone(), - ), - "'".to_string(), - ), - span.clone(), - ), - diagnostics: constructor_call_admission_diags( - callee_name.clone(), - scope.clone(), - span.clone(), - ), - }) -} - -pub fn constructor_reference_admission_unshadowed( - callee_name: String, - span: Rc, - scope: Rc, -) -> Option> { - if v1_rt::map_has(&scope.body_locals.clone(), callee_name.clone()) { - None - } else { - constructor_reference_admission_early_refusal( - callee_name.clone(), - span.clone(), - scope.clone(), - ) - } -} - -pub fn constructor_reference_admission_early_refusal( - callee_name: String, - span: Rc, - scope: Rc, -) -> Option> { - { - let admission_diags = - constructor_call_admission_diags(callee_name.clone(), scope.clone(), span.clone()); - match admission_diags.clone().first().cloned() { - Some(_) => Some(constructor_reference_admission_refusal( - callee_name.clone(), - span.clone(), - scope.clone(), - )), - None => None, - } - } -} - -pub fn type_mismatch_error( - expected: String, - got: String, - span: Rc, - module_name: String, -) -> Rc { - make_error_node( - Rc::new(CompilerDiagnostic::TypeMismatch { - expected: expected.clone(), - got: got.clone(), - span: span.clone(), - }), - module_name.clone(), - ) -} - -pub fn seed_node_traversal_frontier() -> String { - thread_local! { - static CACHED: String = { - "🟡 dissolve-on: v1_seed_deleted_at_v2_self_host (opened 2026-07-31) — the v1 seed reads and recurses substrate Node storage directly instead of consuming a canonical traversal surface. Recorded as ONE frontier row for the CLASS, because that is the honest grain: the idiom is 16 self-recursive `children |> flat_map` sites on origin/main across 04_emit_info, 04_sigs, 04_infer, 05_emit, 05_emit_rust, compile and complexity (collect_type_names_from_node, named_type_vars_in_node, collect_value_ref_names and siblings), plus 579 direct Node-storage field reads in 04_infer alone. collect_explicit_return_values is the 17th instance and v1.compiler.trait_derive_emit.v1_type_expr_contains_param_name the 18th (codex review 47248), not new classes, and a per-function row would assert separable work that does not exist while 16 identical siblings carried none (codex reviews 45570, 45580, 45666). SIBLING COUNT IS NOT THE JUSTIFICATION and the reviewer is right to reject that reading — precedent is debt, not permission. The justification is that no canonical surface is REACHABLE here: fold_node and node_query are v2 substrate, no v1 seed module imports v2, and v1 COMPILES v2, so routing seed inference through v2's fold inverts the bootstrap; and no shared v1 walker exists to route through, because every v1 collector recurses itself. DESIGN's fold_node line is scoped to the 7 v2 stages. COST OF CLOSING NOW, which is why this is retained rather than accepted: building a v1-local generic traversal for one call site adds another shape without removing any of the existing ones, and migrating all 18 is a seed-wide refactor of the stage that IS the traversal — against a seed whose declared endpoint is deletion. DISSOLVES WHEN the v1 seed is deleted at v2 self-host, at which point every row in this class goes with it; the same trigger compiler_diagnostic_seed_projection_note carries for the hand-Rust arms, because it is the same seed and the same endpoint.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn collect_explicit_return_values(n: Rc) -> Rc>> { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*n.expr_data.clone()).clone() { - ExprData::ExprLambda => Rc::new(vec![]), - ExprData::ExprReturn => v1_rt::concat( - Rc::new(vec![return_value(n.clone())]), - Rc::new({ - let mut __result = Vec::new(); - for c in n.children.clone().iter().cloned() { - __result - .extend((*collect_explicit_return_values(c.clone())).iter().cloned()); - } - __result - }), - ), - _ => Rc::new({ - let mut __result = Vec::new(); - for c in n.children.clone().iter().cloned() { - __result.extend((*collect_explicit_return_values(c.clone())).iter().cloned()); - } - __result - }), - } - }) -} - -pub fn explicit_return_conformance_diags( - declared: Rc, - body_typed: Rc, - scope: Rc, -) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for returned in collect_explicit_return_values(body_typed.clone()) - .iter() - .cloned() - { - __result.extend( - (*declared_type_conformance_diags( - declared.clone(), - resolved_type(returned.clone()), - returned.span.clone(), - scope.clone(), - )) - .iter() - .cloned(), - ); - } - __result - }) -} - -pub fn explicit_return_conformance_note() -> String { - thread_local! { - static CACHED: String = { - "An EARLY return is a second exit from the same declaration and must meet the same declared type as the last expression. The conformance wall first checked only the body's final inferred type, so `fn f(cond: Bool) -> Int { if cond { return \"wrong\" } 1 }` compiled clean — the block's value is the trailing 1, which conforms, and the wrong-typed exit was never compared against anything (codex review 45472, confirmed by execution: exit 0 before, a located TypeMismatch after). The check reuses declared_type_conformance_diags rather than minting a second relation, so the early exit is judged by exactly the ground-kernel-scalar and ground-element-collection discipline the trailing expression is judged by, and it widens with that gate rather than beside it. THE WALK STOPS AT A LAMBDA BOUNDARY, and it did not at first. A `return` inside a nested lambda belongs to the LAMBDA's callable return type, not the enclosing declaration's, so recursing through ExprLambda checked it against the wrong declaration and refused correct code — a fabricated refusal, which §5 forbids exactly as it forbids a fabricated success, and the mirror image of the hole this fn was added to close (codex review 45481, confirmed by execution: a lambda returning String inside a fn declared -> Int refused with expected Primitive(Int) got Primitive(String)). Every callable boundary is a new declaration and its returns are judged against it, not against whatever encloses it. THE WALKER'S OWN DISPOSITION, distinct from the lambda-coverage trigger below and asked for separately (codex review 45580): it is the seed's, not this function's. Self-recursive `children |> flat_map` collection is the v1 seed's only traversal idiom — 16 such sites on origin/main across 04_emit_info, 04_sigs, 04_infer, 05_emit, 05_emit_rust, compile and complexity (collect_type_names_from_node, named_type_vars_in_node, collect_value_ref_names and siblings) — and there is no shared v1 walker to route through, because each collector recurses itself. Nor is there a canonical fold to reach for: fold_node and node_query are v2 substrate, no v1 seed module imports v2, and v1 COMPILES v2, so routing seed inference through v2's fold inverts the bootstrap. DESIGN's fold_node line is scoped to the 7 v2 stages. So this is the 17th instance of a 16-instance idiom, and its trigger is the one every sibling carries: the v1 seed shrinks to zero at v2 self-host and they dissolve together. Generalizing a shared collector for this one call site alone would ADD a 17th shape rather than remove one; the dissolution that is real is the seed's. That reasoning was recorded on where_refinement_receiver_peel_note for the same class and NOT here, which is why it had to be found twice — a disposition stated on one carrier and omitted from its sibling is not stated. Lambda returns are consequently NOT yet judged here — the lambda's own declared return is not threaded to this post-pass — which is a narrowing, stated rather than implied, and it dissolves when the walk carries each callable's declared return rather than only infer_item's.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn declared_return_type_node(item: Rc) -> Rc { - preserve_outer_optional_cardinality(item.clone(), resolved_type(item.clone())) -} - -pub fn conformance_ground_kernel_scalar( - n: Rc, - source_indices: Rc>>, -) -> bool { - { - let plain_shape = ((n.connective.clone() == Connective::NoConnective) - && ((n.children.clone().len() as i64) == 0)); - let required = (n.return_cardinality.clone() == Cardinality::Required); - let kernel_named = is_kernel_type(authored_name_at(source_indices.clone(), n.clone())); - ((plain_shape.clone() && required.clone()) && kernel_named.clone()) - } -} - -pub fn conformance_ground_element_collection( - n: Rc, - source_indices: Rc>>, -) -> bool { - { - let shaped_container = (((n.connective.clone() == Connective::NoConnective) - && node_is_element_collection(n.clone(), source_indices.clone())) - && (node_is_keyed_collection(n.clone(), source_indices.clone()) == false)); - let required = (n.return_cardinality.clone() == Cardinality::Required); - let element_ground = match n.children.clone().first().cloned() { - Some(el) => conformance_ground_kernel_scalar( - child_type_node(el.clone()), - source_indices.clone(), - ), - None => false, - }; - ((shaped_container.clone() && required.clone()) && element_ground.clone()) - } -} - -pub fn conformance_ground_type( - n: Rc, - source_indices: Rc>>, -) -> bool { - (conformance_ground_kernel_scalar(n.clone(), source_indices.clone()) - || conformance_ground_element_collection(n.clone(), source_indices.clone())) -} - -pub fn conformance_unjudged_live_hole_note() -> String { - thread_local! { - static CACHED: String = { - "PROVEN LIVE HOLE, AND THE REASON THE UNJUDGED ADVISORY IS EXCLUDED FROM THIS PR (codex reviews 45647, 45767). The branch now returns [] for the unjudged case, matching origin/main exactly, so this PR neither closes nor worsens the class; it lands with the identity capability instead. The record below is kept because the witness and the five measured attempts are what that lane starts from. The unjudged branch is not merely unmeasured — a program that is simply WRONG reaches emission through it. Executed witness: `type R { x: Int }` `type S { y: String }` `fn wrong_record() -> R { S { y: \"a\" } }` compiles EXIT 0 and EMITS TWO FILES, on this branch and on origin/main alike. Two structurally unrelated named records is not a representation gap; it is the conformance half of #7479. It was briefly reported as a counted advisory here, and that is precisely what was removed: counting it protects nothing, and a number beside a wrong program is the fabricated success DESIGN 5 forbids, one level up. THE FIX WAS ATTEMPTED AND IS NOT LANDED, and the measurements are recorded because they are the real cost of the next attempt rather than a reason to stop looking. Three successive narrowings of a refuse-when-both-sides-are-named-structured rule were each run against the whole corpus: (1) both sides structured and named -> 90 refusals of CORRECT code, dominated by the two-representation optionality class (24 Node(Optional) vs Primitive(Node), plus Coproduct(X) vs Coproduct(Optional)); (2) narrowed to inhabited named RECORDS with kernel scope names excluded -> 15; (3) additionally guarding the raw nodes -> 27, and the population had by then shifted to a NEW class, produced sides that are let-BINDING names (module_emit_scope, scope_after_expr, lookup_item) rather than types. The count moving 90 -> 15 -> 27 rather than monotonically down is the finding: each guard displaces the false-positive population instead of shrinking it, which is the exemption-accumulation this wall refuses elsewhere, and shipping any of the three would red correct code. So the arm is NOT landed, and with no arm to land the residue is left exactly where main leaves it rather than dressed up as partial coverage. The blocking obstacle is named and is not vague: the produced-side node reaching this branch is not reliably a TYPE — it can be a nominal reference, a kernel encoding of cardinality or absence, an anonymous literal, or a let-binding identity — so no predicate over its shape can separate a real mismatch from a representation gap until produced-side type identity is established upstream. A FOURTH attempt isolated the obstacle exactly, and it is the reason the other three moved the population instead of shrinking it: guarding on `both sides are Conj whose authored name RESOLVES via lookup_type_by_name to a record declaration` still refused 14 seed sites, and every one had a LET-BINDING name on the produced side (module_emit_scope, scope_after_expr, lookup_item, service_fallback_transport). lookup_type_by_name resolves those because bindings and types inhabit ONE name environment, so the guard cannot tell a type identity from a binding identity — which is the stated obstacle, now demonstrated rather than inferred. A FIFTH attempt tested the one discriminator that looked left — requiring the resolved declaration to NAME ITSELF, on the theory that a type declares its own name while a binding resolves to a type named differently — and it returned the IDENTICAL 14 sites, because lookup_type_by_name on a binding returns a node carrying the BINDING's name, not its type's. The name environment does not merely conflate the two lookups; the resolved node itself carries no separable type identity. No predicate over the produced node's shape or name can close this class. Dissolve-on: feature:conformance-produced-type-identity — the produced node carries a resolved type identity rather than a shape to be guessed at, at which point the refusal arm is one predicate over two identities and this row deletes. THE PERMISSION IS NOT THIS PATH'S AND THAT WAS MEASURED, NOT ASSERTED: the identical program built against origin/main compiles EXIT 0, emits 2 files and reports ZERO diagnostics, and this branch now does the same, because the unjudged branch returns the same empty list main returns. So the conformance path neither newly permits the emission nor closes it. THE COUNTED-ADVISORY MIDDLE GROUND WAS TRIED AND REJECTED, and the rejection is the useful part of this row: an advisory made the fail-open visible without making it stop, and review held that visibility is not protection when the program is PROVABLY wrong rather than merely unproven (codex reviews 45647, 45695, 45711, 45767, 45777). Agreed on execution — the R/S witness above emitted two files under the advisory. So the class is left at main's behavior and named here with its trigger, and what ships is the method-existence wall, which does refuse and does emit nothing. That is a judgment about sequencing, not a claim that the hole is acceptable: a declared boundary with an executed witness, an owner-facing trigger and a measured cost, and deliberately NOT a success path with a number beside it.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn conformance_expansion_depth_note() -> String { - thread_local! { - static CACHED: String = { - "MEASUREMENT RECEIPT FOR THE NEXT LANE, NOT A DESCRIPTION OF LIVE CODE — the expansion-peeling comparison it records was deleted together with the unjudged advisory it fed (codex review 45767), and this row is kept because the measurement is what the next attempt starts from rather than re-derives. A declared type and a produced type routinely arrive at DIFFERENT EXPANSION DEPTHS: the declaration side is a nominal reference to T while the body side is T's already-expanded body, so comparing them as they arrive reads one type as two. Measured over the whole corpus that was the majority of the unjudged residue — 203 Node, 173 Outcome, 46 Witness, 43 Optional, 38 PipelineStep and a long tail, each a reference and its own body — which is why the frontier first read 3005 and then 1566 once each side was resolved through lookup_type_for and peeled through peel_where_refinement_base, the SAME peel the method wall uses (DESIGN section 3: one authority, two consumers, not a second one minted here). Reporting those as unjudged was not a conservative silence but a WRONG COUNT, and an inflated frontier buries the residue that genuinely cannot be decided under pairs that were never in doubt. THE COMPARISON MUST BE THE STRUCTURAL RELATION, NOT A RENDERED SHAPE STRING, and the first version of this got that wrong in a way worth keeping on the record: it compared node_type_shape output, which collapses every anonymous product to the literal text Product() and every named product to its OUTER NAME ONLY, discarding fields, variants and their types. So two structurally different records compared EQUAL and were stamped proven-conforming — the exact fail-open this wall exists to delete, reintroduced while removing a different one, and by the same mechanism as the earlier 1.0/0.0 seam: a projection that looks like evidence used where a proof was required (codex review 45600). A display projection is for MESSAGES; a judgment must consume the structural relation. That constraint outlives the deleted code and binds whoever rebuilds it: node_type_compatible recurses into container elements and compares canonical template names, so identity is established rather than rendered, but its known imprecision is only safe where a mismatch costs a count rather than a refusal — it reports MISMATCH for the four classes of correct code enumerated in declared_type_conformance_note, so wiring it to a refusal without first establishing produced-side type identity (feature:conformance-produced-type-identity) reds correct code. That is the trap the five measured attempts in conformance_unjudged_live_hole_note fell into.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn declared_type_conformance_diags( - declared: Rc, - produced: Rc, - span: Rc, - scope: Rc, -) -> Rc>> { - { - let si = scope.type_env.clone().source_indices.clone(); - let both_ground = (conformance_ground_type(declared.clone(), si.clone()) - && conformance_ground_type(produced.clone(), si.clone())); - if !both_ground.clone() { - Rc::new(vec![]) - } else { - if node_type_compatible(declared.clone(), produced.clone(), si.clone()) { - Rc::new(vec![]) - } else { - Rc::new(vec![type_mismatch_error( - node_type_shape(declared.clone(), si.clone()), - node_type_shape(produced.clone(), si.clone()), - span.clone(), - scope.module_name.clone(), - )]) - } - } - } -} - -pub fn declared_type_conformance_note() -> String { - thread_local! { - static CACHED: String = { - "WALL (DESIGN §5) — a declaration must CONSTRAIN the value it declares, not merely state an intent beside it. infer_item passed the declared return into body inference as expected but then kept the declaration own inferred return REGARDLESS of what the body produced, and the generic expected handling in infer_expr applies where-refinement checks rather than a general actual-subtype-of-declared judgment. So fn f() -> Int { \"wrong\" } typechecked with ZERO diagnostics and the lie surfaced at the first consumer, field access, or host parser. Three positions are checked against their declaration: a fn body vs its declared return (both the param-carrying and paramless arms) and a data value vs its type annotation. THE SCOPE IS DELIBERATELY NARROW AND THE NARROWING IS THE FINDING. node_type_compatible is the corpus compatibility relation and it is NOT sound as a general declared-versus-produced conformance judgment: measured over the whole tree, four independent classes of CORRECT code reported a mismatch, each a place where the relation compares names across representations it never peels. (1) OPTIONALITY LIVES IN TWO REPRESENTATIONS — a fn declared -> String? carries optionality in item.return_cardinality while its body produces the nominal Optional coproduct, so 4 correct sites in 05_emit_rust.dag read as expected Primitive(String) got Coproduct(Optional). (2) BRAND ALIASES ARE NOT PEELED — Hash is ContentHash is a branded String, so 3 correct sites in dag_collect_support.dag read as expected Primitive(String) got Primitive(Hash); the same class the method wall measured as NonEmptyStr arriving as Product(NonEmptyStr). (3) ANONYMOUS RECORD LITERALS — the corpus writes a typed list as [ { name: ..., .. }, .. ] without repeating the nominal type, so 8+ correct rows in dag/std/algebra.dag read as expected Container(List,Product(AlgebraFieldTemplate)) got Container(List,Product()). (4) CARDINALITY IS NOT ON THE RESOLVED TYPE NODE — resolved_type(n: item) drops the declaration optional marker, which is why the declared side is built through preserve_outer_optional_cardinality, the existing single authority for carrying an outer node cardinality onto an inner type node. Each class was found by RUNNING the wall over the corpus, never by reasoning about it, and the list is not known to be exhaustive — which is precisely why this wall does not chase them with exemptions. Four ad-hoc carve-outs would leave a wall that is neither principled nor trustworthy, and fabricating a refusal is the mirror image of the fabricated success the wall exists to delete. So the predicate is POSITIVE ESTABLISHMENT, the same discipline the method wall uses: judge ONLY when both sides are ground kernel scalars — plain shape, Required cardinality, and a name in std.types kernel_type_set — because then a name difference IS a real difference with no alias, brand, container, coproduct or cardinality representation in between. That admits the whole class the operator named (declaring one primitive and returning another, fn f() -> Int { \"a string\" } and data d: Int = \"a string\") and admits nothing it cannot prove. THE GATE WAS FIRST WRITTEN AS SCALAR-ONLY AND THAT WAS TOO NARROW, which review found before any consumer did: a plain shape excludes a List, so a declared List whose body produced a List was indistinguishable from a conforming declaration and compiled clean, and calling that state UNJUDGED in prose did not model it (codex review 45398). The widening is the SAME argument, not an exception to it — a container of a ground kernel scalar has no alias, brand, coproduct, anonymous-literal or cardinality representation standing between the two sides either, so a difference in the element name is a real difference exactly as a difference in a scalar name is. conformance_ground_type therefore admits a ground kernel scalar OR a Required, non-keyed element collection whose element is one, and the whole dag + src/v2 corpus stays clean under it, which is the same instrument that found the four false-positive classes above. The discriminating control was run against the PRIOR compiler rather than reasoned about: `fn f() -> List { [\"a\", \"b\"] }` with `data d: List = [1, 2]` compiles with exit 0 on the pre-widening binary and refuses with two located mismatches on this one. EVERYTHING STILL WIDER IS UNJUDGED, AND IN THIS PR UNJUDGED IS A SILENCE — a deliberate narrowing, not an oversight. It is worth stating why the opposite was tried first: an unproven declaration returning an empty diagnostic list is byte-for-byte indistinguishable in the output from a proven-conforming one, so the absence of a check reads as the presence of a proof (codex review 45500). Making it a counted DeclaredTypeConformanceUnjudged advisory answered that objection and raised a larger one — an advisory does not stop a wrong program, so a proven-wrong program still emitted with a number beside it (codex reviews 45647, 45695, 45711, 45777). That advisory measured the frontier at 1566 declarations whole-tree and is EXCLUDED here (codex review 45767), because the branch could not be made to refuse safely either — see conformance_unjudged_live_hole_note for the executed witness and the five measured attempts. So this branch returns [] for the unjudged case, which is byte-for-byte what origin/main does, and this PR's contribution to conformance is exactly the REFUSALS it can prove: ground kernel scalars and ground element collections. Nothing about the unjudged class is worse than main; it is simply not addressed here, and it lands with the identity capability rather than beside it. IT WAS FIRST MEASURED AT 3005 AND THAT NUMBER WAS WRONG, which matters because the count is the whole bound: nearly half of it was one type compared against ITSELF at two expansion depths (a declaration naming T versus a body producing T's expanded body), so the frontier was reported almost twice its true size — see conformance_expansion_depth_note. An inflated frontier is not a conservative error; it hides the residue that genuinely cannot be decided underneath pairs that were never in doubt. It fires only where the declared and produced SHAPES DIFFER, because identical shapes have nothing to prove and counting them would bury the signal under declarations nobody doubts — the residue that matters is exactly the set where a mismatch could hide. Each numbered class above is a promotion trigger, and each promotion should be visible as a drop in that count. Keyed collections are deliberately not admitted yet — the key and value axes need their own corpus measurement, and guessing that the element argument transfers is precisely the move this note refuses elsewhere. Dissolve-on: a peeling conformance relation that grounds brand aliases to their base, reconciles the two optionality representations, and grounds an anonymous literal against its expected nominal type — at which point the ground-kernel-scalar gate widens class by class and finally deletes. Not covered here and each its own lane: direct-call argument types inside compiler modules (the v2. / v1.compiler. exemption), default field values, generic record instantiation, and post-substitution generic field access.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn rejects_string_for_optional_coproduct_field( - expected: Rc, - got: Rc, - source_indices: Rc>>, - env: Rc, -) -> bool { - { - let expected_resolved = - match lookup_type_for(env.clone(), with_required_cardinality(expected.clone())) { - Some(resolved) => resolved.clone(), - None => with_required_cardinality(expected.clone()), - }; - let expected_is_optional_coproduct = ((expected.return_cardinality.clone() - == Cardinality::CardOptional) - && (expected_resolved.connective.clone() == Connective::Disj)); - let got_is_string = ((node_type_shape(got.clone(), source_indices.clone()) - == "Primitive(String)".to_string()) - || (authored_name_at(source_indices.clone(), got.clone()) == "String".to_string())); - (expected_is_optional_coproduct.clone() && got_is_string.clone()) - } -} - -pub fn bare_none_construction_wall_note() -> String { - thread_local! { - static CACHED: String = { - "CONSTRUCTION WALL (DESIGN 4b): the bare name `None` carries absence and NOTHING else, so a construction position whose declared field type cannot carry absence must refuse it rather than adopt whichever `None` variant happens to be in scope. MEASURED HOLE this closes, on the pre-wall binary: with `type Diags = None | Some { n: Int }` in scope, `Holder { n: None }` for `n: Int` and `ListHolder { xs: None }` for `xs: List` compiled with ZERO blocking diagnostics and emitted `n: Rc::new(Diags::None)` / `xs: Rc::new(Diags::None)` — a Rust program the declared types refute, produced silently. WHY THIS SLICE AND NOT THE GENERAL CONFORMANCE RULE: conformance_unjudged_live_hole_note records five successive attempts at a general named-vs-named refusal, each of which red correct code because the produced side carries no separable type identity. A bare `None` reference needs no produced-side identity — it is a SYNTACTIC form whose only meaning is absence — so admissibility is decided entirely from the DECLARED side, which is exactly why this class is decidable where the general one is not. ADMISSION is deliberately two-armed and nothing else: optional cardinality (the `T?` carrier), or a coproduct that declares a `None` variant at its own level (std.cache_interface AuthScope, v2.std.diagnostic Diagnostics — the two live carriers). A qualified `Owner.None` is not a bare reference and is not judged here. COVERAGE BOUNDARY, stated rather than left to be found: the wall fires only where the field s declared type is known at this site; a field whose declared type does not resolve is not judged, which is the check s precision frontier and not a failure arm.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn field_declared_type_is_identified(ft: Rc, scope: Rc) -> bool { - { - let required = match lookup_type_for( - scope.type_env.clone(), - with_required_cardinality(ft.clone()), - ) { - Some(resolved) => resolved.clone(), - None => with_required_cardinality(ft.clone()), - }; - (authored_name_at( - scope.type_env.clone().source_indices.clone(), - required.clone(), - ) != "".to_string()) - } -} - -pub fn field_type_admits_bare_none(ft: Rc, scope: Rc) -> bool { - { - let required = match lookup_type_for( - scope.type_env.clone(), - with_required_cardinality(ft.clone()), - ) { - Some(resolved) => resolved.clone(), - None => with_required_cardinality(ft.clone()), - }; - let expanded = - expand_scrut_type_for_variant_lookup(required.clone(), scope.type_env.clone()); - let declares_none_variant = ((expanded.connective.clone() == Connective::Disj) - && has_child_named( - expanded.clone(), - "None".to_string(), - scope.type_env.clone().source_indices.clone(), - )); - ((ft.return_cardinality.clone() == Cardinality::CardOptional) - || declares_none_variant.clone()) - } -} - -pub fn expr_is_bare_none_reference(texpr: Rc, scope: Rc) -> bool { - match (*texpr.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - (expr_var_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()) - == "None".to_string()) - } - _ => false, - } -} - -pub fn bare_none_field_construction_diags( - fi: Rc, - fi_name: String, - field_declared_type: Option>, - type_name_for_message: String, - scope: Rc, -) -> Rc>> { - match field_declared_type.clone() { - None => Rc::new(vec![]), - Some(ft) => { - let value_expr = field_init_node_value(fi.clone()); - if ((expr_is_bare_none_reference(value_expr.clone(), scope.clone()) - && field_declared_type_is_identified(ft.clone(), scope.clone())) - && (field_type_admits_bare_none(ft.clone(), scope.clone()) == false)) - { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::BareNoneNotAdmittedByFieldType { - field: fi_name.clone(), - type_name: type_name_for_message.clone(), - declared_type: node_type_shape( - ft.clone(), - scope.type_env.clone().source_indices.clone(), - ), - span: value_expr.span.clone(), - }), - scope.module_name.clone(), - )]) - } else { - Rc::new(vec![]) - } - } - } -} - -pub fn field_type_is_optional_coproduct(ft: Rc, env: Rc) -> bool { - { - let inner = match lookup_type_for(env.clone(), with_required_cardinality(ft.clone())) { - Some(resolved) => resolved.clone(), - None => with_required_cardinality(ft.clone()), - }; - ((ft.return_cardinality.clone() == Cardinality::CardOptional) - && (inner.connective.clone() == Connective::Disj)) - } -} - -pub fn record_lit_expected_fields( - type_name: Option, - scope: Rc, -) -> Rc>> { - match type_name.clone() { - Some(tn) => match lookup_type_by_name(scope.type_env.clone(), tn.clone()) { - Some(direct) => direct.children.clone(), - None => match variant_owner_node(scope.clone(), tn.clone()) { - Some(parent) => match Rc::new({ - let mut __result = Vec::new(); - for v in parent.children.clone().iter().cloned() { - if (authored_name_at( - scope.type_env.clone().source_indices.clone(), - v.clone(), - ) == tn.clone()) - { - __result.push(v); - } - } - __result - }) - .first() - .cloned() - { - Some(variant) => variant.children.clone(), - None => Rc::new(vec![]), - }, - None => Rc::new(vec![]), - }, - }, - None => Rc::new(vec![]), - } -} - -pub fn record_lit_expanded_from_expected( - type_name: Option, - expected: Option>, - scope: Rc, -) -> Option> { - match type_name.clone() { - Some(tn) => match expected.clone() { - Some(exp) => { - if (((authored_name_at( - scope.type_env.clone().source_indices.clone(), - exp.clone(), - ) == tn.clone()) - && (exp.connective.clone() == Connective::Conj)) - && ((exp.children.clone().len() as i64) > 0)) - { - Some(exp.clone()) - } else { - match exp.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: expanded, .. }) => { - if (authored_name_at( - scope.type_env.clone().source_indices.clone(), - expanded.clone(), - ) == tn.clone()) - { - Some(expanded.clone()) - } else { - None - } - } - _ => { - let rt = resolved_type(exp.clone()); - if (authored_name_at( - scope.type_env.clone().source_indices.clone(), - rt.clone(), - ) == tn.clone()) - { - Some(rt.clone()) - } else { - None - } - } - } - } - } - None => None, - }, - None => None, - } -} - -pub fn record_lit_expected_coproduct( - expected: Option>, - scope: Rc, -) -> Option> { - match expected.clone() { - Some(exp) => { - let resolved = match lookup_type_for(scope.type_env.clone(), exp.clone()) { - Some(r) => r.clone(), - None => exp.clone(), - }; - let nominal = if node_is_element_collection( - resolved.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - match resolved.children.clone().first().cloned() { - Some(elem) => { - let elem_ty = child_type_node(elem.clone()); - match lookup_type_for(scope.type_env.clone(), elem_ty.clone()) { - Some(r) => Some(r.clone()), - None => Some(elem_ty.clone()), - } - } - None => None, - } - } else { - Some(resolved.clone()) - }; - match nominal.clone() { - Some(n) => { - if (n.connective.clone() == Connective::Disj) { - Some(n.clone()) - } else { - None - } - } - None => None, - } - } - None => None, - } -} - -pub fn record_lit_parent_enum_from_expected( - type_name: String, - expected: Option>, - scope: Rc, -) -> Option { - match record_lit_variant_from_expected(Some(type_name.clone()), expected.clone(), scope.clone()) - { - Some(_) => match record_lit_expected_coproduct(expected.clone(), scope.clone()) { - Some(coproduct) => Some(authored_name_at( - scope.type_env.clone().source_indices.clone(), - coproduct.clone(), - )), - None => None, - }, - None => None, - } -} - -pub fn record_lit_variant_from_expected( - type_name: Option, - expected: Option>, - scope: Rc, -) -> Option> { - match type_name.clone() { - Some(tn) => match record_lit_expected_coproduct(expected.clone(), scope.clone()) { - Some(coproduct) => Rc::new({ - let mut __result = Vec::new(); - for v in coproduct.children.clone().iter().cloned() { - if (authored_name_at(scope.type_env.clone().source_indices.clone(), v.clone()) - == qualified_last_segment(tn.clone())) - { - __result.push(v); - } - } - __result - }) - .first() - .cloned(), - None => None, - }, - None => None, - } -} - -pub fn record_lit_fields_from_expected( - type_name: Option, - expected: Option>, - scope: Rc, -) -> Option>>> { - match record_lit_expanded_from_expected(type_name.clone(), expected.clone(), scope.clone()) { - Some(expanded) => { - if ((expanded.connective.clone() == Connective::Conj) - && ((expanded.children.clone().len() as i64) > 0)) - { - Some(expanded.children.clone()) - } else { - None - } - } - None => None, - } -} - - -pub fn field_declared_type_node(sf: Rc) -> Rc { - match sf.inferred.as_deref() { - Some(InferredNode::Resolved { node: rt }) => { - preserve_outer_optional_cardinality(sf.clone(), rt.clone()) - } - _ => field_node_type_expr(sf.clone()), - } -} - -pub fn record_lit_instantiated_fields( - type_name: Option, - expected: Option>, - scope: Rc, -) -> Option>>> { - match type_name.clone() { - Some(tn) => match expected.clone() { - Some(exp) => { - if (type_name_compatible( - authored_name_at(scope.type_env.clone().source_indices.clone(), exp.clone()), - tn.clone(), - ) == false) - { - None - } else { - if ((exp.children.clone().len() as i64) == 0) { - None - } else { - match lookup_type_for(scope.type_env.clone(), exp.clone()) { - Some(decl) => { - if ((decl.params.clone().len() as i64) - != (exp.children.clone().len() as i64)) - { - None - } else { - { - let subst = Rc::new(decl.params.clone().iter().cloned().enumerate().map(|(i, v)| (i as i64, v)).collect::>()).iter().cloned().fold(v1_rt::rc_empty_map::>(), |acc: Rc>>, pair: (i64, Rc)| { - let slot = authored_name_at(scope.type_env.clone().source_indices.clone(), pair.1.clone()); -match exp.children.clone().iter().cloned().skip(pair.0.clone() as usize).next() { - Some(arg) => v1_rt::rc_map_insert(acc.clone(), slot.clone(), resolved_type(arg.clone())), - None => acc.clone(), -} -}); - let template_fields = decl.children.clone(); - Some(Rc::new({ - let mut __result = Vec::new(); - for sf in template_fields.clone().iter().cloned() { - __result.push(Rc::new(Node { - name: sf.name.clone(), - span: sf.span.clone(), - ident_span: sf.ident_span.clone(), - children: sf.children.clone(), - connective: sf.connective.clone(), - params: sf.params.clone(), - inferred: Some(Rc::new( - InferredNode::Resolved { - node: substitute_generics( - field_declared_type_node(sf.clone()), - subst.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - ), - }, - )), - return_cardinality: sf - .return_cardinality - .clone(), - uses: sf.uses.clone(), - body: sf.body.clone(), - transport: sf.transport.clone(), - properties: sf.properties.clone(), - type_annotation: sf.type_annotation.clone(), - is_self_recursive: sf.is_self_recursive.clone(), - has_non_tail_self_call: sf - .has_non_tail_self_call - .clone(), - match_pattern: sf.match_pattern.clone(), - expr_data: sf.expr_data.clone(), - ident: None, - })); - } - __result - })) - } - } - } - None => None, - } - } - } - } - None => None, - }, - None => None, - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct KernelListTyDiag { - pub ty: Rc, - pub miss_diags: Rc>>, -} - -pub fn list_kernel_ty_from_element(element: Rc) -> Rc { - { - let b = make_container_type("List".to_string(), element.clone()); - Rc::new(KernelListTyDiag { - ty: b.ty.clone(), - miss_diags: b.diagnostics.clone(), - }) - } -} - -pub fn set_kernel_ty_from_element(element: Rc) -> Rc { - { - let b = make_container_type("Set".to_string(), element.clone()); - Rc::new(KernelListTyDiag { - ty: b.ty.clone(), - miss_diags: b.diagnostics.clone(), - }) - } -} - -pub fn set_builtin_receiver_is_set(receiver_arg: Rc, scope: Rc) -> bool { - match arg_value(receiver_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: receiver_type, - .. - }) => node_is_set_collection( - receiver_type.clone(), - scope.type_env.clone().source_indices.clone(), - ), - _ => false, - } -} - -pub fn set_union_other_operand_is_resolved_non_set( - other_arg: Rc, - scope: Rc, -) -> bool { - match arg_value(other_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: other_type, .. - }) => !node_is_set_collection( - other_type.clone(), - scope.type_env.clone().source_indices.clone(), - ), - _ => false, - } -} - -pub fn set_element_type_from_receiver( - receiver_type: Rc, - scope: Rc, -) -> Option> { - match set_element_type_in_env(receiver_type.clone(), scope.type_env.clone()) { - Some(elem_slot) => Some(child_type_node(elem_slot.clone())), - None => None, - } -} - -pub fn set_element_type_is_concrete(elem: Rc) -> bool { - match elem.inferred.clone() { - Some(inf) => !is_type_variable(inf.clone()), - None => true, - } -} - -pub fn set_element_types_mismatch( - recv_elem: Rc, - operand_elem: Rc, - source_indices: Rc>>, -) -> bool { - ((set_element_type_is_concrete(recv_elem.clone()) - && set_element_type_is_concrete(operand_elem.clone())) - && !node_type_compatible( - recv_elem.clone(), - operand_elem.clone(), - source_indices.clone(), - )) -} - -pub fn type_node_is_callable(n: Rc) -> bool { - ((n.params.clone().len() as i64) > 0) -} - -pub fn module_skips_direct_call_arg_check(module_name: String) -> bool { - ((v1_rt::string_length(&module_name) >= 3) - && (v1_rt::substring(&module_name, 0, 3) == "v2.".to_string())) -} - -pub fn brand_grounds_transparently_to( - name: String, - other: Rc, - type_env: Rc, - source_indices: Rc>>, -) -> bool { - match lookup_type_by_name(type_env.clone(), name.clone()) { - Some(resolved) => { - ((((resolved.connective.clone() == Connective::NoConnective) - && ((resolved.children.clone().len() as i64) == 0)) - && (resolved.inferred.clone() != None)) - && match resolved.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: target, .. }) => { - let target_name = authored_name_at(source_indices.clone(), target.clone()); - let other_name = authored_name_at(source_indices.clone(), other.clone()); - ((is_kernel_type(target_name.clone()) - && (target_name.clone() == other_name.clone())) - || (qualified_last_segment(target_name.clone()) - == qualified_last_segment(other_name.clone()))) - } - _ => false, - }) - } - None => false, - } -} - -pub fn nominal_call_arg_brand_mismatch( - formal: Rc, - actual: Rc, - type_env: Rc, - source_indices: Rc>>, -) -> bool { - { - let formal_name = authored_name_at(source_indices.clone(), formal.clone()); - let actual_name = authored_name_at(source_indices.clone(), actual.clone()); - ((((((((((formal.connective.clone() != Connective::Arrow) - && (actual.connective.clone() != Connective::Arrow)) - && (formal_name.clone() != "".to_string())) - && (actual_name.clone() != "".to_string())) - && (qualified_last_segment(formal_name.clone()) - != qualified_last_segment(actual_name.clone()))) - && (structural_carrier_template_name(formal.clone(), source_indices.clone()) - == structural_carrier_template_name(actual.clone(), source_indices.clone()))) - && !is_declared_container_alias_spelling(formal_name.clone())) - && !is_declared_container_alias_spelling(actual_name.clone())) - && !brand_grounds_transparently_to( - formal_name.clone(), - actual.clone(), - type_env.clone(), - source_indices.clone(), - )) - && !brand_grounds_transparently_to( - actual_name.clone(), - formal.clone(), - type_env.clone(), - source_indices.clone(), - )) - } -} - -pub fn is_where_refinement_type(ty: Rc) -> bool { - (((ty.connective.clone() == Connective::Conj) && (ty.type_annotation.clone() != None)) - && ((ty.children.clone().len() as i64) == 1)) -} - -pub fn where_refinement_chain(ty: Rc, type_env: Rc) -> Rc>> { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - if is_where_refinement_type(ty.clone()) { - match ty.children.clone().first().cloned() { - Some(base) => { - let base_resolved = match lookup_type_for(type_env.clone(), base.clone()) { - Some(resolved) => resolved.clone(), - None => base.clone(), - }; - v1_rt::concat( - Rc::new(vec![ty.clone()]), - where_refinement_chain(base_resolved.clone(), type_env.clone()), - ) - } - None => Rc::new(vec![ty.clone()]), - } - } else { - Rc::new(vec![ty.clone()]) - } - }) -} - -pub fn type_expr_where_refinement_predicates(ty: Rc) -> Rc>> { - if is_where_refinement_type(ty.clone()) { - match ty.type_annotation.clone() { - Some(annot) => match annot.connective.clone() { - Connective::Conj => annot.children.clone(), - _ => Rc::new(vec![annot.clone()]), - }, - None => Rc::new(vec![]), - } - } else { - Rc::new(vec![]) - } -} - -pub fn type_where_refinement_predicates_transitive( - ty: Rc, - type_env: Rc, -) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for link in where_refinement_chain(ty.clone(), type_env.clone()) - .iter() - .cloned() - { - __result.extend( - (*type_expr_where_refinement_predicates(link.clone())) - .iter() - .cloned(), - ); - } - __result - }) -} - -pub fn peel_where_refinement_base(ty: Rc, type_env: Rc) -> Rc { - match where_refinement_chain(ty.clone(), type_env.clone()) - .last() - .cloned() - { - Some(ground) => ground.clone(), - None => ty.clone(), - } -} - -pub fn where_predicate_name_at( - pred: Rc, - source_indices: Rc>>, -) -> String { - field_init_node_name_at(pred.clone(), source_indices.clone()) -} - -pub fn where_predicate_named_int_arg( - pred: Rc, - field: String, - source_indices: Rc>>, -) -> Option { - match record_lit_named_field_value_optional( - field_init_node_value(pred.clone()), - field.clone(), - source_indices.clone(), - ) { - Some(field_expr) => expr_literal_int_optional(field_expr.clone()), - None => None, - } -} - -pub fn where_predicate_canonical_name(pred_name: String) -> String { - if (pred_name.clone() == "brand".to_string()) { - "Brand".to_string() - } else { - pred_name.clone() - } -} - -pub fn where_predicate_optional_int_args_match( - left: Rc, - right: Rc, - source_indices: Rc>>, -) -> bool { - { - let min_ok = where_predicate_int_bound_args_equivalent( - left.clone(), - right.clone(), - "min".to_string(), - source_indices.clone(), - ); - let max_ok = where_predicate_int_bound_args_equivalent( - left.clone(), - right.clone(), - "max".to_string(), - source_indices.clone(), - ); - (min_ok.clone() && max_ok.clone()) - } -} - -pub fn where_predicate_int_bound_args_equivalent( - left: Rc, - right: Rc, - field: String, - source_indices: Rc>>, -) -> bool { - match record_lit_named_field_value_optional( - field_init_node_value(left.clone()), - field.clone(), - source_indices.clone(), - ) { - None => match record_lit_named_field_value_optional( - field_init_node_value(right.clone()), - field.clone(), - source_indices.clone(), - ) { - None => true, - Some(_) => false, - }, - Some(left_expr) => match record_lit_named_field_value_optional( - field_init_node_value(right.clone()), - field.clone(), - source_indices.clone(), - ) { - None => false, - Some(right_expr) => match expr_literal_int_optional(left_expr.clone()) { - Some(a) => match expr_literal_int_optional(right_expr.clone()) { - Some(b) => (a.clone() == b.clone()), - None => false, - }, - None => false, - }, - }, - } -} - -pub fn where_predicate_literal_string_args_match(left: Rc, right: Rc) -> bool { - match expr_literal_string_optional(field_init_node_value(left.clone())) { - Some(a) => match expr_literal_string_optional(field_init_node_value(right.clone())) { - Some(b) => (a.clone() == b.clone()), - None => false, - }, - None => match expr_literal_string_optional(field_init_node_value(right.clone())) { - Some(_) => false, - None => true, - }, - } -} - -pub fn where_refinement_predicates_equivalent( - formal_pred: Rc, - actual_pred: Rc, - source_indices: Rc>>, -) -> bool { - { - let formal_name = where_predicate_canonical_name(where_predicate_name_at( - formal_pred.clone(), - source_indices.clone(), - )); - let actual_name = where_predicate_canonical_name(where_predicate_name_at( - actual_pred.clone(), - source_indices.clone(), - )); - if (formal_name.clone() != actual_name.clone()) { - false - } else { - if (formal_name.clone() == "range".to_string()) { - where_predicate_optional_int_args_match( - formal_pred.clone(), - actual_pred.clone(), - source_indices.clone(), - ) - } else { - if (((((formal_name.clone() == "Brand".to_string()) - || (formal_name.clone() == "Pattern".to_string())) - || (formal_name.clone() == "Format".to_string())) - || (formal_name.clone() == "ContentEncoding".to_string())) - || (formal_name.clone() == "Domain".to_string())) - { - where_predicate_literal_string_args_match( - formal_pred.clone(), - actual_pred.clone(), - ) - } else { - true - } - } - } - } -} - -pub fn where_refinement_min_length_implication_note() -> String { - thread_local! { - static CACHED: String = { - "THE FRAGMENT IS TWO PARTIAL FUNCTIONS, NOT AN IMPLICATION ENGINE, and the asymmetry between them is the entire soundness argument. Predicate implication in general is undecidable, so this decides exactly one relation and refuses outside it: a value whose refinement GUARANTEES a minimum length satisfies a formal position whose refinement DEMANDS a minimum length AND NOTHING ELSE. Provider and demander are separate partial functions over the same closed predicate vocabulary because a predicate can inhabit one side and not the other, and collapsing them into one min-length table is a FAIL-OPEN that the obvious framing walks straight into: model lower_hex_64 as min-length 64 on both sides and a formal lower_hex_64 is then satisfied by an actual lower_hex_128, since 128 >= 64 — but those predicates demand DIFFERENT EXACT LENGTHS and a 128-digit string is not a valid sha256 hex. lower_hex_N therefore appears as a PROVIDER only (it guarantees exactly N lower-hex digits, hence at least N characters) and never as a demander (it demands an exact length and a charset, neither of which a length lower bound establishes). non_empty is the only predicate in the live vocabulary that is a pure length lower bound, so it is the only demander, and it is a provider too because it demands what it guarantees. Everything outside both tables answers Absent and the caller falls through to the pre-existing name-equality path unchanged, so this widens what the wall can DECIDE and narrows nothing it already decided. oci_other_digest_algorithm and oci_other_digest_encoded are deliberately NOT providers even though their grammars happen to exclude the empty string: that fact lives in oci_digest_algorithm_wire_holds / oci_encoded_digest_syntax_valid as a consequence of a syntax walk, not as a declared constant this table could cite, and asserting a bound the predicate does not state is the fabrication DESIGN §5 forbids. The four lower_hex_N bounds ARE declared constants — each is content_hash_validate_lower_hex_length(text, expected_hex_digits: N), whose body is text.length() == N — so the number in this table is the number in the predicate, cited rather than restated. WHY THIS IS A WALL AND NOT A WIDENING: the two corpus sites it closes (std.content_hash serialize_content_hash, `s.digest as NonEmptyStr` over Fnv1a64StructuralDigestHex and `d.hex as NonEmptyStr` over Sha1DigestHex) were carrying WhereRefinementUnenforced advisories for REFUSED evidence, not absent evidence — the value's own declared type already proved the property and where_refinement_predicates_equivalent could not see it because it compares predicate NAMES for equality, and lower_hex_40 != non_empty. WHAT IS NOT STRUCTURAL, STATED AT ITS HONEST RUNG (§4b) BECAUSE A TABLE PAIR WHOSE SOUNDNESS LIVES IN PROSE DECAYS SILENTLY: nothing prevents a predicate from being enrolled in BOTH tables, and membership in both is NOT the fail-open — non_empty is deliberately in both and is sound there, because it demands exactly what it guarantees. The real enrollment condition is narrower: a predicate may take a REQUIRED row only if its entire semantics is a length lower bound and nothing else. lower_hex_64 in both tables would be unsound not because it appears twice but because it demands an exact length and a charset that a lower bound does not establish. That condition is enforced by nobody: these are two hand-written name-keyed partial functions, so a future demander row asserting more than length would fail open and no check would fire. The decided relation guaranteed >= required is mechanically enforced; the authoring discipline that populates the demander table is DILIGENCE, rung MITIGATABLE, and it is contained only by the vocabulary being closed and small. Next-rung trigger is the same dissolve-on below: once the bounds are fields on WhereRefinementPredicateKind's own declaration, a predicate states its guarantee and its demand once and the mis-enrollment has no place to be written. Dissolve-on: feature:where-refinement-predicate-coproduct — when WhereRefinementPredicateKind replaces the string classifiers, the guaranteed and required bounds become fields on the predicate's own declaration rather than two tables a reader must keep in lockstep with where_refinement_is_string_literal_predicate and decidable_where_string_predicate_holds.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn where_predicate_guaranteed_min_length(pred_name: String) -> Option { - if (pred_name.clone() == "non_empty".to_string()) { - Some(1) - } else { - if (pred_name.clone() == "lower_hex_16".to_string()) { - Some(16) - } else { - if (pred_name.clone() == "lower_hex_40".to_string()) { - Some(40) - } else { - if (pred_name.clone() == "lower_hex_64".to_string()) { - Some(64) - } else { - if (pred_name.clone() == "lower_hex_128".to_string()) { - Some(128) - } else { - None - } - } - } - } - } -} - -pub fn where_predicate_required_min_length(pred_name: String) -> Option { - if (pred_name.clone() == "non_empty".to_string()) { - Some(1) - } else { - None - } -} - -pub fn where_refinement_predicate_min_length_implies( - formal_pred: Rc, - actual_pred: Rc, - source_indices: Rc>>, -) -> bool { - match where_predicate_required_min_length(where_predicate_canonical_name( - where_predicate_name_at(formal_pred.clone(), source_indices.clone()), - )) { - Some(required) => { - match where_predicate_guaranteed_min_length(where_predicate_canonical_name( - where_predicate_name_at(actual_pred.clone(), source_indices.clone()), - )) { - Some(guaranteed) => (guaranteed.clone() >= required.clone()), - None => false, - } - } - None => false, - } -} - -pub fn where_refinement_predicate_satisfied_by( - formal_pred: Rc, - actual_pred: Rc, - source_indices: Rc>>, -) -> bool { - (where_refinement_predicates_equivalent( - formal_pred.clone(), - actual_pred.clone(), - source_indices.clone(), - ) || where_refinement_predicate_min_length_implies( - formal_pred.clone(), - actual_pred.clone(), - source_indices.clone(), - )) -} - -pub fn where_refinement_predicates_covered( - formal_preds: Rc>>, - actual_preds: Rc>>, - source_indices: Rc>>, -) -> bool { - { - let mut __all = true; - for fp in formal_preds.clone().iter().cloned() { - if !({ - let mut __found = false; - for ap in actual_preds.clone().iter().cloned() { - if where_refinement_predicate_satisfied_by( - fp.clone(), - ap.clone(), - source_indices.clone(), - ) { - __found = true; - break; - } - } - __found - }) { - __all = false; - break; - } - } - __all - } -} - -pub fn decidable_where_int_predicate_holds( - pred_name: String, - pred: Rc, - value: i64, - source_indices: Rc>>, -) -> Option { - if (pred_name.clone() == "gt_zero".to_string()) { - Some((value.clone() > 0)) - } else { - if (pred_name.clone() == "range".to_string()) { - { - let passes_min = match record_lit_named_field_value_optional( - field_init_node_value(pred.clone()), - "min".to_string(), - source_indices.clone(), - ) { - None => Some(true), - Some(field_expr) => match expr_literal_int_optional(field_expr.clone()) { - Some(lo) => Some((value.clone() >= lo.clone())), - None => None, - }, - }; - let passes_max = match record_lit_named_field_value_optional( - field_init_node_value(pred.clone()), - "max".to_string(), - source_indices.clone(), - ) { - None => Some(true), - Some(field_expr) => match expr_literal_int_optional(field_expr.clone()) { - Some(hi) => Some((value.clone() <= hi.clone())), - None => None, - }, - }; - match passes_min.clone() { - Some(min_ok) => match passes_max.clone() { - Some(max_ok) => Some((min_ok.clone() && max_ok.clone())), - None => None, - }, - None => None, - } - } - } else { - None - } - } -} - -pub fn where_refinement_predicate_kind_scaffold_note() -> String { - thread_local! { - static CACHED: String = { - "owner: v1.compiler.infer. lane: where_refinement_diags_for_predicate dispatch. interim: predicate kind routed via where_refinement_is_*_literal_predicate / where_refinement_is_deferred_predicate closed string sets — must stay in lockstep with decidable_*_predicate_holds and where_refinement_predicates_equivalent. bound: vocabulary changes require updating all classifier fns + eval + equivalence arms in one commit. dissolve-on: feature:where-refinement-predicate-coproduct (WhereRefinementPredicateKind coproduct replacing string classifiers).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn where_refinement_is_int_literal_predicate(pred_name: String) -> bool { - ((pred_name.clone() == "gt_zero".to_string()) || (pred_name.clone() == "range".to_string())) -} - -pub fn where_refinement_is_string_literal_predicate(pred_name: String) -> bool { - (((((((pred_name.clone() == "non_empty".to_string()) - || (pred_name.clone() == "lower_hex_64".to_string())) - || (pred_name.clone() == "lower_hex_40".to_string())) - || (pred_name.clone() == "lower_hex_128".to_string())) - || (pred_name.clone() == "lower_hex_16".to_string())) - || (pred_name.clone() == "oci_other_digest_algorithm".to_string())) - || (pred_name.clone() == "oci_other_digest_encoded".to_string())) -} - -pub fn where_refinement_is_deferred_predicate(pred_name: String) -> bool { - ((((((((pred_name.clone() == "brand".to_string()) - || (pred_name.clone() == "Brand".to_string())) - || (pred_name.clone() == "unicode_scalar".to_string())) - || (pred_name.clone() == "is_text_readable".to_string())) - || (pred_name.clone() == "Pattern".to_string())) - || (pred_name.clone() == "Format".to_string())) - || (pred_name.clone() == "ContentEncoding".to_string())) - || (pred_name.clone() == "Domain".to_string())) -} - -pub fn decidable_where_string_predicate_holds(pred_name: String, value: String) -> Option { - if (pred_name.clone() == "non_empty".to_string()) { - Some((v1_rt::string_length(&value) > 0)) - } else { - if (pred_name.clone() == "lower_hex_64".to_string()) { - Some(content_hash_validate_lower_hex_length(value.clone(), 64)) - } else { - if (pred_name.clone() == "lower_hex_40".to_string()) { - Some(content_hash_validate_lower_hex_length(value.clone(), 40)) - } else { - if (pred_name.clone() == "lower_hex_128".to_string()) { - Some(content_hash_validate_lower_hex_length(value.clone(), 128)) - } else { - if (pred_name.clone() == "lower_hex_16".to_string()) { - Some(content_hash_validate_lower_hex_length(value.clone(), 16)) - } else { - if (pred_name.clone() == "oci_other_digest_algorithm".to_string()) { - Some(oci_other_digest_algorithm(value.clone())) - } else { - if (pred_name.clone() == "oci_other_digest_encoded".to_string()) { - Some(oci_other_digest_encoded(value.clone())) - } else { - None - } - } - } - } - } - } - } -} - -pub fn where_predicate_range_non_literal_bound_reason( - pred: Rc, - source_indices: Rc>>, -) -> Option { - match record_lit_named_field_value_optional( - field_init_node_value(pred.clone()), - "min".to_string(), - source_indices.clone(), - ) { - Some(min_expr) => match expr_literal_int_optional(min_expr.clone()) { - Some(_) => match record_lit_named_field_value_optional( - field_init_node_value(pred.clone()), - "max".to_string(), - source_indices.clone(), - ) { - Some(max_expr) => match expr_literal_int_optional(max_expr.clone()) { - Some(_) => None, - None => Some("predicate argument is not an int literal".to_string()), - }, - None => None, - }, - None => Some("predicate argument is not an int literal".to_string()), - }, - None => match record_lit_named_field_value_optional( - field_init_node_value(pred.clone()), - "max".to_string(), - source_indices.clone(), - ) { - Some(max_expr) => match expr_literal_int_optional(max_expr.clone()) { - Some(_) => None, - None => Some("predicate argument is not an int literal".to_string()), - }, - None => None, - }, - } -} - -pub fn where_refinement_unenforced_error( - predicate: String, - formal: Rc, - reason: String, - span: Rc, - module_name: String, - source_indices: Rc>>, -) -> Rc { - make_error_node( - Rc::new(CompilerDiagnostic::WhereRefinementUnenforced { - predicate: predicate.clone(), - formal_type: node_type_shape(formal.clone(), source_indices.clone()), - reason: reason.clone(), - span: span.clone(), - }), - module_name.clone(), - ) -} - -pub fn where_refinement_diags_for_predicate( - pred: Rc, - formal: Rc, - value_expr: Rc, - span: Rc, - module_name: String, - source_indices: Rc>>, -) -> Rc>> { - { - let pname = field_init_node_name_at(pred.clone(), source_indices.clone()); - let refinement_refusal = Rc::new(vec![type_mismatch_error( - node_type_shape(formal.clone(), source_indices.clone()), - node_type_shape(resolved_type(value_expr.clone()), source_indices.clone()), - span.clone(), - module_name.clone(), - )]); - if where_refinement_is_int_literal_predicate(pname.clone()) { - match expr_literal_int_optional(value_expr.clone()) { - Some(v) => match decidable_where_int_predicate_holds( - pname.clone(), - pred.clone(), - v.clone(), - source_indices.clone(), - ) { - Some(holds) => { - if !holds.clone() { - refinement_refusal - } else { - Rc::new(vec![]) - } - } - None => { - if (pname.clone() == "range".to_string()) { - match where_predicate_range_non_literal_bound_reason( - pred.clone(), - source_indices.clone(), - ) { - Some(reason) => Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - reason.clone(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]), - None => Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "int predicate not implemented".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]), - } - } else { - Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "int predicate not implemented".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]) - } - } - }, - None => { - if expr_is_any_literal(value_expr.clone()) { - refinement_refusal - } else { - Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "non-literal value at refined position".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]) - } - } - } - } else { - if where_refinement_is_string_literal_predicate(pname.clone()) { - { - let string_literal_value = - match expr_literal_string_optional(value_expr.clone()) { - Some(v) => Some(v.clone()), - None => expr_literal_symbol_optional(value_expr.clone()), - }; - match string_literal_value.clone() { - Some(v) => { - match decidable_where_string_predicate_holds(pname.clone(), v.clone()) { - Some(holds) => { - if !holds.clone() { - refinement_refusal - } else { - Rc::new(vec![]) - } - } - None => Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "string predicate not implemented".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]), - } - } - None => { - if expr_is_any_literal(value_expr.clone()) { - refinement_refusal - } else { - Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "non-literal value at refined position".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]) - } - } - } - } - } else { - if where_refinement_is_deferred_predicate(pname.clone()) { - Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "predicate deferred at compile time".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]) - } else { - Rc::new(vec![where_refinement_unenforced_error( - pname.clone(), - formal.clone(), - "predicate not enforced at compile time".to_string(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )]) - } - } - } - } -} - -pub fn where_refinement_value_under_cast(mut value_expr: Rc) -> Rc { - loop { - match (*value_expr.expr_data.clone()).clone() { - ExprData::ExprCast => { - let __tco_0 = cast_expr(value_expr); - value_expr = __tco_0; - continue; - } - _ => { - break value_expr.clone(); - } - } - } -} - -pub fn where_refinement_peel_cost_note() -> String { - thread_local! { - static CACHED: String = { - "Cost shape (bare-minimum-cost, DESIGN 6): peel_nominal_alias_identity runs only on the refusal path (predicates present AND not covered), inside the final else of where_refinement_mismatch_diags. That fn runs on EVERY infer_expr with an expected type; 97% of calls find zero predicates, and an eager peel at fn entry was 6.5s of discarded resolve_node_bounded work per host_effect_realize entry compile (typecheck-perf investigation, 2026-07-31). formal_checked is consumed only by where_refinement_diags_for_predicate, so the sink is behavior-identical: peel is pure and its NodeResolveResult diagnostics were already discarded.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn where_refinement_mismatch_diags( - formal: Rc, - value_expr: Rc, - span: Rc, - module_name: String, - type_env: Rc, -) -> Rc>> { - { - let source_indices = type_env.source_indices.clone(); - let formal_resolved = match lookup_type_for(type_env.clone(), formal.clone()) { - Some(resolved) => resolved.clone(), - None => formal.clone(), - }; - let preds = - type_where_refinement_predicates_transitive(formal_resolved.clone(), type_env.clone()); - if ((preds.clone().len() as i64) == 0) { - Rc::new(vec![]) - } else { - { - let value_for_refinement = where_refinement_value_under_cast(value_expr.clone()); - let actual_raw = resolved_type(value_for_refinement.clone()); - let actual_resolved = match lookup_type_for(type_env.clone(), actual_raw.clone()) { - Some(resolved) => resolved.clone(), - None => actual_raw.clone(), - }; - let actual_preds = type_where_refinement_predicates_transitive( - actual_resolved.clone(), - type_env.clone(), - ); - if where_refinement_predicates_covered( - preds.clone(), - actual_preds.clone(), - source_indices.clone(), - ) { - Rc::new(vec![]) - } else { - { - let formal_checked = peel_nominal_alias_identity( - formal_resolved.clone(), - type_env.clone(), - module_name.clone(), - ); - Rc::new({ - let mut __result = Vec::new(); - for pred in preds.clone().iter().cloned() { - __result.extend( - (*where_refinement_diags_for_predicate( - pred.clone(), - formal_checked.clone(), - value_for_refinement.clone(), - span.clone(), - module_name.clone(), - source_indices.clone(), - )) - .iter() - .cloned(), - ); - } - __result - }) - } - } - } - } - } -} - -pub fn with_expected_where_refinement_diags( - result: Rc, - expected: Option>, - scope: Rc, -) -> Rc { - match expected.clone() { - Some(expected_ty) => match (*result.typed.clone().expr_data.clone()).clone() { - ExprData::ExprCast => result.clone(), - _ => Rc::new(InferResult { - typed: result.typed.clone(), - diagnostics: v1_rt::concat( - result.diagnostics.clone(), - where_refinement_mismatch_diags( - expected_ty.clone(), - result.typed.clone(), - result.typed.clone().span.clone(), - scope.module_name.clone(), - scope.type_env.clone(), - ), - ), - }), - }, - None => result.clone(), - } -} - -pub fn infer_expr( - texpr: Rc, - scope: Rc, - expected: Option>, -) -> Rc { - with_expected_where_refinement_diags( - infer_expr_body(texpr.clone(), scope.clone(), expected.clone()), - expected.clone(), - scope.clone(), - ) -} - -pub fn kernel_value_declared_type_mismatch( - formal: Rc, - actual: Rc, - type_env: Rc, - source_indices: Rc>>, -) -> bool { - if (((formal.connective.clone() == Connective::Arrow) - || (actual.connective.clone() == Connective::Arrow)) - || ((actual.children.clone().len() as i64) > 0)) - { - false - } else { - { - let formal_base = peel_where_refinement_base(formal.clone(), type_env.clone()); - let actual_name = authored_name_at(source_indices.clone(), actual.clone()); - if ((is_kernel_type(actual_name.clone()) == false) - || (actual_name.clone() == "Unit".to_string())) - { - false - } else { - { - let formal_name = authored_name_at(source_indices.clone(), formal_base.clone()); - if (((formal_name.clone() == "".to_string()) - || (qualified_last_segment(formal_name.clone()) - == qualified_last_segment(actual_name.clone()))) - || dag_can_cast(actual_name.clone(), formal_name.clone())) - { - false - } else { - if (structural_carrier_template_name( - formal_base.clone(), - source_indices.clone(), - ) == structural_carrier_template_name( - actual.clone(), - source_indices.clone(), - )) { - false - } else { - if is_kernel_type(formal_name.clone()) { - true - } else { - match lookup_type_by_name(type_env.clone(), formal_name.clone()) { - Some(decl) => { - let decl_is_refinement_over_actual = - (((decl.connective.clone() == Connective::Conj) - && ((decl.children.clone().len() as i64) == 1)) - && ((decl.type_annotation.clone() != None) - || match decl.children.clone().first().cloned() - { - Some(refinement_child) => { - (authored_name_at( - source_indices.clone(), - refinement_child.clone(), - ) == actual_name.clone()) - } - None => false, - })); - ((((decl.connective.clone() == Connective::Conj) - || (decl.connective.clone() == Connective::Disj)) - && ((decl.children.clone().len() as i64) > 0)) - && (decl_is_refinement_over_actual.clone() == false)) - } - None => false, - } - } - } - } - } - } - } - } -} - -pub fn application_type_name_identity( - type_name: String, - type_env: Rc, - module_name: String, - source_indices: Rc>>, -) -> String { - match lookup_type_by_name(type_env.clone(), type_name.clone()) { - Some(decl) => match decl.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: target, .. }) => authored_name_at( - source_indices.clone(), - peel_nominal_alias_identity(target.clone(), type_env.clone(), module_name.clone()), - ), - _ => authored_name_at( - source_indices.clone(), - peel_nominal_alias_identity(decl.clone(), type_env.clone(), module_name.clone()), - ), - }, - None => type_name.clone(), - } -} - -pub fn structured_application_structural_type_name( - type_name: String, - scope: Rc, -) -> String { - application_type_name_identity( - type_name.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - scope.type_env.clone().source_indices.clone(), - ) -} - -pub fn structured_application_record_lit_nominal_name( - lit_name: String, - scope: Rc, -) -> String { - structured_application_structural_type_name(lit_name.clone(), scope.clone()) -} - -pub fn structured_application_lit_is_declared_optional_variant( - formal: Rc, - lit_name: String, - scope: Rc, -) -> bool { - { - let source_indices = scope.type_env.clone().source_indices.clone(); - let formal_resolved = match lookup_type_for( - scope.type_env.clone(), - with_required_cardinality(formal.clone()), - ) { - Some(resolved) => resolved.clone(), - None => with_required_cardinality(formal.clone()), - }; - if ((formal.return_cardinality.clone() == Cardinality::CardOptional) - && ((lit_name.clone() == "Present".to_string()) - || (lit_name.clone() == "Absent".to_string()))) - { - true - } else { - has_child_named( - formal_resolved.clone(), - lit_name.clone(), - source_indices.clone(), - ) - } - } -} - -pub fn application_type_names_compatible( - formal_name: String, - lit_name: String, - type_env: Rc, - module_name: String, - source_indices: Rc>>, -) -> bool { - if ((formal_name.clone() == "".to_string()) || (lit_name.clone() == "".to_string())) { - (formal_name.clone() == lit_name.clone()) - } else { - if (formal_name.clone() == lit_name.clone()) { - true - } else { - { - let formal_identity = application_type_name_identity( - formal_name.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ); - let lit_identity = application_type_name_identity( - lit_name.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ); - if (formal_identity.clone() == lit_identity.clone()) { - true - } else { - if dag_can_cast(lit_name.clone(), formal_name.clone()) { - true - } else { - if (type_name_transparently_aliases_to( - lit_name.clone(), - formal_name.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ) || type_name_transparently_aliases_to( - formal_name.clone(), - lit_name.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - )) { - true - } else { - match lookup_type_by_name(type_env.clone(), formal_name.clone()) { - Some(formal_decl) => brand_grounds_transparently_to( - lit_name.clone(), - formal_decl.clone(), - type_env.clone(), - source_indices.clone(), - ), - None => false, - } - } - } - } - } - } - } -} - -pub fn type_name_transparently_aliases_to( - mut alias_name: String, - mut target_name: String, - mut type_env: Rc, - mut module_name: String, - mut source_indices: Rc>>, -) -> bool { - loop { - match lookup_type_by_name(type_env.clone(), alias_name.clone()) { - Some(decl) => { - let peeled = peel_nominal_alias_identity( - decl.clone(), - type_env.clone(), - module_name.clone(), - ); - let peeled_name = authored_name_at(source_indices.clone(), peeled.clone()); - if (peeled_name.clone() == alias_name.clone()) { - break false; - } else { - if (peeled_name.clone() == target_name.clone()) { - break true; - } else { - { - let __tco_0 = peeled_name.clone(); - alias_name = __tco_0; - continue; - } - } - } - } - None => { - break false; - } - } - } -} - -pub fn structured_application_site_type_mismatch( - formal: Rc, - actual_expr: Rc, - scope: Rc, -) -> bool { - match (*actual_expr.expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => { - structured_application_site_type_mismatch_with_peeled( - formal.clone(), - peel_nominal_alias_identity( - formal.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ), - actual_expr.clone(), - scope.clone(), - ) - } - _ => false, - } -} - -pub fn structured_application_site_type_mismatch_with_peeled( - formal: Rc, - formal_peeled: Rc, - actual_expr: Rc, - scope: Rc, -) -> bool { - match (*actual_expr.expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => { - let source_indices = scope.type_env.clone().source_indices.clone(); - if type_node_is_callable(formal_peeled.clone()) { - false - } else { - { - let formal_name = - authored_name_at(source_indices.clone(), formal_peeled.clone()); - if (formal_name.clone() == "".to_string()) { - false - } else { - { - let formal_structural = structured_application_structural_type_name( - formal_name.clone(), - scope.clone(), - ); - match record_lit_type_name_at( - actual_expr.clone(), - source_indices.clone(), - ) { - Some(lit_name) => { - if application_type_names_compatible( - formal_name.clone(), - lit_name.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - source_indices.clone(), - ) { - false - } else { - { - let lit_nominal = - structured_application_record_lit_nominal_name( - lit_name.clone(), - scope.clone(), - ); - if ((lit_name.clone() == "".to_string()) || structured_application_lit_is_declared_optional_variant(formal.clone(), lit_name.clone(), scope.clone())) { - false - } else { - if match record_lit_alias_struct_expansion(lit_name.clone(), scope.clone()) { - Some(expansion) => { - let expanded_name = authored_name_at(source_indices.clone(), expansion.resolved.clone()); -((expanded_name.clone() == formal_structural.clone()) || application_type_names_compatible(formal_structural.clone(), expanded_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) -}, - None => false, -} { - false - } else { - if brand_grounds_transparently_to(lit_name.clone(), formal_peeled.clone(), scope.type_env.clone(), source_indices.clone()) { - false - } else { - if ((((formal_structural.clone() == lit_nominal.clone()) || (formal_structural.clone() == lit_name.clone())) || application_type_names_compatible(formal_structural.clone(), lit_nominal.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) || application_type_names_compatible(formal_structural.clone(), lit_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) { - false - } else { - { - let formal_decl = match lookup_type_for(scope.type_env.clone(), with_required_cardinality(formal_peeled.clone())) { - Some(resolved) => Some(resolved.clone()), - None => lookup_type_by_name(scope.type_env.clone(), formal_name.clone()), -}; -match formal_decl.clone() { - Some(decl) => match decl.connective.clone() { - Connective::Disj => if has_child_named(decl.clone(), lit_name.clone(), source_indices.clone()) { - false - } else { - match variant_owner_node(scope.clone(), lit_name.clone()) { - Some(owner) => { - let owner_name = authored_name_at(source_indices.clone(), owner.clone()); -!application_type_names_compatible(formal_name.clone(), owner_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone()) -}, - None => true, -} - }, - Connective::Conj => { - let decl_name = structured_application_structural_type_name(authored_name_at(source_indices.clone(), decl.clone()), scope.clone()); -(!application_type_names_compatible(decl_name.clone(), lit_nominal.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone()) && !application_type_names_compatible(decl_name.clone(), lit_name.clone(), scope.type_env.clone(), scope.module_name.clone(), source_indices.clone())) -}, - _ => false, -}, - None => if is_kernel_type(formal_name.clone()) { - match lookup_type_by_name(scope.type_env.clone(), lit_name.clone()) { - Some(lit_decl) => ((lit_decl.connective.clone() == Connective::Conj) || (lit_decl.connective.clone() == Connective::Disj)), - None => match variant_owner_node(scope.clone(), lit_name.clone()) { - Some(_) => true, - None => false, -}, -} - } else { - if ((lookup_type_by_name(scope.type_env.clone(), lit_name.clone()) != None) && (lookup_type_by_name(scope.type_env.clone(), formal_name.clone()) != None)) { - true - } else { - false - } - }, -} -} - } - } - } - } - } - } - } - None => false, - } - } - } - } - } - } - _ => false, - } -} - -pub fn direct_call_structured_record_literal_resolved_type_mismatch( - formal: Rc, - actual_expr: Rc, - type_env: Rc, - module_name: String, - source_indices: Rc>>, -) -> bool { - match (*actual_expr.expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => { - let formal_peeled = - peel_nominal_alias_identity(formal.clone(), type_env.clone(), module_name.clone()); - let formal_name = authored_name_at(source_indices.clone(), formal_peeled.clone()); - match record_lit_type_name_at(actual_expr.clone(), source_indices.clone()) { - Some(lit_name) => { - if application_type_names_compatible( - formal_name.clone(), - lit_name.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ) { - false - } else { - { - let actual_raw = resolved_type(actual_expr.clone()); - let actual = peel_nominal_alias_identity( - actual_raw.clone(), - type_env.clone(), - module_name.clone(), - ); - direct_call_arg_type_mismatch( - formal.clone(), - actual.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ) - } - } - } - None => { - let actual_raw = resolved_type(actual_expr.clone()); - let actual = peel_nominal_alias_identity( - actual_raw.clone(), - type_env.clone(), - module_name.clone(), - ); - direct_call_arg_type_mismatch( - formal.clone(), - actual.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ) - } - } - } - _ => false, - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct CallFormalApplication { - pub index: i64, - pub param_name: String, - pub formal_subst: Rc, - pub formal: Rc, - pub matched_arg: Option>, -} - -pub fn call_application_plan_note() -> String { - thread_local! { - static CACHED: String = { - "Cost shape (DESIGN §6 bare-minimum-cost) and single authority (§3). direct_call_arg_mismatch_diags and direct_call_structured_application_mismatch_diags were line-for-line duplicates of the same per-formal prologue: param_node_type_expr, substitute_generics, peel_nominal_alias_identity, authored_name_at, and the named-then-positional actual search. Both run over the SAME value_params, typed_args and call_subst at the one direct-call seam, so every formal was canonicalized twice per call. peel_nominal_alias_identity is resolve_node_bounded, an unmemoized recursive rebuild allocating a fresh Node per level, and it measured as the ENTIRE cost of the conformance seam: on gunbc.host_effect_realize the two timed peels inside direct_call_arg_mismatch_diags accounted for that function to within instrument overhead (62719ms + 62804ms against 125438ms over 330 calls), while the timer around direct_call_arg_type_mismatch never entered the top fourteen operations and substitute_generics already short-circuits an empty substitution. That module holds 63% of all corpus type inference. Building the binding ONCE and passing it to both consumers is the deduplication, not a cache: no map is introduced, so nothing here becomes an order-exposing operation in the v2.std.determinism denominator. Behavior is identical because every recomputed term is a pure function of arguments both callers already share.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn build_call_application_plan( - value_params: Rc>>, - typed_args: Rc>>, - call_subst: Rc>>, - type_env: Rc, - module_name: String, -) -> Rc>> { - { - let source_indices = type_env.source_indices.clone(); - Rc::new({ - let mut __result = Vec::new(); - for pair in Rc::new( - value_params - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.push({ - let formal_raw = param_node_type_expr(pair.1.clone()); - let formal_subst = substitute_generics( - formal_raw.clone(), - call_subst.clone(), - source_indices.clone(), - ); - let param_name = authored_name_at(source_indices.clone(), pair.1.clone()); - Rc::new(CallFormalApplication { - index: pair.0.clone(), - param_name: param_name.clone(), - formal_subst: formal_subst.clone(), - formal: peel_nominal_alias_identity( - formal_subst.clone(), - type_env.clone(), - module_name.clone(), - ), - matched_arg: match Rc::new({ - let mut __result = Vec::new(); - for ta in typed_args.clone().iter().cloned() { - if arg_has_name( - ta.clone(), - param_name.clone(), - source_indices.clone(), - ) { - __result.push(ta); - } - } - __result - }) - .first() - .cloned() - { - Some(named_ta) => Some(named_ta.clone()), - None => typed_args - .clone() - .iter() - .cloned() - .skip(pair.0.clone() as usize) - .next(), - }, - }) - }); - } - __result - }) - } -} - -pub fn direct_call_structured_application_mismatch_diags( - plan: Rc>>, - scope: Rc, -) -> Rc>> { - { - let type_env = scope.type_env.clone(); - let module_name = scope.module_name.clone(); - let source_indices = type_env.source_indices.clone(); - Rc::new({ - let mut __result = Vec::new(); - for app in plan.clone().iter().cloned() { - __result.extend( - (*{ - let formal_subst = app.formal_subst.clone(); - let formal = app.formal.clone(); - match app.matched_arg.clone() { - Some(ta) => { - let actual_expr = arg_value(ta.clone()); - if (structured_application_site_type_mismatch_with_peeled( - formal_subst.clone(), - formal.clone(), - actual_expr.clone(), - scope.clone(), - ) - || direct_call_structured_record_literal_resolved_type_mismatch( - formal.clone(), - actual_expr.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - )) - { - { - let actual_raw = resolved_type(actual_expr.clone()); - let actual = peel_nominal_alias_identity( - actual_raw.clone(), - type_env.clone(), - module_name.clone(), - ); - Rc::new(vec![type_mismatch_error( - node_type_shape(formal.clone(), source_indices.clone()), - node_type_shape(actual.clone(), source_indices.clone()), - actual_expr.span.clone(), - module_name.clone(), - )]) - } - } else { - Rc::new(vec![]) - } - } - None => Rc::new(vec![]), - } - }) - .iter() - .cloned(), - ); - } - __result - }) - } -} - -pub fn container_element_nominal_brand_mismatch( - formal: Rc, - actual: Rc, - type_env: Rc, - module_name: String, - source_indices: Rc>>, -) -> bool { - if ((node_is_element_collection(formal.clone(), source_indices.clone()) - && node_is_element_collection(actual.clone(), source_indices.clone())) - && (authored_name_at(source_indices.clone(), formal.clone()) - == authored_name_at(source_indices.clone(), actual.clone()))) - { - match formal.children.clone().first().cloned() { - Some(formal_ch) => match actual.children.clone().first().cloned() { - Some(actual_ch) => { - let formal_el = peel_nominal_alias_identity( - child_type_node(formal_ch.clone()), - type_env.clone(), - module_name.clone(), - ); - let actual_el = peel_nominal_alias_identity( - child_type_node(actual_ch.clone()), - type_env.clone(), - module_name.clone(), - ); - nominal_call_arg_brand_mismatch( - formal_el.clone(), - actual_el.clone(), - type_env.clone(), - source_indices.clone(), - ) - } - None => false, - }, - None => false, - } - } else { - false - } -} - -pub fn direct_call_arg_type_mismatch( - formal: Rc, - actual: Rc, - type_env: Rc, - module_name: String, - source_indices: Rc>>, -) -> bool { - if (type_node_is_callable(formal.clone()) || type_node_is_callable(actual.clone())) { - false - } else { - ((nominal_call_arg_brand_mismatch( - formal.clone(), - actual.clone(), - type_env.clone(), - source_indices.clone(), - ) || container_element_nominal_brand_mismatch( - formal.clone(), - actual.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - )) || kernel_value_declared_type_mismatch( - formal.clone(), - actual.clone(), - type_env.clone(), - source_indices.clone(), - )) - } -} - -pub fn borrowed_callable_call_type( - gnode: Rc, - typed_args: Rc>>, - scope: Rc, -) -> Rc { - { - let source_indices = scope.type_env.clone().source_indices.clone(); - let base = callable_inferred(gnode.clone()); - let tp_names = fn_type_param_names(gnode.clone(), source_indices.clone()); - if ((tp_names.clone().len() as i64) == 0) { - base - } else { - { - let value_params = Rc::new({ - let mut __result = Vec::new(); - for p in gnode.params.clone().iter().cloned() { - if !param_is_generic_decl(p.clone(), source_indices.clone()) { - __result.push(p); - } - } - __result - }); - let subst = Rc::new( - value_params - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, pair: (i64, Rc)| { - let formal_raw = param_node_type_expr(pair.1.clone()); - let param_name = authored_name_at(source_indices.clone(), pair.1.clone()); - let matched_arg = match Rc::new({ - let mut __result = Vec::new(); - for ta in typed_args.clone().iter().cloned() { - if arg_has_name( - ta.clone(), - param_name.clone(), - source_indices.clone(), - ) { - __result.push(ta); - } - } - __result - }) - .first() - .cloned() - { - Some(named_ta) => Some(named_ta.clone()), - None => typed_args - .clone() - .iter() - .cloned() - .skip(pair.0.clone() as usize) - .next(), - }; - match matched_arg.clone() { - Some(ta) => unify_generics( - formal_raw.clone(), - resolved_type(arg_value(ta.clone())), - tp_names.clone(), - source_indices.clone(), - acc.clone(), - ), - None => acc.clone(), - } - }, - ); - substitute_generics(base, subst.clone(), source_indices.clone()) - } - } - } -} - -pub fn is_anonymous_bound_name(name: String) -> bool { - (name.clone() == "_".to_string()) -} - -pub fn call_arg_label_matches_param(param_name: String, arg_label: String) -> bool { - (((param_name.clone() == arg_label.clone()) || (param_name.clone() == "_".to_string())) - || (((v1_rt::string_length(¶m_name) >= 1) - && (v1_rt::substring(¶m_name, 0, 1) == "_".to_string())) - && (v1_rt::substring(¶m_name, 1, v1_rt::string_length(¶m_name)) - == arg_label.clone()))) -} - -pub fn param_binds_positionally( - p: Rc, - source_indices: Rc>>, -) -> bool { - match p.children.clone().first().cloned() { - Some(type_expr) => { - (authored_name_at(source_indices.clone(), type_expr.clone()) - != authored_name_at(source_indices.clone(), p.clone())) - } - None => false, - } -} - -pub fn call_arg_bound_param_at_binding_key_note() -> String { - thread_local! { - static CACHED: String = { - "Runtime (v1_interpreter.rs call_function_inner) keys `bindings` differently per argument form: a NAMED actual is inserted under its own literal caller label (`bindings.insert(ctx.sym(name), ...)` — the raw label, never resolved through the underscore idiom to a declared name), while a POSITIONAL actual is inserted under the declared name it fills by running positional index (`bindings.insert(ctx.sym(¶m_names[positional_idx]), ...)`). Two named actuals therefore collide only when they carry the SAME literal label, and a positional-then-named collision (`one(1, a: 2)`) only when the named label equals the positional slot's declared name (found by review 48724). Resolving a named actual's key through declared_names via call_arg_label_matches_param (the prior form of this function) is a DIFFERENT and wrong key: filter-then-first picks whichever declared param the caller-label test hits first in declaration order, and an underscore-named param (`_: Edge`) matches ANY label unconditionally, so a later exact-named actual (`child:` against declared `child`) could be shadowed into colliding with an unrelated earlier underscore-idiom actual (`e:` against declared `_`) even though the runtime keys them apart as \"e\" and \"child\" — the false positive measured live at src/v2/std/cardinality.dag's termination_proof_fold_step(acc:, e:, child:) call against fn termination_proof_fold_step(acc, _: Edge, child), which compiled clean before this correction and fails at this wall after it without the fix.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct CallArgBoundParamAccum { - pub bound: Option, - pub pos: i64, -} - -pub fn call_arg_bound_param_at( - idx: i64, - typed_args: Rc>>, - source_indices: Rc>>, - positionally_eligible_names: Rc>, -) -> Option { - Rc::new( - typed_args - .clone() - .iter() - .cloned() - .take((idx.clone() + 1) as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - Rc::new(CallArgBoundParamAccum { - bound: None, - pos: 0, - }), - |acc: Rc, ta: Rc| match arg_name_at( - ta.clone(), - source_indices.clone(), - ) { - Some(label) => Rc::new(CallArgBoundParamAccum { - bound: Some(label.clone()), - pos: acc.pos.clone(), - }), - None => Rc::new(CallArgBoundParamAccum { - bound: positionally_eligible_names - .clone() - .iter() - .cloned() - .skip(acc.pos.clone() as usize) - .next(), - pos: (acc.pos.clone() + 1), - }), - }, - ) - .bound - .clone() -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct CallShapeArityScan { - pub positional_slot: i64, - pub required_count: i64, - pub supplied_count: i64, - pub deficit_param: Option>, -} - -pub fn scan_call_shape_arity( - sig_params: Rc>>, - typed_args: Rc>>, - positional_args: Rc>>, - source_indices: Rc>>, -) -> Rc { - sig_params.clone().iter().cloned().fold( - Rc::new(CallShapeArityScan { - positional_slot: 0, - required_count: 0, - supplied_count: 0, - deficit_param: None, - }), - |st: Rc, param: Rc| { - if (st.deficit_param.clone() != None) { - st.clone() - } else { - if param_is_generic_decl(param.clone(), source_indices.clone()) { - st.clone() - } else { - if (param_node_default_value(param.clone()) != None) { - st.clone() - } else { - { - let param_name = - authored_name_at(source_indices.clone(), param.clone()); - let named_supplied = { - let mut __found = false; - for ta in typed_args.clone().iter().cloned() { - if match arg_name_at(ta.clone(), source_indices.clone()) { - Some(label) => call_arg_label_matches_param( - param_name.clone(), - label.clone(), - ), - None => false, - } { - __found = true; - break; - } - } - __found - }; - let next_required = (st.required_count.clone() + 1); - if named_supplied.clone() { - Rc::new(CallShapeArityScan { - positional_slot: st.positional_slot.clone(), - required_count: next_required.clone(), - supplied_count: (st.supplied_count.clone() + 1), - deficit_param: None, - }) - } else { - if param_binds_positionally(param.clone(), source_indices.clone()) { - if (st.positional_slot.clone() - < (positional_args.clone().len() as i64)) - { - Rc::new(CallShapeArityScan { - positional_slot: (st.positional_slot.clone() + 1), - required_count: next_required.clone(), - supplied_count: (st.supplied_count.clone() + 1), - deficit_param: None, - }) - } else { - Rc::new(CallShapeArityScan { - positional_slot: st.positional_slot.clone(), - required_count: next_required.clone(), - supplied_count: st.supplied_count.clone(), - deficit_param: Some(param.clone()), - }) - } - } else { - Rc::new(CallShapeArityScan { - positional_slot: st.positional_slot.clone(), - required_count: next_required.clone(), - supplied_count: st.supplied_count.clone(), - deficit_param: Some(param.clone()), - }) - } - } - } - } - } - } - }, - ) -} - -pub fn direct_call_shape_diags( - func_name: String, - sig_params: Rc>>, - typed_args: Rc>>, - type_env: Rc, - module_name: String, - call_span: Rc, -) -> Rc>> { - { - let source_indices = type_env.source_indices.clone(); - let declared_names = Rc::new({ - let mut __result = Vec::new(); - for p in sig_params.clone().iter().cloned() { - __result.push(authored_name_at(source_indices.clone(), p.clone())); - } - __result - }); - let positionally_eligible_names = Rc::new({ - let mut __result = Vec::new(); - for p in Rc::new({ - let mut __result = Vec::new(); - for p in sig_params.clone().iter().cloned() { - if param_binds_positionally(p.clone(), source_indices.clone()) { - __result.push(p); - } - } - __result - }) - .iter() - .cloned() - { - __result.push(authored_name_at(source_indices.clone(), p.clone())); - } - __result - }); - let unknown_label_diags = Rc::new({ - let mut __result = Vec::new(); - for ta in typed_args.clone().iter().cloned() { - __result.extend( - (*match arg_name_at(ta.clone(), source_indices.clone()) { - Some(label) => { - if { - let mut __found = false; - for pn in declared_names.clone().iter().cloned() { - if call_arg_label_matches_param(pn.clone(), label.clone()) { - __found = true; - break; - } - } - __found - } { - Rc::new(vec![]) - } else { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::CallArgumentNameUnknown { - callee: func_name.clone(), - argument: label.clone(), - declared: declared_names.clone(), - span: ta.span.clone(), - }), - module_name.clone(), - )]) - } - } - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let positional_capacity = (Rc::new({ - let mut __result = Vec::new(); - for p in sig_params.clone().iter().cloned() { - if param_binds_positionally(p.clone(), source_indices.clone()) { - __result.push(p); - } - } - __result - }) - .len() as i64); - let positional_args = Rc::new({ - let mut __result = Vec::new(); - for ta in typed_args.clone().iter().cloned() { - if (arg_name_at(ta.clone(), source_indices.clone()) == None) { - __result.push(ta); - } - } - __result - }); - let surplus_diags = - if ((positional_args.clone().len() as i64) > positional_capacity.clone()) { - match positional_args - .clone() - .iter() - .cloned() - .skip(positional_capacity.clone() as usize) - .next() - { - Some(overflow) => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::CallPositionalSurplus { - callee: func_name.clone(), - supplied: (positional_args.clone().len() as i64), - capacity: positional_capacity.clone(), - span: overflow.span.clone(), - }), - module_name.clone(), - )]), - None => Rc::new(vec![]), - } - } else { - Rc::new(vec![]) - }; - let duplicate_label_diags = Rc::new({ - let mut __result = Vec::new(); - for pair in Rc::new( - typed_args - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.extend( - (*{ - let current_bound = call_arg_bound_param_at( - pair.0.clone(), - typed_args.clone(), - source_indices.clone(), - positionally_eligible_names.clone(), - ); - match current_bound.clone() { - Some(bound_name) => { - let earlier_dup = { - let mut __found = false; - for other in Rc::new( - typed_args - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - if ((other.0.clone() < pair.0.clone()) - && (call_arg_bound_param_at( - other.0.clone(), - typed_args.clone(), - source_indices.clone(), - positionally_eligible_names.clone(), - ) - .as_deref() - == current_bound.clone().as_deref())) - { - __found = true; - break; - } - } - __found - }; - if (earlier_dup.clone() - && !is_anonymous_bound_name(bound_name.clone())) - { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::CallArgumentDuplicate { - callee: func_name.clone(), - argument: bound_name.clone(), - span: pair.1.clone().span.clone(), - }), - module_name.clone(), - )]) - } else { - Rc::new(vec![]) - } - } - None => Rc::new(vec![]), - } - }) - .iter() - .cloned(), - ); - } - __result - }); - let arity_scan = scan_call_shape_arity( - sig_params.clone(), - typed_args.clone(), - positional_args.clone(), - source_indices.clone(), - ); - let deficit_diags = match arity_scan.deficit_param.clone() { - Some(missing_param) => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::CallPositionalDeficit { - callee: func_name.clone(), - parameter: authored_name_at(source_indices.clone(), missing_param.clone()), - supplied: arity_scan.supplied_count.clone(), - required: arity_scan.required_count.clone(), - span: call_span.clone(), - }), - module_name.clone(), - )]), - None => Rc::new(vec![]), - }; - v1_rt::concat( - v1_rt::concat(unknown_label_diags.clone(), surplus_diags.clone()), - v1_rt::concat(duplicate_label_diags.clone(), deficit_diags.clone()), - ) - } -} - -pub fn function_value_call_named_arg_diags( - func_name: String, - typed_args: Rc>>, - type_env: Rc, - module_name: String, - body_locals: Rc>, - locals: Rc>>, -) -> Rc>> { - match v1_rt::map_get(&body_locals, func_name.clone()) { - None => Rc::new(vec![]), - Some(_) => { - let named_diags = Rc::new({ - let mut __result = Vec::new(); - for ta in typed_args.clone().iter().cloned() { - __result.extend( - (*match arg_name_at(ta.clone(), type_env.source_indices.clone()) { - Some(label) => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::CallNamedArgOnFunctionValue { - callee: func_name.clone(), - argument: label.clone(), - span: ta.span.clone(), - }), - module_name.clone(), - )]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let arity_diags = match v1_rt::map_get(&locals, func_name.clone()) { - Some(binding) => { - let param_count = (binding.resolved.clone().params.clone().len() as i64); - if (param_count.clone() > 0) { - { - let supplied = (typed_args.clone().len() as i64); - if (supplied.clone() > param_count.clone()) { - match typed_args - .clone() - .iter() - .cloned() - .skip(param_count.clone() as usize) - .next() - { - Some(overflow) => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::CallPositionalSurplus { - callee: func_name.clone(), - supplied: supplied.clone(), - capacity: param_count.clone(), - span: overflow.span.clone(), - }), - module_name.clone(), - )]), - None => Rc::new(vec![]), - } - } else { - Rc::new(vec![]) - } - } - } else { - Rc::new(vec![]) - } - } - None => Rc::new(vec![]), - }; - v1_rt::concat(named_diags.clone(), arity_diags.clone()) - } - } -} - -pub fn function_value_named_application_wall_note() -> String { - thread_local! { - static CACHED: String = { - "WALL (DESIGN §5) — RUNG (§4b): mitigatable minimum for the class named actuals on function-value application. Reason: coverage path (5) — record-field fn value invoked as cfg.callback(a:) via ExprMethodCall — is compile-clean Accepted today and bypasses both this wall and #7519; executing probe function_value_field_method_known_hole_probe (ct_function_value_field_method_known_hole_probe_test) pins that hole and flips to a permanent regression control when the method-call label wall lands. The direct-call label wall (direct_call_shape_wall_note, gunbc#7519) runs only when a module fn sig resolves at the ExprCall seam. Function-value calls route through body_locals shadowing (call_locals_shadow_note): a let-bound or parameter callee skips sig lookup, so named actuals were silently accepted while the emitter's order_typed_call_args cannot reorder them (lookup_func_sig_in_scope returns Absent) and labels are not validated against any declared parameter authority. This wall refuses every named actual when the callee is a body-scope binding — the function-value path — until declaration-identity join can validate labels against the underlying fn. Positional calls on function values stay allowed. Named actuals on direct module/builtin calls (sig resolved) remain on the sibling wall. COVERAGE ACROSS CALLEE PATHS (§4b rung honesty — class rung is the minimum in-scope path, specimens measured by execution): (1) ExprCall bare name in body_locals (fn param, let, match binder, lambda param) — THIS WALL; structurally guaranteed for named actuals on that path. (2) ExprCall bare name with module fn sig resolved — sibling direct_call_shape_wall_note (#7519). (3) Module-level data binding with typed fn value called by bare name (data cb: fn(...) = ...) — NOT body_locals; routes #7519 when lookup resolves (specimen: CallArgumentNameUnknown on cb(a:, b:)). (4) Generic HO param where the arrow is a type variable (agree: F) — body_locals; same wall as (1). (5) Record field holding fn value invoked as cfg.callback(a:) — UNCOVERED HOLE: parser make_call_expr maps ExprFieldAccess callee to ExprMethodCall, not ExprCall; neither this wall nor #7519 runs; specimen compiles clean with named actuals; executing probe function_value_field_method_known_hole_probe. Dissolve-on: method-call / ExprMethodCall argument-label wall (direct_call_shape_wall_note unwalled class (3)). (6) Immediate apply f()(a:) on a call result — syntax parses (make_call_expr default → ExprCall name \"\"); NOT body_locals, sig does not resolve; neither wall fires on named args; specimen fails InternalError before Accepted (non-identifier ExprCall callee not modeled) — unwritable as Accepted today, not a live compile-clean named-arg hole.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn direct_call_shape_wall_note() -> String { - thread_local! { - static CACHED: String = { - "WALL (DESIGN §5) — the compile seam now refuses the four direct-call shape states the interpreter refuses at runtime, so the two authorities agree instead of one refusing and the other absorbing. The runtime authority is v1_interpreter.rs call_function_inner: a caller label naming no declared parameter raises CallContractMismatch (accepting label x against a declared x, _x, or _ — the deliberately-unused-parameter idiom, mirrored here in call_arg_label_matches_param); a positional argument beyond the positional parameter list raises CallContractMismatch too; a required parameter omitted without a declared default raises CallContractMismatch too (param_node_default_value legitimately fills omissions that carry a default — only non-default params count as required); and a second actual binding under one already-bound parameter key raises CallContractMismatch too ('argument supplied more than once'). Before this wall the compile seam was SILENT on all four, and the divergence was three-way on the first two (measured live, 2026-07-31, the probe-2 receipt in the guarantee-lane census): `sub(a: 10, bb: 3)` against `fn sub(a: Int, b: Int)` compiled with zero diagnostics, the interpreter refused it loudly, and the Rust emitter silently REORDERED it positionally — order_typed_call_args's name-match-else-positional arm bound bb's value to b, so the emitted realization computed an answer the interpreter refuses: two realizations of one program disagreeing silently, the exact state the guarantee ladder calls silent wrongness. The mechanism of the compile silence was the same absorbing fallback one seam over: direct_call_arg_mismatch_diags walks PARAMS and falls back positionally (`typed_args |> skip(pair.first) |> first`) when no arg carries the param's name, so a mislabeled arg is absorbed into a position and only its TYPE is ever judged — the label itself was never a checked fact. This wall checks application shape at the direct-call seam via direct_call_shape_diags: every labeled actual must name a declared parameter (modulo the underscore idiom); unlabeled actuals must fit within the positional capacity; every required parameter (no default) must be supplied by name or positional slot — scan_call_shape_arity mirrors call_function_inner's binding walk, including the same positional-capacity predicate (a param binds positionally iff its type-expr child's authored name differs from its own); and no two actuals may resolve to the same declared parameter — call_arg_bound_param_at (binding-key discipline documented at call_arg_bound_param_at_binding_key_note) resolves each actual, named or positional, to the parameter it fills, mirroring exactly how call_function_inner keys `bindings`. WHY THIS CHECK IS NOT UNDER module_skips_direct_call_arg_check: that exemption exists for the TYPE judgment, whose false-positive classes are representation gaps (brand aliases, optionality's two forms, anonymous literals, expansion depth — the conformance wall's four measured classes). A LABEL has no representation: it is a surface string matched against a declared surface string, the same exact-membership judgment the interpreter performs, so the exemption's reason does not reach it and the wall runs over every module including the compiler's own sources. All four diagnostics BLOCK (CallArgumentNameUnknown, CallPositionalSurplus, CallPositionalDeficit, CallArgumentDuplicate — is_error_diagnostic and is_interpreter_blocking_diagnostic default arms), so a refused program never reaches emit — which retires the emission path's silent reorder for Accepted programs at this seam without touching order_typed_call_args: its positional arm remains the legitimate binding rule for unlabeled args, and the states it could absorb are no longer writable in an Accepted program. DELIBERATELY NOT WALLED, with its trigger: method/pipe-seam argument labels — this wall covers the direct-call seam (the sig != none branch); the method-call path binds its arguments through its own inference arms and is the method wall's territory. The subject grain of the climb, stated per the ladder's rung-honesty rule: the classes 'unknown argument label', 'positional surplus', 'missing required argument', and 'a caller label or slot is bound more than once' each move from mitigatable (runtime refusal on the interpretation path; silent wrong output or deferred NoSuchVariable on the emission path) to structurally guaranteed at the direct-call seam — no Accepted program contains one — while the method-pipe path stays at its measured rung, named here rather than implied climbed. DEFICIT REQUIRED-GRAIN RULING (measured 2026-08-05, option b): the only writable shape where scan_call_shape_arity's required set (skip param_is_generic_decl, else require when not positionally supplied) diverges from call_function_inner's is_value_param (`type_expr authored name != param name`) is a param spelled `x: x<...>` — the param name equals the applied-type constructor with a non-leaf type-expr — corpus census `grep -rPno '\\b([a-z_][a-z0-9_]*): \\1<'` over dag/ src/v1/ src/v2/: 0 sites; params with no type-expr child are unwritable from authored surface. This seam refuses that shape as CallPositionalDeficit; the interpreter does not — compile is authoritative here because a non-positional param with no default and no supplied binding cannot be bound; matching the looser runtime predicate would copy an interpreter deficit for symmetry, not prevent silent wrongness. THE CENSUS RECEIPT, run before landing rather than promised after (2026-07-31): the label/surplus wall refused 28 live sites across the [src/v1, dag] regen closure and the dag + src/v2 compile-clean closure, and every one was the same defect — a parameter renamed at its declaration while call sites kept the old label, absorbed positionally ever since: to_string(i:) against the renamed value (8 sites, src/v1/compile.dag), arm_body(arm:) against n, is_import_slot_node(p:) against n, fold_list(init:) against this corpus's declared empty (17 sites, one file), and floor_discovery_walk_failure_refusal_reason(path:) against path_opt. All were relabeled to the declared authority in the same change. The fold_list rows carry the sharpest lesson about WHY compile must hold this fact even where runtime does not: those 17 sites never failed live because the interpreter grounds fold_list natively (label-blind), while call_function_inner would refuse the same label on the user-fn path — so the program's meaning depended on WHICH dispatch tier happened to serve the call, and the label's truth was untested precisely where it was wrong. The wall pins the label to the one declared authority regardless of tier, which is what keeps the call sites correct when the native grounding dissolves into the declared surface (the primitive-realization-single-authority trigger). MEASURED BLIND SPOT, stated rather than implied covered: 3 more to_string(i:) sites in src/v1/dag_collect.dag never reached the wall because their callee resolves NO sig at this seam (no import, global-bare miss) — the sig == none fallthrough routes to the method bridge and this wall never sees the call. They were found by grep on the fossil's shape and fixed with the rest, but the CLASS stays open: a call whose callee sig does not resolve is judged by nothing here, and that fallthrough closes with resolution coverage (the namespace lane), not with a wider label check. (Corrected 2026-08-05: the duplicate-label class LANDED in the order this note originally specified — v1_interpreter.rs call_function_inner now refuses a second binding under one caller label (CallContractMismatch, 'argument supplied more than once') before this seam was given its mirror, CallArgumentDuplicate. The class 'a caller label is supplied more than once' therefore climbs from mitigatable (silent last-write-wins) to structurally guaranteed at the direct-call seam, alongside the other three; a whole-tree census at landing found zero live duplicate-label call sites, so the wall adds no new refusal to any existing corpus form.) (Corrected 2026-08-05, cursor review 48724: an interim version of the duplicate-label mirror keyed CallArgumentDuplicate on exact caller-label string equality, which overclaimed. The runtime authority (call_function_inner) keys `bindings` by resolved PARAMETER symbol, not by caller-label string, and populates that key from a positional bind exactly as it does from a named one — so a positional bind of the sole parameter followed by a same-parameter named actual (`one(1, a: 2)` against `fn one(a: Int)`) collides and refuses at runtime, a state the label-string-only compile check could not see (`Absent => false` for positional predecessors) and so compiled clean, reaching emit. CallArgumentDuplicate is now keyed the same way the runtime is: call_arg_bound_param_at resolves each actual — named or positional — to the declared parameter it fills (positional actuals against the interpreter's own filtered param_binds_positionally list, in running positional order; named actuals through call_arg_label_matches_param, the same underscore-idiom equality unknown-label matching already uses) and the wall refuses a second actual resolving to the same parameter, never comparing raw caller-label strings against each other. The measured false-negative this closes and its discriminating fixture: call_duplicate_mixed_red_source, a single-parameter positional-then-named collision that a label-string-only check could not distinguish from the corpus's positional-only and named-only green controls.) (Corrected 2026-08-05, live cardinality.dag false positive: the prior correction's 'resolves a NAMED actual through call_arg_label_matches_param to a declared parameter' also overclaimed. The runtime keys a named actual under its own LITERAL caller label, never resolved through the underscore idiom to a declared name; only a positional actual is keyed by resolved declared name. Resolving named actuals through declared_names let an underscore-named param (matching ANY label unconditionally) shadow an unrelated later exact-named actual into a false collision — measured live at termination_proof_fold_step(acc: acc, e: e, child: child) against fn termination_proof_fold_step(acc, _: Edge, child), which this wall wrongly refused on 'child' until call_arg_bound_param_at's named branch was corrected to bind directly to the caller's literal label.) (Corrected 2026-08-05, #7848 merge: this note previously described only the label/surplus/deficit trio or only the duplicate-label mirror depending on branch; merging the two PRs' parallel work on this same wall found no consistency defect between the two additions — both diagnostics BLOCK, both use the same declared-parameter binding discipline as their keying authority, and both honor the underscore idiom identically, so the merge is a union of coverage, not a reconciliation of conflicting semantics.) (Corrected 2026-08-05, review from parent session loyal-ant-382: the duplicate-binding key, as landed, keyed EVERY anonymous ('_') parameter under the same literal string regardless of position, so a signature with two or more anonymous parameters bound positionally (or a mix of positional and record-field/method-value invocation of the same signature) false-refused CallArgumentDuplicate on its second anonymous actual — a live specimen, provider_readiness_independence_claim in dag/gunbc/provider_readiness_claim_evidence.dag, carries exactly this shape. The class 'a caller label or slot is bound more than once' does NOT climb to structurally guaranteed for anonymous parameters and never claimed to on a correct reading — 'more than once' presupposes the binding is READ twice, and an anonymous parameter's body cannot read it at all, so two anonymous parameters filled at two positions are two distinct, unreadable slots, not one key bound twice. call_arg_bound_param_at's duplicate check (this file) now excludes a resolved binding of exactly '_' from the collision check via the top-level `is_anonymous_bound_name` function (the earlier-duplicate scan still runs unconditionally; its result is combined with `!is_anonymous_bound_name(name: bound_name)` in the final `if`) — an anonymous parameter can never collide with another anonymous parameter under this authority, named or positional. `is_anonymous_bound_name` is a top-level function rather than an inline comparison for the same reason `call_arg_label_matches_param` already is one in this file: 'what counts as anonymous' is a single fact the whole module should ask one authority for, not a `== '_'` literal repeated ad hoc at each call site that cares — the existing pattern, not a new one. The runtime mirror (v1_interpreter.rs call_function_inner) excludes '_' from its collision check the same way, but — unlike an outright exclusion from binding — still INSERTS the value under the '_' key on every anonymous bind: the insert is what the required-argument check (`param_supplied_at_call`, reading `bindings.contains_key`) depends on to see an anonymous parameter as filled, so removing the insert entirely (the fix's first, corrected draft) turned every anonymous-but-positionally-supplied parameter into a false CallPositionalDeficit/'missing required argument' one layer downstream of the duplicate check it was fixing. Harmless repeated overwrite under one dead key, never read by the body, is the correct shape here — not 'never bound' literally, but 'never checked for collision, and immaterial which write wins.' The two required regression fixtures: a call binding two-or-more anonymous parameters positionally (direct and via a stored function value) stays ACCEPTED; the existing named/mixed duplicate fixtures (call_duplicate_mixed_red_source, the cardinality.dag underscore-shadow control) stay RED, because those collide on a NAMED, readable label, not an anonymous one.)".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn direct_call_arg_mismatch_diags( - plan: Rc>>, - type_env: Rc, - module_name: String, -) -> Rc>> { - { - let source_indices = type_env.source_indices.clone(); - Rc::new({ - let mut __result = Vec::new(); - for app in plan.clone().iter().cloned() { - __result.extend( - (*{ - let formal = app.formal.clone(); - match app.matched_arg.clone() { - Some(ta) => { - let actual_expr = arg_value(ta.clone()); - if match (*actual_expr.expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => true, - _ => false, - } { - Rc::new(vec![]) - } else { - { - let actual_raw = resolved_type(actual_expr.clone()); - let actual = peel_nominal_alias_identity( - actual_raw.clone(), - type_env.clone(), - module_name.clone(), - ); - if direct_call_arg_type_mismatch( - formal.clone(), - actual.clone(), - type_env.clone(), - module_name.clone(), - source_indices.clone(), - ) { - Rc::new(vec![type_mismatch_error( - node_type_shape( - formal.clone(), - source_indices.clone(), - ), - node_type_shape( - actual.clone(), - source_indices.clone(), - ), - actual_expr.span.clone(), - module_name.clone(), - )]) - } else { - Rc::new(vec![]) - } - } - } - } - None => Rc::new(vec![]), - } - }) - .iter() - .cloned(), - ); - } - __result - }) - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct Tier2bBt { - pub bt: Rc, - pub kernel_diags: Rc>>, -} - -pub fn infer_tier2b_builtin_with_kernel_diags( - func_name: String, - typed_args: Rc>>, - scope: Rc, - span: Rc, -) -> Rc { - if ((func_name.clone() == "lookup".to_string()) || (func_name.clone() == "map_get".to_string())) - { - Rc::new(Tier2bBt { - bt: match typed_args.clone().first().cloned() { - Some(receiver_arg) => match arg_value(receiver_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: receiver_type, - .. - }) => { - match map_value_type_in_env(receiver_type.clone(), scope.type_env.clone()) { - Some(value_type) => with_optional_cardinality(value_type.clone()), - None => resolve_builtin_call_type(func_name.clone()), - } - } - _ => resolve_builtin_call_type(func_name.clone()), - }, - None => resolve_builtin_call_type(func_name.clone()), - }, - kernel_diags: Rc::new(vec![]), - }) - } else { - if ((func_name.clone() == "map_keys".to_string()) - || (func_name.clone() == "sorted_map_keys".to_string())) - { - match typed_args.clone().first().cloned() { - Some(receiver_arg) => match arg_value(receiver_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: receiver_type, - .. - }) => { - match map_key_type_in_env(receiver_type.clone(), scope.type_env.clone()) { - Some(key_type) => { - let lk = list_kernel_ty_from_element(key_type.clone()); - Rc::new(Tier2bBt { - bt: lk.ty.clone(), - kernel_diags: lk.miss_diags.clone(), - }) - } - None => Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }), - } - } - _ => Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }), - }, - None => Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }), - } - } else { - if (func_name.clone() == "map_values".to_string()) { - match typed_args.clone().first().cloned() { - Some(receiver_arg) => match arg_value(receiver_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: receiver_type, - .. - }) => match map_value_type_in_env( - receiver_type.clone(), - scope.type_env.clone(), - ) { - Some(value_type) => { - let lv = list_kernel_ty_from_element(value_type.clone()); - Rc::new(Tier2bBt { - bt: lv.ty.clone(), - kernel_diags: lv.miss_diags.clone(), - }) - } - None => Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }), - }, - _ => Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }), - }, - None => Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }), - } - } else { - if (((func_name.clone() == "set_insert".to_string()) - || (func_name.clone() == "set_union".to_string())) - || (func_name.clone() == "set_contains".to_string())) - { - { - let operand_elem = if ((func_name.clone() == "set_insert".to_string()) - || (func_name.clone() == "set_contains".to_string())) - { - match typed_args.clone().iter().cloned().skip(1 as usize).next() { - Some(insert_arg) => match arg_value(insert_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { node: elem, .. }) => { - Some(elem.clone()) - } - _ => None, - }, - None => None, - } - } else { - match typed_args.clone().iter().cloned().skip(1 as usize).next() { - Some(other_arg) => match arg_value(other_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: other_type, .. - }) => match set_element_type_in_env( - other_type.clone(), - scope.type_env.clone(), - ) { - Some(elem_slot) => Some(child_type_node(elem_slot.clone())), - None => None, - }, - _ => None, - }, - None => None, - } - }; - let recv_is_set = match typed_args.clone().first().cloned() { - Some(receiver_arg) => { - set_builtin_receiver_is_set(receiver_arg.clone(), scope.clone()) - } - None => false, - }; - let union_other_bad = if (func_name.clone() == "set_union".to_string()) { - match typed_args.clone().iter().cloned().skip(1 as usize).next() { - Some(other_arg) => set_union_other_operand_is_resolved_non_set( - other_arg.clone(), - scope.clone(), - ), - None => false, - } - } else { - false - }; - let recv_elem = match typed_args.clone().first().cloned() { - Some(receiver_arg) => match arg_value(receiver_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: receiver_type, - .. - }) => set_element_type_from_receiver( - receiver_type.clone(), - scope.clone(), - ), - _ => None, - }, - None => None, - }; - let elem_mismatch = match recv_elem.clone() { - Some(re) => match operand_elem.clone() { - Some(oe) => set_element_types_mismatch( - re.clone(), - oe.clone(), - scope.type_env.clone().source_indices.clone(), - ), - None => false, - }, - None => false, - }; - let wrong_receiver_diags = if recv_is_set.clone() { - Rc::new(vec![]) - } else { - Rc::new(vec![inference_error( - v1_rt::concat( - func_name.clone(), - " receiver must be a Set".to_string(), - ), - span.clone(), - scope.module_name.clone(), - )]) - }; - let wrong_union_other_diags = if union_other_bad.clone() { - Rc::new(vec![inference_error( - "set_union second operand must be a Set".to_string(), - span.clone(), - scope.module_name.clone(), - )]) - } else { - Rc::new(vec![]) - }; - let mismatch_diags = if elem_mismatch.clone() { - Rc::new(vec![inference_error( - v1_rt::concat( - func_name.clone(), - " incompatible set element types".to_string(), - ), - span.clone(), - scope.module_name.clone(), - )]) - } else { - Rc::new(vec![]) - }; - let result_bt = if (func_name.clone() == "set_contains".to_string()) { - if (recv_is_set.clone() && !elem_mismatch.clone()) { - bool_type() - } else { - resolve_builtin_call_type(func_name.clone()) - } - } else { - match typed_args.clone().first().cloned() { - Some(receiver_arg) => { - if ((recv_is_set.clone() && !elem_mismatch.clone()) - && !union_other_bad.clone()) - { - match arg_value(receiver_arg.clone()) - .inferred - .clone() - .as_deref() - .cloned() - { - Some(InferredNode::Resolved { - node: receiver_type, - .. - }) => match recv_elem.clone() { - Some(_) => receiver_type.clone(), - None => match operand_elem.clone() { - Some(element) => { - set_kernel_ty_from_element(element.clone()) - .ty - .clone() - } - None => { - resolve_builtin_call_type(func_name.clone()) - } - }, - }, - _ => resolve_builtin_call_type(func_name.clone()), - } - } else { - resolve_builtin_call_type(func_name.clone()) - } - } - None => resolve_builtin_call_type(func_name.clone()), - } - }; - let build_diags = if (func_name.clone() == "set_contains".to_string()) { - Rc::new(vec![]) - } else { - match operand_elem.clone() { - Some(element) => { - if ((recv_is_set.clone() && !elem_mismatch.clone()) - && !union_other_bad.clone()) - { - set_kernel_ty_from_element(element.clone()) - .miss_diags - .clone() - } else { - Rc::new(vec![]) - } - } - None => Rc::new(vec![]), - } - }; - Rc::new(Tier2bBt { - bt: result_bt.clone(), - kernel_diags: v1_rt::concat( - wrong_receiver_diags.clone(), - v1_rt::concat( - wrong_union_other_diags.clone(), - v1_rt::concat(mismatch_diags.clone(), build_diags.clone()), - ), - ), - }) - } - } else { - Rc::new(Tier2bBt { - bt: resolve_builtin_call_type(func_name.clone()), - kernel_diags: Rc::new(vec![]), - }) - } - } - } - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct MethodPipeFallback { - pub result_ty: Rc, - pub kernel_diags: Rc>>, -} - -pub fn method_existence_decision( - recv_rt: Rc, - method_name: String, - scope: Rc, - span: Rc, -) -> Rc { - { - let recv_shape = node_type_shape( - recv_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let recv_surface_established = (kernel_profile_lookup(authored_name_at( - scope.type_env.clone().source_indices.clone(), - recv_rt.clone(), - )) != None); - if recv_surface_established.clone() { - Rc::new(MethodPipeFallback { - result_ty: error_type(), - kernel_diags: Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::MethodNotFound { - method: method_name.clone(), - receiver_type: recv_shape.clone(), - span: span.clone(), - }), - scope.module_name.clone(), - )]), - }) - } else { - { - let peeled = peel_where_refinement_base(recv_rt.clone(), scope.type_env.clone()); - let peeled_lookup = lookup_structural_method( - peeled.clone(), - method_name.clone(), - scope.type_env.clone().source_indices.clone(), - ); - match peeled_lookup.resolution.clone() { - Some(mfr) => Rc::new(MethodPipeFallback { - result_ty: mfr.result_type.clone(), - kernel_diags: peeled_lookup.kernel_diagnostics.clone(), - }), - None => { - let peeled_shape = node_type_shape( - peeled.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let peeled_surface_established = (kernel_profile_lookup(authored_name_at( - scope.type_env.clone().source_indices.clone(), - peeled.clone(), - )) != None); - if peeled_surface_established.clone() { - Rc::new(MethodPipeFallback { - result_ty: error_type(), - kernel_diags: Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::MethodNotFound { - method: method_name.clone(), - receiver_type: peeled_shape.clone(), - span: span.clone(), - }), - scope.module_name.clone(), - )]), - }) - } else { - match unresolved_method_frontier_trigger( - scope.module_name.clone(), - method_name.clone(), - recv_shape.clone(), - ) { - Some(trigger) => { - if (authored_name_at( - scope.type_env.clone().source_indices.clone(), - recv_rt.clone(), - ) == "".to_string()) - { - Rc::new(MethodPipeFallback { - result_ty: error_type(), - kernel_diags: Rc::new(vec![make_error_node( - Rc::new( - CompilerDiagnostic::ReceiverTypeUnestablished { - method: method_name.clone(), - span: span.clone(), - }, - ), - scope.module_name.clone(), - )]), - }) - } else { - Rc::new(MethodPipeFallback { - result_ty: error_type(), - kernel_diags: Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::MethodExistenceFrontierAdmitted { - method: method_name.clone(), - receiver_type: recv_shape.clone(), - trigger: dissolution_description(trigger.clone()), - span: span.clone(), -}), scope.module_name.clone())]), -}) - } - } - None => Rc::new(MethodPipeFallback { - result_ty: error_type(), - kernel_diags: Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::MethodExistenceUndecided { - method: method_name.clone(), - receiver_type: recv_shape.clone(), - span: span.clone(), - }), - scope.module_name.clone(), - )]), - }), - } - } - } - } - } - } - } -} - -pub fn method_pipe_map_keys_values_fallback( - recv_rt: Rc, - method_name: String, - scope: Rc, - span: Rc, -) -> Rc { - if ((method_name.clone() == "map_keys".to_string()) - || (method_name.clone() == "sorted_map_keys".to_string())) - { - match map_key_type_in_env(recv_rt.clone(), scope.type_env.clone()) { - Some(key_type) => { - let lk = list_kernel_ty_from_element(key_type.clone()); - Rc::new(MethodPipeFallback { - result_ty: lk.ty.clone(), - kernel_diags: lk.miss_diags.clone(), - }) - } - None => method_existence_decision( - recv_rt.clone(), - method_name.clone(), - scope.clone(), - span.clone(), - ), - } - } else { - if (method_name.clone() == "map_values".to_string()) { - match map_value_type_in_env(recv_rt.clone(), scope.type_env.clone()) { - Some(value_type) => { - let lv = list_kernel_ty_from_element(value_type.clone()); - Rc::new(MethodPipeFallback { - result_ty: lv.ty.clone(), - kernel_diags: lv.miss_diags.clone(), - }) - } - None => method_existence_decision( - recv_rt.clone(), - method_name.clone(), - scope.clone(), - span.clone(), - ), - } - } else { - method_existence_decision( - recv_rt.clone(), - method_name.clone(), - scope.clone(), - span.clone(), - ) - } - } -} - -pub fn method_existence_wall_note() -> String { - thread_local! { - static CACHED: String = { - "WALL (DESIGN §5) — an unresolved method REFUSES; it never inherits the receiver type. The deleted else-arm returned recv_rt with an EMPTY diagnostic list, so an unknown method on List became another List: a success-shaped answer that survived a whole collection pipeline, stamped PlainMethodSemantics as if it had resolved. Nothing refused until InterpError::Unimplemented { what: \"method 'filter_map'\" } — whole-tree compile reported ZERO blocking errors while live dispatch returned HTTP 500 (#7479). THE DECIDABILITY PREDICATE IS THE LOAD-BEARING PART. It is PER-RECEIVER, not per-name: refuse exactly when kernel_profile_lookup returns a profile for the receiver canonical container kind, because tier0 (lookup_structural_method) has already consulted that profile algebra templates and missed — so reaching this arm with a kernel-profiled receiver PROVES the method is absent from that receiver complete declared surface. This is the same authority tier0 reads, not a second relation minted here (§3). A NAME-GRAIN PREDICATE WAS TRIED AND IS WRONG, and the receipt is worth keeping because it is subtle: gating on membership in a declared method-name roster admits any rostered name on ANY receiver, so List |> starts_with(..) and List |> to_upper() compiled clean while the diagnostic claimed the receiver was under-resolved — a fail-open with a message that also LIED about its cause, since Container(List,Primitive(Int)) is fully resolved (codex review 45327, confirmed by execution). Per-receiver closes both: those two now REFUSE. THE ONE MEASURED OBSTACLE TO PER-RECEIVER WAS A REAL §3 FORK, AND IT IS FIXED HERE RATHER THAN WORKED AROUND: free_monoid_scalar_templates omitted count while the interpreter dispatches it natively on strings (the length/count/size arm), so String |> count reached this arm and was admitted only by the fail-open — a hollow green. count is now declared on the String profile, matching the runtime, so it resolves at tier0 and never reaches here. WHAT STAYS UNDECIDED, and why refusing there would fabricate: a receiver with NO kernel profile has no complete declared surface to prove absence against. THE LARGEST MEASURED CLASS WAS NOT UNDECIDABLE AT ALL AND IS NOW DECIDED — a where-refinement alias arrived as Product(NonEmptyStr) only because resolve_method_receiver_type short-circuits on Conj and never peeled to the String base; peeling it (where_refinement_receiver_peel_note) moved 12 corpus sites out of this residue in both directions at once, resolving the correct .length() calls AND making a bogus method on a branded string a hard MethodNotFound. What remains genuinely has no surface: a lambda parameter whose type never propagates so the receiver has no authored name at all (the LexMatchThunk { apply: fn(s) } idiom in src/v2/compiler/01_tokenize.dag and the StoreObjectFold lambdas in extdeps/git/object_store.dag), a coproduct payload bound by pattern destructuring arriving typed Primitive(ok) (a correct labels |> list_push(label)), a bare type variable, and an Optional whose cardinality is dropped before lookup so the inner product is what arrives. Refusing those would red correct code, which is the mirror image of the fabricated success this wall deletes. A RECEIVER WITH NO AUTHORED NAME AT ALL is not weak evidence about the method — it is no evidence about anything, because the receiver's own type was never established upstream. That is a different judgment failure from 'this receiver has a surface and the method is not on it', so it carries its own diagnostic, ReceiverTypeUnestablished, whose message names that cause instead of implying the method is missing. THE DIAGNOSTIC NAMES THE CAUSE; THE ROSTER BOUNDS THE ADMISSION, and separating those two was a correction. The class was first admitted on the CAUSE alone — any anonymous receiver, non-blocking — on the reasoning that the wall cannot tell an existing method from a nonexistent one when the receiver has no type, so refusing would refuse both. That reasoning is sound about DECIDABILITY and wrong about ADMISSION: it made every future anonymous-receiver call green, including one whose method does not exist, so the exception was unbounded exactly where existence is unknown (codex review 45459). Counting a diagnostic does not stop invalid code reaching the live system. Admission is now gated on the same declared roster as every other unestablished shape, keyed (module, method, Primitive()), so the seven measured occurrences are admitted and a new one anywhere else REFUSES as MethodExistenceUndecided. That is a ratchet that can only shrink, and blocking a new instance of a known deficit is the factory model rather than an inconvenience. Everything that has a name but no surface stays in the same shape-keyed roster. MethodExistenceUndecided carries what is left as a typed, located, COUNTED non-blocking diagnostic (the is_error_diagnostic partition, UnlistedImportUse precedent) so the frequency stays observable and prioritizable rather than zeroed by construction — and it now means exactly ONE thing, receiver surface not established, rather than doubling as a name-grain escape. Both arms return error_type, never recv_rt, so one located refusal does not cascade downstream. AND THE WALL IS REACHED FROM EVERY ARM, WHICH IT WAS NOT AT FIRST: the decision lived inline in the final else of method_pipe_map_keys_values_fallback, so an unresolved map_keys, sorted_map_keys or map_values whose receiver is not a keyed collection took an EARLIER branch and returned recv_rt with an empty diagnostic list — the identical success-shaped fallback this wall exists to delete, preserved in the two special cases that ran before it (codex review 45430). A wall reachable only from the default arm is not a wall, and prose about the default arm cannot see the two arms in front of it. The decision is now method_existence_decision, held once and called from all three, with the control run against the prior binary rather than reasoned about: List |> map_keys and |> map_values compile with exit 0 on the pre-routing binary and produce two located MethodNotFound refusals on this one. Positive controls: map/filter/fold/flat_map resolve at tier0 and service ops at tier1, neither reaching this arm. THE UPSTREAM DEFECTS ARE NAMED BY THE MEASUREMENT, one fixed here and the rest left as promotion triggers that would each let the wall decide a further non-kernel receiver: (1) FIXED — a where-refinement alias resolving to a Product shape instead of peeling to its declared base before method lookup; (2) a lambda parameter receiver whose type never propagates from the declared fn type it is bound under; (3) a coproduct payload binding typed as the VARIANT name rather than the field type; (4) an optional receiver whose cardinality is dropped so the inner product reaches lookup in place of Optional own surface. Each is carried as a row in unresolved_method_frontier, keyed on the receiver shape that is the evidence for it, except (2) which is the ReceiverTypeUnestablished cause class above. THE INSTRUMENT WAS WRONG BEFORE THE WALL WAS, and that is the most transferable thing here: this wall was measured with `gunbc run --entry dag/tools/generated_artifact_gate.dag`, which reaches only that gate's import closure, and it reported CLEAN while twelve real sites sat outside it — they surfaced from CI instead. The whole-corpus instrument is `gunbc compile --source-root dag --source-root src/v2 --target dag`, the same compile-clean gate CI runs, and it resolves 1629 sources against 2740 indexed modules. A narrow instrument reporting clean is indistinguishable from a wall that works, which is the §5 specification-without-execution trap wearing the shape of a green run. A FOURTH SHAPE was then found and NOT fixed: a brand alias can also arrive as a plain qualified LEAF (Primitive(std.types.NonEmptyStr)) rather than the refinement Conj the peel walks. Three head-resolution strategies were implemented and measured against it — lookup_type_for on the node, lookup_type_by_name on the qualified name, and on its last segment — none recovered the refinement, so the machinery was DELETED rather than shipped unproven and the site is a declared row. Unproven machinery that decides nothing is worse than a declared row that admits what it cannot decide. Dissolve-on: primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete surface, the count-style forks are unwritable rather than hand-reconciled, and MethodExistenceUndecided is deleted.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn where_refinement_receiver_peel_note() -> String { - thread_local! { - static CACHED: String = { - "A where-refinement type is a Conj carrying its base as its single child and its predicates in type_annotation, and resolve_method_receiver_type SHORT-CIRCUITS on connective == Conj — it treats any product as already-structural and returns it untouched. So NonEmptyStr, declared `String where non_empty`, reached method lookup as Product(NonEmptyStr) and String's algebra profile was never consulted: `.length()` on a branded string had no surface to resolve against and no surface to prove absence against either, which put 12 correct corpus sites (8 in extdeps.filesystem.linux, 4 across gunbc.design) in the wall's undecided residue. This peel is the fix, and the FIRST version of it was a §3 violation that this note asserted its way past — worth recording, because the note is where the defect actually lived. It hand-rolled a second recursive walker over the Conj/annotation/single-child shape and then CLAIMED, in this sentence, that the refinement chain had one traversal authority and the peel was its second consumer. Both walkers independently encoded the shape test, the lookup_type_for base resolution and the recursion, so they could drift apart silently; the prose asserted the property instead of the code establishing it (codex review 45410). WHY THESE READ NODE STORAGE DIRECTLY, since it is asked and the answer is not a per-function one: they are 2 of the 589 direct Node-storage reads in this file (579 of them on origin/main), which is the v1 seed's pervasive and only idiom — the seed IS the traversal, the stage that walks the tree so that later stages need not. There is no canonical query or fold surface reachable from here: fold_node and node_query live in src/v2/std, no v1 seed module imports v2 at all, and v1 COMPILES v2, so routing v1 inference through v2's fold inverts the bootstrap rather than tidying it. DESIGN's fold_node line is scoped to the 7 v2 stages and is a DRY example within v2, not a rule binding the seed. So the disposition here is the SEED'S disposition, the same trigger the hand-Rust receipt carries — the v1 seed shrinks to zero at v2 self-host and these dissolve with it — and attaching a separate per-function trigger to 2 reads while 587 identical reads beside them carry none would be a fabricated bound, describing separable work that does not exist (codex review 45570). The repair is the extraction the claim described: where_refinement_chain is the one walk, it yields the refinement chain from the surface alias down to its ground base, and it has exactly two consumers — type_where_refinement_predicates_transitive flat_maps the immediate predicates over the chain, and peel_where_refinement_base takes its last link. The shape test itself is is_where_refinement_type, held once. Now there is one traversal authority, and it is one because the code says so. It runs only where the wall was already about to refuse or admit, so no previously-resolving call changes meaning; tier0 keeps first claim on the unpeeled receiver, which is what preserves a method declared on the brand itself. The consequence that matters is not that 12 sites went green — it is that they became DECIDABLE IN BOTH DIRECTIONS: once the peeled receiver is kernel-profiled, a method genuinely absent from String now refuses as MethodNotFound instead of resting in the frontier. Widening what the wall can decide is the only move that shrinks the frontier without either fabricating a success or fabricating a refusal.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct UnresolvedMethodFrontierRow { - pub module_name: String, - pub method: String, - pub receiver_shape: String, - pub occurrences: i64, - pub cause: String, - pub dissolution: Rc, -} - -pub fn unresolved_method_frontier() -> Rc>> { - Rc::new(vec![Rc::new(UnresolvedMethodFrontierRow { - module_name: "v2.compiler.tokenize".to_string(), - method: "apply".to_string(), - occurrences: 7, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is a lambda parameter whose type is never inferred, so it arrives with NO authored name at all. The call is a product FIELD holding a callable — the LexMatchThunk { apply: fn(s) } idiom — not a method at all.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing, so the receiver resolves to its declared product and apply is found as a field".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.git.object_store".to_string(), - method: "map".to_string(), - occurrences: 2, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is `tree.entries` where `tree` is the parameter of a lambda stored in a StoreObjectFold record field, so the field's declared fn type never reaches the lambda's parameter and the projection off it has no established type.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.git.object_store".to_string(), - method: "flat_map".to_string(), - occurrences: 1, - receiver_shape: "Primitive()".to_string(), - cause: "same StoreObjectFold lambda-parameter shape as the `map` row above; listed separately because the key names one method on one receiver shape, never a module-wide pass.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.mercurial".to_string(), - method: "any".to_string(), - occurrences: 3, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is an untyped parameter of a lambda stored in a fold record field, the same shape as the object_store rows.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "gunbc.scm_compatibility.mercurial".to_string(), - method: "map".to_string(), - occurrences: 3, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is `missing_changesets`, an untyped parameter of the `partial:` lambda in a MercurialRepositoryCompletenessFold record field.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.dns.domain_name".to_string(), - method: "list_push".to_string(), - occurrences: 1, - receiver_shape: "Primitive(ok)".to_string(), - cause: "receiver is a coproduct payload bound by pattern destructuring, which arrives typed as the VARIANT name rather than the field type.".to_string(), - dissolution: unbound_dissolution("coproduct payload binding typed as the field type, at which point the receiver is List and DECIDABLE".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "v1.compiler.trace".to_string(), - method: "map".to_string(), - occurrences: 1, - receiver_shape: "Product(SpanMapping)".to_string(), - cause: "receiver is an Optional produced by `|> last`, and the optional functor is being mapped over. It arrives as the INNER product because the optional cardinality is dropped before method lookup, so Optional's own surface is never consulted.".to_string(), - dissolution: unbound_dissolution("reconciling the two optionality representations (cardinality-marked node vs the nominal Optional coproduct) so an optional receiver keeps its optional surface at method lookup".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "gunbc.source_integration_landing_spine".to_string(), - method: "map".to_string(), - occurrences: 1, - receiver_shape: "Node(Optional)".to_string(), - cause: "same optional-functor class as the v1.compiler.trace row, in its OTHER surface form: here the Optional survives as a named node rather than collapsing to its inner product, and neither form carries a method surface. Two shapes for one concept is itself the defect the trigger names.".to_string(), - dissolution: unbound_dissolution("reconciling the two optionality representations so an optional receiver keeps its optional surface at method lookup".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "test.claim.sccache_local_content_verified_on_read".to_string(), - method: "contains".to_string(), - occurrences: 1, - receiver_shape: "Primitive(std.types.NonEmptyStr)".to_string(), - cause: "the brand-alias class in its LEAF form. The receiver is a coproduct variant payload whose declared type is NonEmptyStr, and it arrives not as the refinement Conj the peel walks but as a plain leaf carrying the QUALIFIED name std.types.NonEmptyStr — so there is no refinement chain to descend and no kernel profile under that name. Three head-resolution strategies were tried against this site and measured: resolving the leaf through lookup_type_for, through lookup_type_by_name on the qualified name, and on its last segment. NONE of them recovered the refinement, so the machinery was deleted rather than shipped unproven, and the site is declared here instead. Why the peel reaches the Conj form but not this one is not yet understood, and saying so is more useful than a fourth guess.".to_string(), - dissolution: unbound_dissolution("one representation for a brand alias at method lookup — the same reconciliation the conformance wall's class (2) names — so the leaf and Conj forms stop being two shapes for one concept".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "v2.std.compilers.target_model".to_string(), - method: "lookup".to_string(), - occurrences: 1, - receiver_shape: "Primitive(T)".to_string(), - cause: "receiver is a bare type variable. This one is genuinely undecidable at this seam rather than a resolution defect: nothing establishes what T offers.".to_string(), - dissolution: unbound_dissolution("primitive-realization-single-authority, giving every receiver a complete declared method surface".to_string()), -})]) -} - -pub fn frontier_diag_matches_row( - d: Rc, - method: String, - receiver_shape: String, -) -> bool { - match diagnostic_frontier_occurrence_key(d.clone()) { - Some(key) => { - ((key.method.clone() == method.clone()) - && (key.receiver_shape.clone() == receiver_shape.clone())) - } - None => false, - } -} - -pub fn frontier_row_observed( - diagnostics: Rc>>, - method: String, - receiver_shape: String, -) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for e in diagnostics.clone().iter().cloned() { - if frontier_diag_matches_row( - e.diagnostic.clone(), - method.clone(), - receiver_shape.clone(), - ) { - __result.push(e); - } - } - __result - }) -} - -pub fn frontier_row_budget_span( - observed: Rc>>, - module_span: Rc, -) -> Rc { - match observed.clone().first().cloned() { - Some(witness) => diagnostic_to_span(witness.diagnostic.clone()), - None => module_span, - } -} - -pub fn frontier_row_budget_diags( - row: Rc, - diagnostics: Rc>>, - module_name: String, - module_span: Rc, -) -> Rc>> { - if ((frontier_row_observed( - diagnostics.clone(), - row.method.clone(), - row.receiver_shape.clone(), - ) - .len() as i64) - == row.occurrences.clone()) - { - Rc::new(vec![]) - } else { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::FrontierOccurrenceBudgetExceeded { - method: row.method.clone(), - receiver_type: row.receiver_shape.clone(), - declared: row.occurrences.clone(), - observed: (frontier_row_observed( - diagnostics.clone(), - row.method.clone(), - row.receiver_shape.clone(), - ) - .len() as i64), - span: frontier_row_budget_span( - frontier_row_observed( - diagnostics.clone(), - row.method.clone(), - row.receiver_shape.clone(), - ), - module_span.clone(), - ), - }), - module_name.clone(), - )]) - } -} - -pub fn frontier_occurrence_budget_diags( - module_name: String, - module_span: Rc, - diagnostics: Rc>>, -) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for r in Rc::new({ - let mut __result = Vec::new(); - for r in unresolved_method_frontier().iter().cloned() { - if (r.module_name.clone() == module_name.clone()) { - __result.push(r); - } - } - __result - }) - .iter() - .cloned() - { - __result.extend( - (*frontier_row_budget_diags( - r.clone(), - diagnostics.clone(), - module_name.clone(), - module_span.clone(), - )) - .iter() - .cloned(), - ); - } - __result - }) -} - -pub fn frontier_occurrence_budget_note() -> String { - thread_local! { - static CACHED: String = { - "THE COUNT IS WHAT MAKES THE FRONTIER A RATCHET INSTEAD OF AN EXEMPTION. Keying admission on (module, method, receiver_shape) bounds WHERE an unresolved call may live but not HOW MANY may live there, so a second call in the same module, on the same method, failing to resolve the same way, inherited the admission — and that is not hypothetical: the measured rows are not all singletons (v2.compiler.tokenize admits seven `apply` calls, extdeps.mercurial three `any`, gunbc.scm_compatibility.mercurial three `map`), so a row admitting seven would silently admit an eighth (codex review 45464). Each row therefore declares its MEASURED occurrence count and this fold refuses the excess, located on the first offending call. THE COMPARISON IS EQUALITY, AND IT WAS FIRST WRITTEN AS A CEILING, WHICH DID NOT RATCHET. `observed > declared` was justified here on the reasoning that a narrower compile closure sees fewer occurrences of a module's rows, so equality would red a partial build. That reasoning is WRONG about this check: it runs per MODULE, and every occurrence of a module's rows is present whenever that module is typechecked at all — a closure that omits the module never runs its rows, so there is no partial-visibility case to protect. What the ceiling actually did was let seven shrink to six while the declared seven stood, so a seventh call could return silently: a static limit, not a ratchet, and the note claimed the ratchet anyway (codex review 45491). Equality closes it in the only way that works — fixing a call reds until the declared count is lowered, which removes the headroom a reintroduction would have slipped into. Both directions are asserted in the witness, because the under-count half is the half that makes it a ratchet and it is the one an author is tempted to relax. WHY NOT A STABLE PER-OCCURRENCE KEY, which would close this exactly: std.occurrence_identity is the corpus authority for occurrence identity and its own scope law forbids filename, SourceSpan, authored name, structural Node equality and content hash as identity inputs, allocating OccurrenceId inside one graph-scoped allocator instead. An allocator-assigned integer cannot appear as a literal in a declared row, because it is not stable across compiles — so a per-occurrence key is not merely unimplemented here, it is unavailable from the authority that owns the concept. The count is the strongest bound the substrate currently supports. Dissolve-on: a content-addressed occurrence identity stable across edits (the namespace lane's containment addressing), at which point rows key on the occurrence itself and the count field deletes.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn frontier_occurrence_budget_checked( - module_name: String, - module_span: Rc, - diagnostics: Rc>>, -) -> Rc>> { - v1_rt::concat( - diagnostics.clone(), - frontier_occurrence_budget_diags( - module_name.clone(), - module_span.clone(), - diagnostics.clone(), - ), - ) -} - -pub fn unresolved_method_frontier_trigger( - module_name: String, - method: String, - receiver_shape: String, -) -> Option> { - match Rc::new({ - let mut __result = Vec::new(); - for r in unresolved_method_frontier().iter().cloned() { - if (((r.module_name.clone() == module_name.clone()) - && (r.method.clone() == method.clone())) - && (r.receiver_shape.clone() == receiver_shape.clone())) - { - __result.push(r); - } - } - __result - }) - .first() - .cloned() - { - Some(row) => Some(row.dissolution.clone()), - None => None, - } -} - -pub fn unresolved_method_frontier_note() -> String { - thread_local! { - static CACHED: String = { - "The declared frontier for method calls whose receiver establishes NO method surface even after where-refinement peeling (DESIGN §7: a declared row with a reason and a migration trigger, countable and prioritizable, never a silent escape hatch). WHY A ROSTER AT ALL: MethodExistenceUndecided BLOCKS. Leaving the undecided class non-blocking meant emittable_graph still emitted code containing a method whose existence was never established — the same fail-open the wall claims to close, correctly refused twice in review (codex reviews 45357 and 45383). Blocking it outright was not available either: the residue is CORRECT, WORKING code, seven sites of it the v2 tokenizer own LexMatchThunk { apply: fn(s) } idiom, so a blanket refusal would refuse the compiler v2 is migrating to — fabricating a refusal, which §5 forbids exactly as it forbids fabricating a success. THE KEY IS (module, method, receiver_shape), AND THE THIRD COMPONENT IS THE CORRECTION. A (module, method) key was shipped first and was wrong on two counts, one found by review and one by execution, which is worth recording because they are the same defect seen from two sides. Review found it as a fail-open: any NEW apply call in v2.compiler.tokenize would inherit the pass even on a fully resolved receiver, so the note claim that no new fail-open can enter was false (codex review 45398). Execution found it as an UNDERCOUNT: the roster was measured over the v1 self-compile closure alone, and the first whole-corpus run reded seven sites in three modules the roster had never seen. Both dissolve into the same fix — the frontier admits a receiver whose surface could not be established, so the SHAPE of that receiver is the evidence, and keying on it means a new call refuses unless it reproduces the exact unestablished shape the row was measured on. The residue after that is 13 sites in four shapes: Primitive() with no authored name (a lambda parameter whose type never propagates, 10 sites), Primitive(T) (a bare type variable), Primitive(ok) (a coproduct payload typed as its variant name), and a Product that is really an Optional whose cardinality was dropped. Every one is an upstream receiver-resolution defect, not a method-existence fact, which is exactly why the wall cannot decide them and why each row names the resolution fix rather than a permanent exemption. Admitted rows still emit MethodExistenceFrontierAdmitted, counted and carrying its own trigger, so the frequency stays observable rather than zeroed by construction (§5). THE RESIDUAL WIDENING, STATED RATHER THAN CLAIMED AWAY: a second unresolved call to the same method, in the same module, on a receiver that fails to resolve in the same way, is still admitted. That is narrower than the module-wide pass it replaces and it is not zero. Closing it entirely needs an occurrence identity stable across edits — content-addressed, not line-anchored — which is the same containment/content-hash authority the namespace lane is landing; until then the honest bound is this key, and the peel above is the mechanism that actually SHRINKS the frontier rather than administering it.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn categorized_error( - message: String, - span: Rc, - module_name: String, - category: String, -) -> Rc { - make_error_node( - Rc::new(CompilerDiagnostic::InternalError { - message: message.clone(), - span: span.clone(), - }), - module_name.clone(), - ) -} - -pub fn validate_cast( - source_inferred: Option>, - target_name: String, - span: Rc, - source_indices: Rc>>, - module_name: String, -) -> Option> { - match source_inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: src_node, .. }) => { - let source_name = authored_name_at(source_indices.clone(), src_node.clone()); - if (source_name.clone() == target_name.clone()) { - None - } else { - if !is_dag_cast_domain_type(source_name.clone()) { - None - } else { - if !is_dag_cast_domain_type(target_name.clone()) { - None - } else { - if dag_can_cast(source_name.clone(), target_name.clone()) { - None - } else { - { - let msg = v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - "invalid cast: ".to_string(), - source_name.clone(), - ), - " as ".to_string(), - ), - target_name.clone(), - ); - let diag = Rc::new(CompilerDiagnostic::InternalError { - message: msg.clone(), - span: span.clone(), - }); - Some(make_error_node(diag.clone(), module_name.clone())) - } - } - } - } - } - } - _ => None, - } -} - -pub fn optional_cast_diags( - source_inferred: Option>, - target_type: Rc, - span: Rc, - source_indices: Rc>>, - module_name: String, -) -> Rc>> { - match source_inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: src_node, .. }) => { - let source_name = authored_name_at(source_indices.clone(), src_node.clone()); - let source_is_optional = ((src_node.return_cardinality.clone() - == Cardinality::CardOptional) - || (qualified_last_segment(source_name.clone()) == "Optional".to_string())); - let target_is_optional = - (target_type.return_cardinality.clone() == Cardinality::CardOptional); - if (source_is_optional.clone() && !target_is_optional.clone()) { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::OptionalCastNotEliminated { - source_type: v1_rt::concat(source_name.clone(), "?".to_string()), - target_type: authored_name_at(source_indices.clone(), target_type.clone()), - span: span.clone(), - }), - module_name.clone(), - )]) - } else { - Rc::new(vec![]) - } - } - _ => Rc::new(vec![]), - } -} - -pub fn type_variable_node(id: String) -> Rc { - Rc::new(Node { - name: "".to_string(), - span: no_span(), - ident_span: None, - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: Some(Rc::new(InferredNode::TypeVariable { id: id.clone() })), - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }) -} - -pub fn is_type_variable(inferred: Rc) -> bool { - match (*inferred.clone()).clone() { - InferredNode::TypeVariable { id: _, .. } => true, - _ => false, - } -} - -pub fn inferred_or_error( - result: Option>, - fallback_message: String, - fallback_span: Rc, -) -> Rc { - match result.clone() { - Some(inferred) => inferred.clone(), - None => Rc::new(InferredNode::CompilerError { - message: fallback_message.clone(), - span: fallback_span.clone(), - }), - } -} - -pub fn resolve_pattern_subject( - scope: Rc, - scrutinee_subject: Rc, -) -> Rc { - match (*scrutinee_subject.clone()).clone() { - PatternSubject::PatternResolved { - node: scrutinee_type, - .. - } => pattern_subject_from_node(preserve_outer_optional_cardinality( - scrutinee_type.clone(), - resolve_scrutinee_type_node(scope.type_env.clone(), scrutinee_type.clone()), - )), - PatternSubject::PatternDynamic { - span: dynamic_span, .. - } => Rc::new(PatternSubject::PatternDynamic { - span: dynamic_span.clone(), - }), - PatternSubject::PatternLookupBlocked => Rc::new(PatternSubject::PatternLookupBlocked), - } -} - -pub fn annotate_pattern_parent_enums( - pattern: Rc, - scrutinee_subject: Rc, - scope: Rc, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*pattern.clone()).clone() { - MatchPattern::VariantPattern { - name: variant_name, - field_bindings: bindings, - .. - } => { - let resolved_scrut = - resolve_pattern_subject(scope.clone(), scrutinee_subject.clone()); - let inferred_parent = match (*resolved_scrut.clone()).clone() { - PatternSubject::PatternResolved { - node: resolved_scrut_node, - .. - } => { - let scrutinee_name = authored_name_at( - scope.type_env.clone().source_indices.clone(), - resolved_scrut_node.clone(), - ); - let optional_cardinality_subject = - ((resolved_scrut_node.return_cardinality.clone() - == Cardinality::CardOptional) - && (scrutinee_name.clone() != "Optional".to_string())); - let optional_coproduct_subject = ((scrutinee_name.clone() - == "Optional".to_string()) - && ((variant_name.clone() == "Present".to_string()) - || (variant_name.clone() == "Absent".to_string()))); - let witness_container_subject = - (is_witness_type_name(scrutinee_name.clone()) - && ((variant_name.clone() == "Holds".to_string()) - || (variant_name.clone() == "Violates".to_string()))); - if ((optional_cardinality_subject.clone() - || optional_coproduct_subject.clone()) - && ((variant_name.clone() == "Present".to_string()) - || (variant_name.clone() == "Absent".to_string()))) - { - Some("Optional".to_string()) - } else { - if witness_container_subject.clone() { - Some("Witness".to_string()) - } else { - { - let is_coproduct = (resolved_scrut_node.connective.clone() - == Connective::Disj); - if is_coproduct.clone() { - Some(scrutinee_name.clone()) - } else { - None - } - } - } - } - } - PatternSubject::PatternDynamic { span: _, .. } => None, - PatternSubject::PatternLookupBlocked => None, - }; - let annotated_variant_name = variant_name.clone(); - let variant_lookup = lookup_variant_in_type( - resolved_scrut.clone(), - variant_name.clone(), - scope.module_name.clone(), - scope.type_env.clone(), - (bindings.clone().len() as i64), - ); - let variant_subject = lookup_result_subject(variant_lookup.clone()); - let annotated_bindings = Rc::new({ - let mut __result = Vec::new(); - for binding in bindings.clone().iter().cloned() { - __result.push({ - let field_lookup = lookup_field_in_variant( - variant_subject.clone(), - field_binding_name_at( - binding.clone(), - scope.type_env.clone().source_indices.clone(), - ), - scope.module_name.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let field_subject = lookup_result_subject(field_lookup.clone()); - make_field_binding_node( - field_binding_name_at( - binding.clone(), - scope.type_env.clone().source_indices.clone(), - ), - annotate_pattern_parent_enums( - field_binding_pattern(binding.clone()), - field_subject.clone(), - scope.clone(), - ), - binding.span.clone(), - node_name_span(binding.clone()), - ) - }); - } - __result - }); - match inferred_parent.clone() { - Some(parent_name) => Rc::new(MatchPattern::VariantPattern { - name: annotated_variant_name.clone(), - parent_enum: Some(parent_name.clone()), - field_bindings: annotated_bindings.clone(), - }), - None => Rc::new(MatchPattern::VariantPattern { - name: variant_name.clone(), - parent_enum: None, - field_bindings: annotated_bindings.clone(), - }), - } - } - _ => pattern.clone(), - } - }) -} - -pub fn build_params_scope(scope: Rc, params: Rc>>) -> Rc { - { - let new_locals = params.clone().iter().cloned().fold( - scope.locals.clone(), - |acc: Rc>>, p: Rc| { - v1_rt::rc_map_insert( - acc, - param_node_name_at(p.clone(), scope.type_env.clone().source_indices.clone()), - Rc::new(TypeBinding { - name: param_node_name_at( - p.clone(), - scope.type_env.clone().source_indices.clone(), - ), - resolved: param_node_type_expr(p.clone()), - provenance: Rc::new(SubValueRelation::PreservedValue), - }), - ) - }, - ); - let new_body_locals = params.clone().iter().cloned().fold( - scope.body_locals.clone(), - |acc: Rc>, p: Rc| { - v1_rt::rc_map_insert( - acc, - param_node_name_at(p.clone(), scope.type_env.clone().source_indices.clone()), - true, - ) - }, - ); - Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: new_locals.clone(), - body_locals: new_body_locals.clone(), - match_bound_names: scope.match_bound_names.clone(), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: scope.caller_decl_name.clone(), - lambda_param_provenance: v1_rt::rc_empty_map::>(), - }) - } -} - -pub fn extend_scope( - scope: Rc, - name: String, - resolved: Rc, - provenance: Rc, -) -> Rc { - Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: v1_rt::rc_map_insert( - scope.locals.clone(), - name.clone(), - Rc::new(TypeBinding { - name: name.clone(), - resolved: resolved.clone(), - provenance: provenance.clone(), - }), - ), - body_locals: v1_rt::rc_map_insert(scope.body_locals.clone(), name.clone(), true), - match_bound_names: scope.match_bound_names.clone(), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: scope.caller_decl_name.clone(), - lambda_param_provenance: scope.lambda_param_provenance.clone(), - }) -} - -pub fn extend_scope_match_bound( - scope: Rc, - name: String, - resolved: Rc, - provenance: Rc, -) -> Rc { - Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: v1_rt::rc_map_insert( - scope.locals.clone(), - name.clone(), - Rc::new(TypeBinding { - name: name.clone(), - resolved: resolved.clone(), - provenance: provenance.clone(), - }), - ), - body_locals: v1_rt::rc_map_insert(scope.body_locals.clone(), name.clone(), true), - match_bound_names: v1_rt::rc_map_insert( - scope.match_bound_names.clone(), - name.clone(), - true, - ), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: scope.caller_decl_name.clone(), - lambda_param_provenance: scope.lambda_param_provenance.clone(), - }) -} - -pub fn extend_scope_with_params(scope: Rc, params: Rc>) -> Rc { - { - let new_locals = params.clone().iter().cloned().fold( - scope.locals.clone(), - |acc: Rc>>, p: String| { - v1_rt::rc_map_insert( - acc, - p.clone(), - Rc::new(TypeBinding { - name: p.clone(), - resolved: type_variable_node("lambda_param".to_string()), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - }, - ); - let new_body_locals = params.clone().iter().cloned().fold( - scope.body_locals.clone(), - |acc: Rc>, p: String| v1_rt::rc_map_insert(acc, p.clone(), true), - ); - Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: new_locals.clone(), - body_locals: new_body_locals.clone(), - match_bound_names: scope.match_bound_names.clone(), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: scope.caller_decl_name.clone(), - lambda_param_provenance: scope.lambda_param_provenance.clone(), - }) - } -} - -pub fn scope_after_stmt_node( - stmt: Rc, - stmt_type: Rc, - scope: Rc, -) -> Rc { - match (*stmt.expr_data.clone()).clone() { - ExprData::ExprLet => { - if ((stmt.children.clone().len() as i64) <= 1) { - { - let val = match stmt.children.clone().first().cloned() { - Some(v) => v.clone(), - None => stmt.clone(), - }; - extend_scope( - scope.clone(), - let_binding_name_at( - stmt.clone(), - scope.type_env.clone().source_indices.clone(), - ), - stmt_type.clone(), - classify_binding_provenance(val.clone(), scope.clone()), - ) - } - } else { - scope.clone() - } - } - _ => scope.clone(), - } -} - -pub fn derive_field_provenance( - scope: Rc, - scrutinee_provenance: Rc, - scrutinee_subject: Rc, - variant_name: String, - field_name: String, -) -> Rc { - match (*scrutinee_provenance.clone()).clone() { - SubValueRelation::SubValueUnknown => Rc::new(SubValueRelation::SubValueUnknown), - _ => { - let scrut_type_name = match (*scrutinee_subject.clone()).clone() { - PatternSubject::PatternResolved { node: n, .. } => authored_name_at( - scope.type_env.clone().source_indices.clone(), - resolved_type(n.clone()), - ), - _ => "".to_string(), - }; - if (scrut_type_name.clone() == "".to_string()) { - Rc::new(SubValueRelation::SubValueUnknown) - } else { - { - let ind_fields = - inductive_fields_for(scope.type_env.clone(), scrut_type_name.clone()); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in ind_fields.clone().iter().cloned() { - if ((f.variant_name.clone() == variant_name.clone()) - && (f.field_name.clone() == field_name.clone())) - { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => { - compose_sub_value(scrutinee_provenance.clone(), ind_field.clone()) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - } - } - } -} - -pub fn extend_scope_with_pattern_node( - scope: Rc, - pattern: Rc, - scrutinee_subject: Rc, - scrutinee_provenance: Rc, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*pattern.clone()).clone() { - MatchPattern::Bind { - declaration: declaration, - .. - } => Rc::new(PatternScopeResult { - scope: extend_scope_match_bound( - scope.clone(), - declaration.name.clone(), - pattern_binding_type(scrutinee_subject.clone()), - scrutinee_provenance.clone(), - ), - diagnostics: Rc::new(vec![]), - }), - MatchPattern::Wildcard => Rc::new(PatternScopeResult { - scope: scope.clone(), - diagnostics: Rc::new(vec![]), - }), - MatchPattern::LitPattern { value: _, .. } => Rc::new(PatternScopeResult { - scope: scope.clone(), - diagnostics: Rc::new(vec![]), - }), - MatchPattern::VariantPattern { - name: vname, - field_bindings: bindings, - .. - } => { - let resolved_scrut = - resolve_pattern_subject(scope.clone(), scrutinee_subject.clone()); - let variant_lookup = lookup_variant_in_type( - resolved_scrut.clone(), - vname.clone(), - scope.module_name.clone(), - scope.type_env.clone(), - (bindings.clone().len() as i64), - ); - let variant_subject = lookup_result_subject(variant_lookup.clone()); - let variant_diags = variant_lookup.diagnostics.clone(); - bindings.clone().iter().cloned().fold( - Rc::new(PatternScopeResult { - scope: scope.clone(), - diagnostics: variant_diags.clone(), - }), - |acc: Rc, fb: Rc| { - let field_name = field_binding_name_at( - fb.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let field_lookup = lookup_field_in_variant( - variant_subject.clone(), - field_name.clone(), - scope.module_name.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let field_subject = lookup_result_subject(field_lookup.clone()); - let field_type = pattern_binding_type(field_subject.clone()); - let field_provenance = derive_field_provenance( - scope.clone(), - scrutinee_provenance.clone(), - scrutinee_subject.clone(), - vname.clone(), - field_name.clone(), - ); - let fb_pattern = field_binding_pattern(fb.clone()); - match (*fb_pattern.clone()).clone() { - MatchPattern::Bind { - declaration: declaration, - .. - } => Rc::new(PatternScopeResult { - scope: extend_scope_match_bound( - acc.scope.clone(), - declaration.name.clone(), - field_type.clone(), - field_provenance.clone(), - ), - diagnostics: v1_rt::concat( - acc.diagnostics.clone(), - field_lookup.diagnostics.clone(), - ), - }), - _ => { - let nested = extend_scope_with_pattern_node( - acc.scope.clone(), - fb_pattern.clone(), - field_subject.clone(), - field_provenance.clone(), - ); - Rc::new(PatternScopeResult { - scope: nested.scope.clone(), - diagnostics: v1_rt::concat( - acc.diagnostics.clone(), - v1_rt::concat( - field_lookup.diagnostics.clone(), - nested.diagnostics.clone(), - ), - ), - }) - } - } - }, - ) - } - } - }) -} - -pub fn method_name_is(opt: Option, expected: String) -> bool { - if (opt.clone() == None) { - false - } else { - (opt.clone().unwrap() == expected.clone()) - } -} - -pub fn arg_has_name( - arg: Rc, - name: String, - source_indices: Rc>>, -) -> bool { - { - let n = arg_name_at(arg.clone(), source_indices.clone()); - if (n.clone() == None) { - false - } else { - (n.clone().unwrap() == name.clone()) - } - } -} - -pub fn extract_fold_init_info( - method_name: Option, - method_args: Rc>>, - min_args: i64, - scope: Rc, - expected: Option>, -) -> Option> { - { - let is_fold = method_name_is(method_name.clone(), "fold".to_string()); - if (is_fold.clone() && ((method_args.clone().len() as i64) >= min_args.clone())) { - { - let init_arg = match Rc::new({ - let mut __result = Vec::new(); - for a in method_args.clone().iter().cloned() { - if arg_has_name( - a.clone(), - "init".to_string(), - scope.type_env.clone().source_indices.clone(), - ) { - __result.push(a); - } - } - __result - }) - .first() - .cloned() - { - Some(a) => Some(a.clone()), - None => method_args.clone().first().cloned(), - }; - match init_arg.clone() { - Some(ia) => { - let init_result = - infer_expr(arg_value(ia.clone()), scope.clone(), expected.clone()); - Some(Rc::new(ArgInferResult { - typed_arg: make_arg_node( - arg_name_at( - ia.clone(), - scope.type_env.clone().source_indices.clone(), - ), - init_result.typed.clone(), - ia.span.clone(), - ia.span.clone(), - ), - diagnostics: init_result.diagnostics.clone(), - })) - } - None => None, - } - } - } else { - None - } - } -} - -pub fn derive_element_provenance( - coll_expr: Rc, - elem_type: Rc, - scope: Rc, -) -> Rc { - { - let coll_prov = classify_binding_provenance(coll_expr.clone(), scope.clone()); - match (*coll_prov.clone()).clone() { - SubValueRelation::SubValueUnknown => Rc::new(SubValueRelation::SubValueUnknown), - _ => { - if (authored_name_at( - scope.type_env.clone().source_indices.clone(), - elem_type.clone(), - ) == "".to_string()) - { - Rc::new(SubValueRelation::SubValueUnknown) - } else { - { - let ind_fields = inductive_fields_for( - scope.type_env.clone(), - authored_name_at( - scope.type_env.clone().source_indices.clone(), - elem_type.clone(), - ), - ); - let list_field = Rc::new({ - let mut __result = Vec::new(); - for f in ind_fields.clone().iter().cloned() { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, - } { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match list_field.clone() { - Some(f) => { - Rc::new(SubValueRelation::IteratedSubValue { field: f.clone() }) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - } - } - } - } -} - -pub fn infer_method_args_with_fold( - method_name: Option, - method_args: Rc>>, - fold_info: Option>, - fold_acc_type: Rc, - element_type: Rc, - elem_provenance: Rc, - arg_contract: Rc, - scope: Rc, -) -> Rc>> { - { - let is_fold = method_name_is(method_name.clone(), "fold".to_string()); - Rc::new({ - let mut __result = Vec::new(); - for idx_pair in Rc::new( - method_args - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.push({ - let a = idx_pair.1.clone(); -let idx = idx_pair.0.clone(); -let is_init_arg = (arg_has_name(a.clone(), "init".to_string(), scope.type_env.clone().source_indices.clone()) || ((arg_name_at(a.clone(), scope.type_env.clone().source_indices.clone()) == None) && (idx.clone() == 0))); -if ((is_fold.clone() && (fold_info.clone() != None)) && is_init_arg.clone()) { - match fold_info.clone() { - Some(fi) => fi.clone(), - None => infer_arg_with_element_type(a.clone(), element_type.clone(), scope.clone()), -} - } else { - if (is_fold.clone() && (fold_info.clone() != None)) { - { - let fold_params = Rc::new(vec![make_param_node("acc".to_string(), fold_acc_type.clone(), None, no_span(), no_span()), make_param_node("elem".to_string(), element_type.clone(), None, no_span(), no_span())]); -let fold_callable = Rc::new(Node { - name: "".to_string(), - span: no_span(), - ident_span: None, - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: fold_params.clone(), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, -}); -let lam_value = arg_value(a.clone()); -let prov_map = match (*elem_provenance.clone()).clone() { - SubValueRelation::SubValueUnknown => v1_rt::rc_empty_map::>(), - _ => v1_rt::rc_map_insert(v1_rt::rc_empty_map::>(), "elem".to_string(), elem_provenance.clone()), -}; -let fold_scope = Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: scope.locals.clone(), - body_locals: scope.body_locals.clone(), - match_bound_names: scope.match_bound_names.clone(), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: scope.caller_decl_name.clone(), - lambda_param_provenance: prov_map.clone(), -}); -let ar = infer_expr(lam_value.clone(), fold_scope.clone(), Some(fold_callable.clone())); -Rc::new(ArgInferResult { - typed_arg: make_arg_node(arg_name_at(a.clone(), scope.type_env.clone().source_indices.clone()), ar.typed.clone(), a.span.clone(), a.span.clone()), - diagnostics: ar.diagnostics.clone(), -}) -} - } else { - { - let nf_lam_value = arg_value(a.clone()); -let nf_prov_map = match (*elem_provenance.clone()).clone() { - SubValueRelation::SubValueUnknown => v1_rt::rc_empty_map::>(), - _ => v1_rt::rc_map_insert(v1_rt::rc_empty_map::>(), "elem".to_string(), elem_provenance.clone()), -}; -let nf_scope = if is_lambda_expr(nf_lam_value.clone()) { - Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: scope.locals.clone(), - body_locals: scope.body_locals.clone(), - match_bound_names: scope.match_bound_names.clone(), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: scope.caller_decl_name.clone(), - lambda_param_provenance: nf_prov_map.clone(), -}) - } else { - scope.clone() - }; -match (*arg_contract.clone()).clone() { - DeclaredArgContract::MethodUnresolved => infer_arg_with_element_type(a.clone(), element_type.clone(), nf_scope.clone()), - DeclaredArgContract::ContractUnavailable => { - let ar = infer_expr(nf_lam_value.clone(), nf_scope.clone(), None); -let contract_diag = categorized_error("no declared argument contract is available for this method call; refusing rather than substituting the receiver element type".to_string(), a.span.clone(), nf_scope.module_name.clone(), "method-arg-contract-unavailable".to_string()); -Rc::new(ArgInferResult { - typed_arg: make_arg_node(arg_name_at(a.clone(), nf_scope.type_env.clone().source_indices.clone()), ar.typed.clone(), a.span.clone(), a.span.clone()), - diagnostics: v1_rt::concat(ar.diagnostics.clone(), Rc::new(vec![contract_diag.clone()])), -}) -}, - DeclaredArgContract::ContractKnown { types: declared_types, .. } => match declared_types.clone().iter().cloned().skip(idx.clone() as usize).next() { - Some(declared_type) => infer_arg_with_element_type(a.clone(), declared_type.clone(), nf_scope.clone()), - None => { - let ar = infer_expr(nf_lam_value.clone(), nf_scope.clone(), None); -let contract_diag = categorized_error("no declared argument contract is available at this parameter position; refusing rather than substituting the receiver element type".to_string(), a.span.clone(), nf_scope.module_name.clone(), "method-arg-contract-unavailable".to_string()); -Rc::new(ArgInferResult { - typed_arg: make_arg_node(arg_name_at(a.clone(), nf_scope.type_env.clone().source_indices.clone()), ar.typed.clone(), a.span.clone(), a.span.clone()), - diagnostics: v1_rt::concat(ar.diagnostics.clone(), Rc::new(vec![contract_diag.clone()])), -}) -}, -}, -} -} - } - } -}); - } - __result - }) - } -} - -pub fn is_lambda_expr(e: Rc) -> bool { - match (*e.expr_data.clone()).clone() { - ExprData::ExprLambda => true, - _ => false, - } -} - -pub fn seed_override_map() -> Rc>> { - Rc::new(vec!["".to_string()]).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, k: String| { - v1_rt::rc_map_insert(acc, k.clone(), unit_type()) - }, - ) -} - -pub fn fold_override_map(key: String, value: Rc) -> Rc>> { - v1_rt::rc_map_insert(seed_override_map(), key.clone(), value.clone()) -} - -pub fn empty_override_map() -> Rc>> { - seed_override_map() -} - -pub fn infer_arg_with_element_type( - arg: Rc, - element_type: Rc, - scope: Rc, -) -> Rc { - { - let ar = infer_expr( - arg_value(arg.clone()), - scope.clone(), - Some(element_type.clone()), - ); - Rc::new(ArgInferResult { - typed_arg: make_arg_node( - arg_name_at(arg.clone(), scope.type_env.clone().source_indices.clone()), - ar.typed.clone(), - arg.span.clone(), - arg.span.clone(), - ), - diagnostics: ar.diagnostics.clone(), - }) - } -} - -pub fn binding_is_namespace_root_nominal(binding: Rc) -> bool { - (((binding.resolved.clone().name.clone() == binding.name.clone()) - && (binding.resolved.clone().connective.clone() == Connective::NoConnective)) - && ((binding.resolved.clone().children.clone().len() as i64) == 0)) -} - -pub fn spine_root_is_shadowed(scope: Rc, root: String) -> bool { - match v1_rt::map_get(&scope.locals.clone(), root.clone()) { - Some(root_binding) => !binding_is_namespace_root_nominal(root_binding.clone()), - None => false, - } -} - -pub fn qualified_value_projection( - texpr: Rc, - scope: Rc, - span: Rc, -) -> Option> { - match field_access_spine(texpr.clone(), scope.type_env.clone().source_indices.clone()) { - None => None, - Some(spine) => match spine_root_is_shadowed(scope.clone(), spine.root.clone()) { - true => None, - false => match symbol_index_lookup( - scope.type_env.clone().symbol_index.clone(), - spine.dotted.clone(), - ) { - None => None, - Some(decl) => { - let raw_value_type = match decl.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), - _ => match decl.type_annotation.clone() { - Some(ann) => ann.clone(), - None => decl.clone(), - }, - }; - let value_type = qualify_borrowed_type_names( - raw_value_type.clone(), - qualified_all_but_last(spine.dotted.clone()), - scope.type_env.clone(), - v1_rt::rc_empty_map::(), - ); - Some(ok_infer(make_named_expr_node( - spine.dotted.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(Rc::new(VarBindingKind::FunctionValueBinding)), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: value_type.clone(), - })), - span.clone(), - kernel_span(spine.dotted.clone()), - ))) - } - }, - }, - } -} - -pub fn infer_expr_body( - texpr: Rc, - scope: Rc, - expected: Option>, -) -> Rc { - match (*texpr.expr_data.clone()).clone() { - ExprData::ExprLiteral { value: lit, .. } => { - let span = texpr.span.clone(); - ok_infer(make_expr_node( - Rc::new(ExprData::ExprLiteral { value: lit.clone() }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: infer_literal_node(lit.clone()), - })), - span.clone(), - )) - } - ExprData::ExprError { kind, message, .. } => { - let span = texpr.span.clone(); - let diagnostics = match kind.clone() { - ExprErrorKind::CensusHeadsBodyStripped => Rc::new(vec![inference_error( - message.clone(), - span.clone(), - scope.module_name.clone(), - )]), - _ => Rc::new(vec![]), - }; - Rc::new(InferResult { - typed: make_expr_error_node(kind.clone(), message.clone(), span.clone()), - diagnostics: diagnostics.clone(), - }) - } - ExprData::ExprVar { - binding_kind: _, .. - } => { - let name = - expr_var_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let span = texpr.span.clone(); - match constructor_reference_admission_unshadowed( - name.clone(), - span.clone(), - scope.clone(), - ) { - Some(refusal) => refusal.clone(), - None => match v1_rt::map_get(&scope.locals.clone(), name.clone()) { - Some(binding) => { - let scope_parent = lookup_variant_parent_enum(scope.clone(), name.clone()); - match scope_parent.clone() { - Some(scope_enum) => ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(Rc::new( - VarBindingKind::VariantValueBinding { - parent_enum: scope_enum.clone(), - }, - )), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: variant_reference_inferred_node( - expected.clone(), - name.clone(), - scope_enum.clone(), - scope.clone(), - binding.resolved.clone(), - ), - })), - span.clone(), - span.clone(), - )), - None => { - let binding_kind = - infer_var_binding_kind(scope.clone(), name.clone()); - ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(binding_kind.clone()), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: binding.resolved.clone(), - })), - span.clone(), - span.clone(), - )) - } - } - } - None => match (*lookup_func_sig( - scope.func_env.clone(), - scope.type_env.clone(), - name.clone(), - )) - .clone() - { - FuncSigLookup::FuncSigResolved { sig: fsig, .. } => { - match ((fsig.params.clone().len() as i64) == 0) { - true => ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: fsig.inferred.clone(), - })), - span.clone(), - span.clone(), - )), - false => ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(Rc::new( - VarBindingKind::FunctionValueBinding, - )), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: resolved_callable_type( - fsig.params.clone(), - fsig.inferred.clone(), - ), - })), - span.clone(), - span.clone(), - )), - } - } - FuncSigLookup::FuncSigAmbiguous { - candidates: ambiguous_fn_candidates, - .. - } => ambiguous_reference_refusal( - name.clone(), - ambiguous_fn_candidates.clone(), - span.clone(), - scope.clone(), - ), - FuncSigLookup::FuncSigUnresolved => { - match lookup_binding_by_name(scope.type_env.clone(), name.clone()) { - Some(gbinding) => { - let scope_parent = - lookup_variant_parent_enum(scope.clone(), name.clone()); - match scope_parent.clone() { - Some(scope_enum) => ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(Rc::new( - VarBindingKind::VariantValueBinding { - parent_enum: scope_enum.clone(), - }, - )), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: variant_reference_inferred_node( - expected.clone(), - name.clone(), - scope_enum.clone(), - scope.clone(), - gbinding.resolved.clone(), - ), - })), - span.clone(), - span.clone(), - )), - None => { - let binding_kind = - infer_var_binding_kind(scope.clone(), name.clone()); - ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(binding_kind.clone()), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: gbinding.resolved.clone(), - })), - span.clone(), - span.clone(), - )) - } - } - } - None => { - let expected_variant_enum = - expected_variant_owner_instantiation( - expected.clone(), - name.clone(), - scope.clone(), - ); - match expected_variant_enum.clone() { - Some(exp_enum) => ok_infer(make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: Some(Rc::new( - VarBindingKind::VariantValueBinding { - parent_enum: authored_name_at( - scope - .type_env - .clone() - .source_indices - .clone(), - exp_enum.clone(), - ), - }, - )), - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: exp_enum.clone(), - })), - span.clone(), - span.clone(), - )), - None => { - let var_ambiguity_cands = - global_bare_strict_ambiguity_candidates( - scope.type_env.clone(), - name.clone(), - ); - if ((var_ambiguity_cands.clone().len() as i64) > 0) { - ambiguous_reference_refusal( - name.clone(), - var_ambiguity_cands.clone(), - span.clone(), - scope.clone(), - ) - } else { - { - let err_texpr = make_named_expr_node( - name.clone(), - Rc::new(ExprData::ExprVar { - binding_kind: None, - }), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { - node: error_type(), - })), - span.clone(), - span.clone(), - ); - Rc::new(InferResult { - typed: err_texpr.clone(), - diagnostics: Rc::new(vec![ - inference_error( - v1_rt::concat( - v1_rt::concat( - "undefined variable '" - .to_string(), - name.clone(), - ), - "'".to_string(), - ), - span.clone(), - scope.module_name.clone(), - ), - ]), - }) - } - } - } - } - } - } - } - }, - }, - } - } - ExprData::ExprFieldAccess { summary: _, .. } => { - let field_name = - field_access_field_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let span = texpr.span.clone(); - let base_expr = field_access_base(texpr.clone()); - match qualified_value_projection(texpr.clone(), scope.clone(), span.clone()) { - Some(proj) => proj.clone(), - None => { - let base_result = infer_expr(base_expr.clone(), scope.clone(), None); - let base_typed = base_result.typed.clone(); - let base_diags = base_result.diagnostics.clone(); - let base_rt = resolved_type(base_typed.clone()); - let base_expansion = - if is_deferred_field_access_base(base_rt.clone(), scope.type_env.clone()) { - Rc::new(NodeResolveResult { - resolved: base_rt.clone(), - diagnostics: Rc::new(vec![]), - }) - } else { - expand_type_for_field_access( - base_rt.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ) - }; - let resolved_base = base_expansion.resolved.clone(); - let resolved_base_diags = base_expansion.diagnostics.clone(); - let resolved_base_is_error = if (resolved_base.inferred.clone() != None) { - is_compiler_error(resolved_base.inferred.clone().clone().unwrap()) - } else { - false - }; - if resolved_base_is_error.clone() { - Rc::new(InferResult { - typed: make_expr_error_node( - ExprErrorKind::SemanticExprError, - "error type cascade".to_string(), - span.clone(), - ), - diagnostics: v1_rt::concat( - base_diags.clone(), - resolved_base_diags.clone(), - ), - }) - } else { - { - let field_type_lookup = lookup_field_type_node( - resolved_base.clone(), - field_name.clone(), - scope.type_env.clone().source_indices.clone(), - ); - match field_type_lookup.clone() { - Some(raw_field_type) => { - let field_type = stamp_field_type_from_decl_params( - raw_field_type.clone(), - resolved_base.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let field_summary = match field_summary_for_type( - base_rt.clone(), - scope.type_env.clone(), - field_name.clone(), - ) { - Some(s) => Some(s.clone()), - None => field_summary_for_type( - resolved_base.clone(), - scope.type_env.clone(), - field_name.clone(), - ), - }; - let fa_texpr = make_named_expr_node( - field_name.clone(), - Rc::new(ExprData::ExprFieldAccess { - summary: field_summary.clone(), - }), - Rc::new(vec![base_typed.clone()]), - Some(Rc::new(InferredNode::Resolved { - node: field_type.clone(), - })), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: fa_texpr.clone(), - diagnostics: v1_rt::concat( - base_diags.clone(), - resolved_base_diags.clone(), - ), - }) - } - None => { - let base_is_type_var = is_deferred_field_access_base( - resolved_base.clone(), - scope.type_env.clone(), - ); - if base_is_type_var.clone() { - { - let fa_texpr = make_named_expr_node( - field_name.clone(), - Rc::new(ExprData::ExprFieldAccess { - summary: Some(Rc::new(FieldSummary { - access_style: FieldAccessStyle::StoredField, - value_shape: FieldValueShape::PlainValue, - })), - }), - Rc::new(vec![base_typed.clone()]), - Some(Rc::new(InferredNode::TypeVariable { - id: "field_of_type_var".to_string(), - })), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: fa_texpr.clone(), - diagnostics: v1_rt::concat( - base_diags.clone(), - resolved_base_diags.clone(), - ), - }) - } - } else { - match check_service_field_access_node( - base_rt.clone(), - field_name.clone(), - scope.service_registry.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(svc_type) => { - let fa_texpr = make_named_expr_node( - field_name.clone(), - Rc::new(ExprData::ExprFieldAccess { - summary: Some(Rc::new(FieldSummary { - access_style: - FieldAccessStyle::StoredField, - value_shape: - FieldValueShape::PlainValue, - })), - }), - Rc::new(vec![base_typed.clone()]), - Some(Rc::new(InferredNode::Resolved { - node: svc_type.clone(), - })), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: fa_texpr.clone(), - diagnostics: v1_rt::concat( - base_diags.clone(), - resolved_base_diags.clone(), - ), - }) - } - None => { - let error_message = v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - "no field '".to_string(), - field_name.clone(), - ), - "' on type '".to_string(), - ), - authored_name_at( - scope - .type_env - .clone() - .source_indices - .clone(), - resolved_base.clone(), - ), - ), - "'".to_string(), - ); - let fa_texpr = make_expr_error_node( - ExprErrorKind::SemanticExprError, - error_message.clone(), - span.clone(), - ); - Rc::new(InferResult { - typed: fa_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - base_diags.clone(), - resolved_base_diags.clone(), - ), - Rc::new(vec![inference_error( - error_message.clone(), - span.clone(), - scope.module_name.clone(), - )]), - ), - }) - } - } - } - } - } - } - } - } - } - } - ExprData::ExprCall { .. } => { - let func_name = - expr_call_func_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let span = texpr.span.clone(); - let call_args = texpr.children.clone(); - let call_sig_lookup = body_shadow_aware_func_sig(scope.clone(), func_name.clone()); - match (*call_sig_lookup.clone()).clone() { - FuncSigLookup::FuncSigAmbiguous { - candidates: ambiguous_fn_candidates, - .. - } => ambiguous_reference_refusal( - func_name.clone(), - ambiguous_fn_candidates.clone(), - span.clone(), - scope.clone(), - ), - _ => { - match constructor_reference_admission_unshadowed( - func_name.clone(), - span.clone(), - scope.clone(), - ) { - Some(refusal) => refusal.clone(), - None => { - let sig = func_sig_if_resolved(call_sig_lookup.clone()); - let sig_params = match sig.clone() { - Some(s) => s.params.clone(), - None => Rc::new(vec![]), - }; - let call_sig_split = split_sig_params( - sig_params.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let has_lambda = { - let mut __found = false; - for a in call_args.clone().iter().cloned() { - if is_lambda_expr(arg_value(a.clone())) { - __found = true; - break; - } - } - __found - }; - let call_method_args = Rc::new( - call_args - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - let call_method_name = Some(func_name.clone()); - let call_fold_info = extract_fold_init_info( - call_method_name.clone(), - call_method_args.clone(), - 2, - scope.clone(), - expected.clone(), - ); - let call_fold_acc_type = match call_fold_info.clone() { - Some(fi) => resolved_type(arg_value(fi.typed_arg.clone())), - None => error_type(), - }; - let arg_call = if ((has_lambda.clone() - && ((call_args.clone().len() as i64) >= 2)) - && (sig.clone() == None)) - { - Rc::new(ArgGenericFoldState { - subst: v1_rt::rc_empty_map::>(), - results: match call_args.clone().first().cloned() { - Some(first_arg) => { - let first_result = infer_expr( - arg_value(first_arg.clone()), - scope.clone(), - None, - ); - let first_type = - resolved_type(first_result.typed.clone()); - let elem_type = for_each_element_type_node( - first_type.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let call_elem_provenance = derive_element_provenance( - first_result.typed.clone(), - elem_type.clone(), - scope.clone(), - ); - let remaining_results = infer_method_args_with_fold( - call_method_name.clone(), - call_method_args.clone(), - call_fold_info.clone(), - call_fold_acc_type.clone(), - elem_type.clone(), - call_elem_provenance.clone(), - Rc::new(DeclaredArgContract::MethodUnresolved), - scope.clone(), - ); - v1_rt::concat( - Rc::new(vec![Rc::new(ArgInferResult { - typed_arg: make_arg_node( - arg_name_at( - first_arg.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - ), - first_result.typed.clone(), - first_arg.span.clone(), - first_arg.span.clone(), - ), - diagnostics: first_result.diagnostics.clone(), - })]), - remaining_results.clone(), - ) - } - None => Rc::new(vec![]), - }, - }) - } else { - { - let value_params = call_sig_split.value_params.clone(); - let generic_names = call_sig_split.generic_names.clone(); - let final_state = Rc::new( - call_args - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - Rc::new(ArgGenericFoldState { - results: Rc::new(vec![]), - subst: v1_rt::rc_empty_map::>(), - }), - |st: Rc, pair: (i64, Rc)| { - let a = pair.1.clone(); - let formal_lookup = value_params - .clone() - .iter() - .cloned() - .skip(pair.0.clone() as usize) - .next(); - let formal_raw = match formal_lookup.clone() { - Some(p) => param_node_type_expr(p.clone()), - None => { - type_variable_node("callable_param".to_string()) - } - }; - let has_formal = match formal_lookup.clone() { - Some(_) => true, - None => false, - }; - let formal_param_type = substitute_generics( - formal_raw.clone(), - st.subst.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let expected = if has_formal.clone() { - Some(formal_param_type.clone()) - } else { - None - }; - let ar = infer_expr( - arg_value(a.clone()), - scope.clone(), - expected.clone(), - ); - let next_subst = - if (is_lambda_expr(arg_value(a.clone())) - || !has_formal.clone()) - { - st.subst.clone() - } else { - if should_unify_record_lit_generics( - formal_raw.clone(), - arg_value(a.clone()), - generic_names.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - ) { - unify_record_lit_generics( - formal_raw.clone(), - ar.typed.clone(), - generic_names.clone(), - scope.clone(), - st.subst.clone(), - ) - } else { - unify_generics( - formal_raw.clone(), - resolved_type(ar.typed.clone()), - generic_names.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - st.subst.clone(), - ) - } - }; - Rc::new(ArgGenericFoldState { - results: v1_rt::concat( - st.results.clone(), - Rc::new(vec![Rc::new(ArgInferResult { - typed_arg: make_arg_node( - arg_name_at( - a.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - ), - ar.typed.clone(), - a.span.clone(), - a.span.clone(), - ), - diagnostics: ar.diagnostics.clone(), - })]), - ), - subst: next_subst.clone(), - }) - }, - ); - final_state.clone() - } - }; - let arg_infer_results = arg_call.results.clone(); - let call_subst = arg_call.subst.clone(); - let typed_args = Rc::new({ - let mut __result = Vec::new(); - for air in arg_infer_results.clone().iter().cloned() { - __result.push(air.typed_arg.clone()); - } - __result - }); - let arg_diags = v1_rt::concat( - Rc::new({ - let mut __result = Vec::new(); - for air in arg_infer_results.clone().iter().cloned() { - __result.extend((*air.diagnostics.clone()).iter().cloned()); - } - __result - }), - function_value_call_named_arg_diags( - func_name.clone(), - typed_args.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - scope.body_locals.clone(), - scope.locals.clone(), - ), - ); - let typed_arg_nodes = typed_args.clone(); - if (sig.clone() != None) { - { - let resolved_type = match sig.clone() { - Some(s) => substitute_generics( - s.inferred.clone(), - call_subst.clone(), - scope.type_env.clone().source_indices.clone(), - ), - None => error_type(), - }; - let value_params_for_check = - call_sig_split.value_params.clone(); - let arg_shape_diags = direct_call_shape_diags( - func_name.clone(), - sig_params.clone(), - typed_args.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - span.clone(), - ); - let call_application_plan = build_call_application_plan( - value_params_for_check.clone(), - typed_args.clone(), - call_subst.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ); - let arg_compat_diags = if module_skips_direct_call_arg_check( - scope.module_name.clone(), - ) { - Rc::new(vec![]) - } else { - direct_call_arg_mismatch_diags( - call_application_plan.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ) - }; - let structured_arg_diags = - direct_call_structured_application_mismatch_diags( - call_application_plan.clone(), - scope.clone(), - ); - Rc::new(InferResult { - typed: make_named_expr_node( - func_name.clone(), - Rc::new(ExprData::ExprCall { - call_semantics: Some( - CallSemantics::PlainCallSemantics, - ), - descent_evidence: None, - }), - typed_arg_nodes.clone(), - Some(Rc::new(InferredNode::Resolved { - node: resolved_type.clone(), - })), - span.clone(), - node_name_span(texpr.clone()), - ), - diagnostics: v1_rt::concat( - arg_diags.clone(), - v1_rt::concat( - arg_shape_diags.clone(), - v1_rt::concat( - arg_compat_diags.clone(), - structured_arg_diags.clone(), - ), - ), - ), - }) - } - } else { - { - let first_arg_type = match typed_args.clone().first().cloned() { - Some(ta) => resolved_type(arg_value(ta.clone())), - None => unit_type(), - }; - let method_receiver = match typed_args.clone().first().cloned() - { - Some(ta) => arg_value(ta.clone()), - None => internal_expr_error_node( - "method bridge missing receiver".to_string(), - span.clone(), - ), - }; - let call_acc_is_under_resolved = !is_fully_resolved( - call_fold_acc_type.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let refined_call_fold_acc_type = if ((call_fold_info.clone() - != None) - && call_acc_is_under_resolved.clone()) - { - match Rc::new({ - let mut __result = Vec::new(); - for a in typed_args.clone().iter().cloned() { - if is_lambda_expr(arg_value(a.clone())) { - __result.push(a); - } - } - __result - }) - .first() - .cloned() - { - Some(lambda_arg) => { - resolved_type(arg_value(lambda_arg.clone())) - } - None => call_fold_acc_type.clone(), - } - } else { - call_fold_acc_type.clone() - }; - let method_resolution = - if listed_import_required_bare_call_blocked( - scope.type_env.clone(), - func_name.clone(), - ) { - Rc::new(KnownMethodResolution { - semantics: None, - result_type: None, - diagnostics: Rc::new(vec![]), - }) - } else { - resolve_known_method_node( - method_receiver.clone(), - resolve_method_receiver_type( - first_arg_type.clone(), - scope.type_env.clone(), - ), - func_name.clone(), - if (call_fold_info.clone() != None) { - Some(refined_call_fold_acc_type.clone()) - } else { - None - }, - scope.service_registry.clone(), - scope.type_env.clone().source_indices.clone(), - ) - }; - let callee_is_body_binding = v1_rt::map_has( - &scope.body_locals.clone(), - func_name.clone(), - ); - let is_known_method = (!callee_is_body_binding.clone() - && (method_resolution.result_type.clone() != None)); - if (is_known_method.clone() - && ((typed_args.clone().len() as i64) > 0)) - { - { - let receiver = method_receiver.clone(); - let remaining = Rc::new( - typed_args - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - let base_result_type = - match method_resolution.result_type.clone() { - Some(mt) => mt.clone(), - None => error_type(), - }; - let method_tv = if (method_resolution.semantics.clone() - == None) - { - Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }) - } else { - match (*method_resolution - .semantics - .clone() - .clone() - .unwrap()) - .clone() - { - MethodSemantics::AlgebraMethodSemantics { - algebra_template: at, - .. - } => match at.clone() { - Some(t) => { - if (template_return_has_variables( - t.clone(), - ) || !is_fully_resolved( - base_result_type.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - )) { - { - let call_arg_types = Rc::new({ - let mut __result = - Vec::new(); - for a in remaining - .clone() - .iter() - .cloned() - { - __result.push( - resolved_type( - arg_value( - a.clone(), - ), - ), - ); - } - __result - }); - let fold_overrides = - if (call_fold_info.clone() - != None) - { - fold_override_map("FoldAccumulator".to_string(), refined_call_fold_acc_type.clone()) - } else { - empty_override_map() - }; - resolve_type_variables_from_template(t.clone(), call_arg_types.clone(), first_arg_type.clone(), fold_overrides.clone(), scope.type_env.clone().source_indices.clone()) - } - } else { - Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }) - } - } - None => Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }), - }, - _ => Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }), - } - }; - let bridge_result_type = method_tv.ty.clone(); - let template_subst_diags = - method_tv.diagnostics.clone(); - let returns_receiver_self = - if (method_resolution.semantics.clone() == None) { - false - } else { - match (*method_resolution - .semantics - .clone() - .clone() - .unwrap()) - .clone() - { - MethodSemantics::AlgebraMethodSemantics { - algebra_template: at, - .. - } => match at.clone() { - Some(t) => { - template_return_is_receiver_self( - t.clone(), - ) - } - None => false, - }, - _ => false, - } - }; - let final_receiver = if ((returns_receiver_self - .clone() - && is_fully_resolved( - bridge_result_type.clone(), - scope.type_env.clone().source_indices.clone(), - )) - && !is_fully_resolved( - first_arg_type.clone(), - scope.type_env.clone().source_indices.clone(), - )) { - Rc::new(Node { - name: receiver.name.clone(), - span: receiver.span.clone(), - ident_span: receiver.ident_span.clone(), - children: bridge_result_type.children.clone(), - connective: receiver.connective.clone(), - params: receiver.params.clone(), - inferred: Some(Rc::new( - InferredNode::Resolved { - node: bridge_result_type.clone(), - }, - )), - return_cardinality: receiver - .return_cardinality - .clone(), - uses: receiver.uses.clone(), - body: receiver.body.clone(), - transport: receiver.transport.clone(), - properties: receiver.properties.clone(), - type_annotation: receiver - .type_annotation - .clone(), - is_self_recursive: receiver - .is_self_recursive - .clone(), - has_non_tail_self_call: receiver - .has_non_tail_self_call - .clone(), - match_pattern: receiver.match_pattern.clone(), - expr_data: receiver.expr_data.clone(), - ident: None, - }) - } else { - receiver.clone() - }; - let remaining_arg_nodes = Rc::new({ - let mut __result = Vec::new(); - for ta in remaining.clone().iter().cloned() { - __result.push(make_arg_node( - arg_name_at( - ta.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - ), - arg_value(ta.clone()), - span.clone(), - span.clone(), - )); - } - __result - }); - Rc::new(InferResult { - typed: make_named_expr_node( - func_name.clone(), - Rc::new(ExprData::ExprMethodCall { - method_semantics: method_resolution - .semantics - .clone(), - }), - v1_rt::concat( - Rc::new(vec![final_receiver.clone()]), - remaining_arg_nodes.clone(), - ), - Some(Rc::new(InferredNode::Resolved { - node: bridge_result_type.clone(), - })), - span.clone(), - node_name_span(texpr.clone()), - ), - diagnostics: v1_rt::concat( - v1_rt::concat( - arg_diags.clone(), - method_resolution.diagnostics.clone(), - ), - template_subst_diags.clone(), - ), - }) - } - } else { - if (!callee_is_body_binding.clone() - && (func_name.clone() == "empty_map".to_string())) - { - { - let bare_m = bare_map_node(); - match expected.clone() { - Some(exp) => if node_is_keyed_collection(exp.clone(), scope.type_env.clone().source_indices.clone()) { - Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: exp.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: arg_diags.clone(), -}) - } else { - { - let empty_map_diags = v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_map(): expected type is not a keyed collection".to_string(), span.clone(), scope.module_name.clone())])); -match bare_m.clone() { - Some(map_t) => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: map_t.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: empty_map_diags.clone(), -}), - None => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { - message: "empty_map(): Map kernel container profile missing (compiler misconfigured)".to_string(), - span: span.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: v1_rt::concat(empty_map_diags.clone(), Rc::new(vec![inference_error("empty_map(): Map kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), -}), -} -} - }, - None => match bare_m.clone() { - Some(map_t) => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: map_t.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: arg_diags.clone(), -}), - None => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { - message: "empty_map(): Map kernel container profile missing (compiler misconfigured)".to_string(), - span: span.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_map(): Map kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), -}), -}, -} - } - } else { - if (!callee_is_body_binding.clone() - && (func_name.clone() == "empty_set".to_string())) - { - { - let bare_s = bare_set_node(); - match expected.clone() { - Some(exp) => if node_is_set_collection(exp.clone(), scope.type_env.clone().source_indices.clone()) { - Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: exp.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: arg_diags.clone(), -}) - } else { - { - let empty_set_diags = v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_set(): expected type is not Set<...>".to_string(), span.clone(), scope.module_name.clone())])); -match bare_s.clone() { - Some(set_t) => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: set_t.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: empty_set_diags.clone(), -}), - None => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { - message: "empty_set(): Set kernel container profile missing (compiler misconfigured)".to_string(), - span: span.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: v1_rt::concat(empty_set_diags.clone(), Rc::new(vec![inference_error("empty_set(): Set kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), -}), -} -} - }, - None => match bare_s.clone() { - Some(set_t) => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: set_t.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: arg_diags.clone(), -}), - None => Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::CompilerError { - message: "empty_set(): Set kernel container profile missing (compiler misconfigured)".to_string(), - span: span.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: v1_rt::concat(arg_diags.clone(), Rc::new(vec![inference_error("empty_set(): Set kernel container profile missing".to_string(), span.clone(), scope.module_name.clone())])), -}), -}, -} - } - } else { - if (!callee_is_body_binding.clone() - && (infer_builtin_call_type(func_name.clone()) - != None)) - { - { - let tier2b = - infer_tier2b_builtin_with_kernel_diags( - func_name.clone(), - typed_args.clone(), - scope.clone(), - span.clone(), - ); - let bt = tier2b.bt.clone(); - let call_semantics = if (func_name.clone() - == "lookup".to_string()) - { - Some(CallSemantics::LookupCallSemantics) - } else { - Some(CallSemantics::PlainCallSemantics) - }; - Rc::new(InferResult { - typed: make_named_expr_node( - func_name.clone(), - Rc::new(ExprData::ExprCall { - call_semantics: call_semantics - .clone(), - descent_evidence: None, - }), - typed_arg_nodes.clone(), - Some(Rc::new( - InferredNode::Resolved { - node: bt.clone(), - }, - )), - span.clone(), - node_name_span(texpr.clone()), - ), - diagnostics: v1_rt::concat( - arg_diags.clone(), - tier2b.kernel_diags.clone(), - ), - }) - } - } else { - { - let callable_local = match v1_rt::map_get( - &scope.locals.clone(), - func_name.clone(), - ) { - Some(binding) => { - if ((binding - .resolved - .clone() - .params - .clone() - .len() - as i64) - > 0) - { - Some(binding.resolved.clone()) - } else { - None - } - } - None => None, - }; - if (callable_local.clone() != None) { - { - let callable_type = - match callable_local.clone() { - Some(ct) => ct.clone(), - None => error_type(), - }; - let resolved_type = match callable_type.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: ret, .. }) => ret.clone(), - _ => error_type(), -}; - Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(if callee_is_body_binding.clone() { - CallSemantics::FunctionValueCallSemantics - } else { - CallSemantics::PlainCallSemantics - }), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: resolved_type.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: arg_diags.clone(), -}) - } - } else { - match infer_variant_constructor_call( - func_name.clone(), - call_args.clone(), - span.clone(), - node_name_span(texpr.clone()), - scope.clone(), - ) { - Some(ctor_result) => { - ctor_result.clone() - } - None => { - let type_match = - lookup_type_by_name( - scope.type_env.clone(), - func_name.clone(), - ); - let global_bare_callable = match type_match.clone() { - Some(_) => None, - None => global_bare_callable_node(scope.type_env.clone(), func_name.clone()), -}; - let resolved_type = match type_match.clone() { - Some(tn) => tn.clone(), - None => match global_bare_callable.clone() { - Some(gnode) => if ((gnode.params.clone().len() as i64) > 0) { - borrowed_callable_call_type(gnode.clone(), typed_arg_nodes.clone(), scope.clone()) - } else { - callable_return_type(gnode.clone()) - }, - None => error_type(), -}, -}; - let call_diags = match type_match.clone() { - Some(_) => Rc::new(vec![]), - None => match global_bare_callable.clone() { - Some(_) => Rc::new(vec![]), - None => { - let call_ambiguity_cands = global_bare_strict_ambiguity_candidates(scope.type_env.clone(), func_name.clone()); -if ((call_ambiguity_cands.clone().len() as i64) > 0) { - Rc::new(vec![make_error_node(Rc::new(CompilerDiagnostic::AmbiguousReference { - name: func_name.clone(), - candidates: call_ambiguity_cands.clone(), - span: span.clone(), -}), scope.module_name.clone())]) - } else { - Rc::new(vec![inference_error(v1_rt::concat(v1_rt::concat("function '".to_string(), func_name.clone()), "' not found in scope".to_string()), span.clone(), scope.module_name.clone())]) - } -}, -}, -}; - Rc::new(InferResult { - typed: make_named_expr_node(func_name.clone(), Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, -}), typed_arg_nodes.clone(), Some(Rc::new(InferredNode::Resolved { - node: resolved_type.clone(), -})), span.clone(), node_name_span(texpr.clone())), - diagnostics: v1_rt::concat(arg_diags.clone(), call_diags.clone()), -}) - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let method_name = - expr_method_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let span = texpr.span.clone(); - let recv = method_receiver(texpr.clone()); - let mc_args = method_arg_nodes(texpr.clone()); - let qualified_direct_call = match field_access_spine( - recv.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - None => None, - Some(recv_spine) => { - match spine_root_is_shadowed(scope.clone(), recv_spine.root.clone()) { - true => None, - false => { - let dotted = v1_rt::concat( - v1_rt::concat(recv_spine.dotted.clone(), ".".to_string()), - method_name.clone(), - ); - match symbol_index_lookup( - scope.type_env.clone().symbol_index.clone(), - dotted.clone(), - ) { - None => None, - Some(_) => Some(infer_expr( - make_named_expr_node( - dotted.clone(), - Rc::new(ExprData::ExprCall { - call_semantics: Some(CallSemantics::PlainCallSemantics), - descent_evidence: None, - }), - mc_args.clone(), - None, - span.clone(), - kernel_span(dotted.clone()), - ), - scope.clone(), - expected.clone(), - )), - } - } - } - } - }; - match qualified_direct_call.clone() { - Some(qdc) => qdc.clone(), - None => { - let recv_result = infer_expr(recv.clone(), scope.clone(), None); - let recv_typed = recv_result.typed.clone(); - let recv_diags = recv_result.diagnostics.clone(); - let recv_rt = resolve_method_receiver_type( - resolved_type(recv_typed.clone()), - scope.type_env.clone(), - ); - let recv_elem_type = for_each_element_type_node( - recv_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let mc_method_name = Some(method_name.clone()); - let fold_info = extract_fold_init_info( - mc_method_name.clone(), - mc_args.clone(), - 2, - scope.clone(), - expected.clone(), - ); - let fold_acc_type = match fold_info.clone() { - Some(fi) => resolved_type(arg_value(fi.typed_arg.clone())), - None => error_type(), - }; - let mc_elem_provenance = derive_element_provenance( - recv_typed.clone(), - recv_elem_type.clone(), - scope.clone(), - ); - let mc_arg_contract = declared_arg_types_for_method( - recv_rt.clone(), - method_name.clone(), - scope.type_env.clone().source_indices.clone(), - |n| { - expand_type_for_field_access( - n.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ) - .resolved - .clone() - }, - ); - let mc_arg_infer_results = infer_method_args_with_fold( - mc_method_name.clone(), - mc_args.clone(), - fold_info.clone(), - fold_acc_type.clone(), - recv_elem_type.clone(), - mc_elem_provenance.clone(), - mc_arg_contract.clone(), - scope.clone(), - ); - let typed_mc_args = Rc::new({ - let mut __result = Vec::new(); - for air in mc_arg_infer_results.clone().iter().cloned() { - __result.push(air.typed_arg.clone()); - } - __result - }); - let mc_arg_diags = Rc::new({ - let mut __result = Vec::new(); - for air in mc_arg_infer_results.clone().iter().cloned() { - __result.extend((*air.diagnostics.clone()).iter().cloned()); - } - __result - }); - let mc_acc_is_under_resolved = !is_fully_resolved( - fold_acc_type.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let refined_fold_acc_type = - if ((fold_info.clone() != None) && mc_acc_is_under_resolved.clone()) { - match Rc::new({ - let mut __result = Vec::new(); - for a in typed_mc_args.clone().iter().cloned() { - if is_lambda_expr(arg_value(a.clone())) { - __result.push(a); - } - } - __result - }) - .first() - .cloned() - { - Some(lambda_arg) => resolved_type(arg_value(lambda_arg.clone())), - None => fold_acc_type.clone(), - } - } else { - fold_acc_type.clone() - }; - let method_resolution = resolve_known_method_node( - recv_typed.clone(), - recv_rt.clone(), - method_name.clone(), - if (fold_info.clone() != None) { - Some(refined_fold_acc_type.clone()) - } else { - None - }, - scope.service_registry.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let pipe_fb = match method_resolution.result_type.clone() { - Some(rt) => Rc::new(MethodPipeFallback { - result_ty: rt.clone(), - kernel_diags: Rc::new(vec![]), - }), - None => method_pipe_map_keys_values_fallback( - recv_rt.clone(), - method_name.clone(), - scope.clone(), - span.clone(), - ), - }; - let base_result_type = pipe_fb.result_ty.clone(); - let method_tv_mc = if (method_resolution.semantics.clone() == None) { - Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }) - } else { - match (*method_resolution.semantics.clone().clone().unwrap()).clone() { - MethodSemantics::AlgebraMethodSemantics { - algebra_template: at, - .. - } => match at.clone() { - Some(t) => { - if (template_return_has_variables(t.clone()) - || !is_fully_resolved( - base_result_type.clone(), - scope.type_env.clone().source_indices.clone(), - )) - { - { - let mc_arg_types = Rc::new({ - let mut __result = Vec::new(); - for a in typed_mc_args.clone().iter().cloned() { - __result - .push(resolved_type(arg_value(a.clone()))); - } - __result - }); - let mc_fold_overrides = if (fold_info.clone() != None) { - fold_override_map( - "FoldAccumulator".to_string(), - refined_fold_acc_type.clone(), - ) - } else { - empty_override_map() - }; - resolve_type_variables_from_template( - t.clone(), - mc_arg_types.clone(), - recv_rt.clone(), - mc_fold_overrides.clone(), - scope.type_env.clone().source_indices.clone(), - ) - } - } else { - Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }) - } - } - None => Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }), - }, - _ => Rc::new(KernelTypeBuild { - ty: base_result_type.clone(), - diagnostics: Rc::new(vec![]), - }), - } - }; - let result_type = method_tv_mc.ty.clone(); - let mc_template_diags = method_tv_mc.diagnostics.clone(); - let method_semantics = if (method_resolution.semantics.clone() != None) { - method_resolution.semantics.clone() - } else { - Some(Rc::new(MethodSemantics::PlainMethodSemantics)) - }; - let typed_mc_arg_nodes = typed_mc_args.clone(); - let mc_texpr = make_named_expr_node( - method_name.clone(), - Rc::new(ExprData::ExprMethodCall { - method_semantics: method_semantics.clone(), - }), - v1_rt::concat( - Rc::new(vec![recv_typed.clone()]), - typed_mc_arg_nodes.clone(), - ), - Some(Rc::new(InferredNode::Resolved { - node: result_type.clone(), - })), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: mc_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat(recv_diags.clone(), mc_arg_diags.clone()), - pipe_fb.kernel_diags.clone(), - ), - v1_rt::concat( - method_resolution.diagnostics.clone(), - mc_template_diags.clone(), - ), - ), - }) - } - } - } - ExprData::ExprMatch => { - let span = texpr.span.clone(); - let scrut = match_scrutinee(texpr.clone()); - let arm_nodes = match_arm_nodes(texpr.clone()); - let scrut_result = infer_expr(scrut.clone(), scope.clone(), None); - let scrut_typed = scrut_result.typed.clone(); - let scrut_diags = scrut_result.diagnostics.clone(); - let scrut_rt = resolved_type(scrut_typed.clone()); - let scrut_subject = pattern_subject_from_inferred(scrut_typed.inferred.clone()); - let scrut_provenance = classify_binding_provenance(scrut.clone(), scope.clone()); - let arm_infer_results = Rc::new({ - let mut __result = Vec::new(); - for arm_node in arm_nodes.clone().iter().cloned() { - __result.push({ - let arm_pat = arm_pattern(arm_node.clone()); - let arm_g = arm_guard(arm_node.clone()); - let arm_b = arm_body(arm_node.clone()); - let typed_pattern = annotate_pattern_parent_enums( - arm_pat.clone(), - scrut_subject.clone(), - scope.clone(), - ); - let pattern_result = extend_scope_with_pattern_node( - scope.clone(), - typed_pattern.clone(), - scrut_subject.clone(), - scrut_provenance.clone(), - ); - let arm_scope = pattern_result.scope.clone(); - let pattern_diags = pattern_result.diagnostics.clone(); - let guard_result = if (arm_g.clone() != None) { - Some(infer_expr(arm_g.clone().unwrap(), arm_scope.clone(), None)) - } else { - None - }; - let body_result = - infer_expr(arm_b.clone(), arm_scope.clone(), expected.clone()); - let body_typed = body_result.typed.clone(); - let body_diags = body_result.diagnostics.clone(); - let guard_unwrapped = match guard_result.clone() { - Some(gr) => gr.clone(), - None => Rc::new(InferResult { - typed: arm_b.clone(), - diagnostics: Rc::new(vec![]), - }), - }; - let guard_diags = if (guard_result.clone() != None) { - guard_unwrapped.diagnostics.clone() - } else { - Rc::new(vec![]) - }; - Rc::new(ArmInferResult { - typed_arm: make_arm_node( - typed_pattern.clone(), - if (guard_result.clone() != None) { - Some(guard_unwrapped.typed.clone()) - } else { - None - }, - body_typed.clone(), - span.clone(), - ), - diagnostics: v1_rt::concat( - pattern_diags.clone(), - v1_rt::concat(guard_diags.clone(), body_diags.clone()), - ), - body_type: resolved_type(body_typed.clone()), - }) - }); - } - __result - }); - let arm_body_types = Rc::new({ - let mut __result = Vec::new(); - for ar in arm_infer_results.clone().iter().cloned() { - __result.push(ar.body_type.clone()); - } - __result - }); - let unified_arm_type = match arm_body_types.clone().first().cloned() { - Some(first_type) => Rc::new( - arm_body_types - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold(first_type.clone(), |acc: _, t: Rc| { - prefer_specific_type( - acc, - t.clone(), - scope.type_env.clone().source_indices.clone(), - ) - }), - None => scrut_rt.clone(), - }; - let arm_infer_results = if is_fully_resolved( - unified_arm_type.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Rc::new({ - let mut __result = Vec::new(); - for pair in Rc::new( - arm_nodes - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.push({ - let idx = pair.0.clone(); - let arm_node = pair.1.clone(); - let original_list = Rc::new({ - let mut __result = Vec::new(); - for ap in Rc::new({ - let mut __result = Vec::new(); - for ap in Rc::new( - arm_infer_results - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - if (ap.0.clone() == idx.clone()) { - __result.push(ap); - } - } - __result - }) - .iter() - .cloned() - { - __result.push(ap.1.clone()); - } - __result - }); - let original = match original_list.clone().first().cloned() { - Some(ar) => ar.clone(), - None => Rc::new(ArmInferResult { - typed_arm: arm_node.clone(), - diagnostics: Rc::new(vec![]), - body_type: scrut_rt.clone(), - }), - }; - if !is_fully_resolved( - original.body_type.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - { - let arm_pat = arm_pattern(arm_node.clone()); - let arm_g = arm_guard(arm_node.clone()); - let arm_b = arm_body(arm_node.clone()); - let typed_pattern = annotate_pattern_parent_enums( - arm_pat.clone(), - scrut_subject.clone(), - scope.clone(), - ); - let pattern_result = extend_scope_with_pattern_node( - scope.clone(), - typed_pattern.clone(), - scrut_subject.clone(), - scrut_provenance.clone(), - ); - let arm_scope = pattern_result.scope.clone(); - let pattern_diags = pattern_result.diagnostics.clone(); - let guard_result = if (arm_g.clone() != None) { - Some(infer_expr( - arm_g.clone().unwrap(), - arm_scope.clone(), - None, - )) - } else { - None - }; - let body_result = infer_expr( - arm_b.clone(), - arm_scope.clone(), - Some(unified_arm_type.clone()), - ); - let body_typed = body_result.typed.clone(); - let body_diags = body_result.diagnostics.clone(); - let guard_unwrapped = match guard_result.clone() { - Some(gr) => gr.clone(), - None => Rc::new(InferResult { - typed: arm_b.clone(), - diagnostics: Rc::new(vec![]), - }), - }; - let guard_diags = if (guard_result.clone() != None) { - guard_unwrapped.diagnostics.clone() - } else { - Rc::new(vec![]) - }; - Rc::new(ArmInferResult { - typed_arm: make_arm_node( - typed_pattern.clone(), - if (guard_result.clone() != None) { - Some(guard_unwrapped.typed.clone()) - } else { - None - }, - body_typed.clone(), - span.clone(), - ), - diagnostics: v1_rt::concat( - pattern_diags.clone(), - v1_rt::concat(guard_diags.clone(), body_diags.clone()), - ), - body_type: resolved_type(body_typed.clone()), - }) - } - } else { - original.clone() - } - }); - } - __result - }) - } else { - arm_infer_results.clone() - }; - let typed_arms = Rc::new({ - let mut __result = Vec::new(); - for ar in arm_infer_results.clone().iter().cloned() { - __result.push(ar.typed_arm.clone()); - } - __result - }); - let arm_diags = Rc::new({ - let mut __result = Vec::new(); - for ar in arm_infer_results.clone().iter().cloned() { - __result.extend((*ar.diagnostics.clone()).iter().cloned()); - } - __result - }); - let result_type = unified_arm_type.clone(); - let empty_arms_diags = if ((arm_infer_results.clone().len() as i64) == 0) { - Rc::new(vec![inference_error( - "match expression has no arms".to_string(), - span.clone(), - scope.module_name.clone(), - )]) - } else { - Rc::new(vec![]) - }; - let exhaustiveness_diags = - match (*resolve_pattern_subject(scope.clone(), scrut_subject.clone())).clone() { - PatternSubject::PatternResolved { - node: resolved_scrutinee, - .. - } => check_match_exhaustiveness( - resolved_scrutinee.clone(), - typed_arms.clone(), - scope.type_env.clone(), - span.clone(), - scope.module_name.clone(), - ), - PatternSubject::PatternDynamic { span: _, .. } => Rc::new(vec![]), - PatternSubject::PatternLookupBlocked => Rc::new(vec![]), - }; - let match_texpr = make_expr_node( - Rc::new(ExprData::ExprMatch), - v1_rt::concat(Rc::new(vec![scrut_typed.clone()]), typed_arms.clone()), - Some(Rc::new(InferredNode::Resolved { - node: result_type.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: match_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat(scrut_diags.clone(), arm_diags.clone()), - empty_arms_diags.clone(), - ), - exhaustiveness_diags.clone(), - ), - }) - } - ExprData::ExprIf => { - let span = texpr.span.clone(); - let cond = if_condition(texpr.clone()); - let then_expr = if_then_branch(texpr.clone()); - let else_expr = if_else_branch(texpr.clone()); - let cond_result = infer_expr(cond.clone(), scope.clone(), None); - let cond_typed = cond_result.typed.clone(); - let cond_diags = cond_result.diagnostics.clone(); - let then_result = infer_expr(then_expr.clone(), scope.clone(), expected.clone()); - let then_typed = then_result.typed.clone(); - let then_diags = then_result.diagnostics.clone(); - match else_expr.clone() { - Some(else_branch) => { - let else_result = - infer_expr(else_branch.clone(), scope.clone(), expected.clone()); - let then_rt = resolved_type(then_result.typed.clone()); - let else_rt = resolved_type(else_result.typed.clone()); - let then_result = if (!is_fully_resolved( - then_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ) && is_fully_resolved( - else_rt.clone(), - scope.type_env.clone().source_indices.clone(), - )) { - infer_expr(then_expr.clone(), scope.clone(), Some(else_rt.clone())) - } else { - then_result.clone() - }; - let else_result = if (!is_fully_resolved( - else_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ) && is_fully_resolved( - then_rt.clone(), - scope.type_env.clone().source_indices.clone(), - )) { - infer_expr(else_branch.clone(), scope.clone(), Some(then_rt.clone())) - } else { - else_result.clone() - }; - let then_typed = then_result.typed.clone(); - let then_diags = then_result.diagnostics.clone(); - let else_typed = else_result.typed.clone(); - let else_diags = else_result.diagnostics.clone(); - let then_rt = resolved_type(then_typed.clone()); - let else_rt = resolved_type(else_typed.clone()); - let unified = prefer_specific_type( - then_rt.clone(), - else_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let branch_diags = if node_type_compatible( - then_rt.clone(), - else_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Rc::new(vec![]) - } else { - Rc::new(vec![inference_error( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - "if branches resolve to incompatible types: ".to_string(), - node_type_shape( - then_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ), - ), - " vs ".to_string(), - ), - node_type_shape( - else_rt.clone(), - scope.type_env.clone().source_indices.clone(), - ), - ), - span.clone(), - scope.module_name.clone(), - )]) - }; - let if_texpr = make_expr_node( - Rc::new(ExprData::ExprIf), - Rc::new(vec![ - cond_typed.clone(), - then_typed.clone(), - else_typed.clone(), - ]), - Some(Rc::new(InferredNode::Resolved { - node: unified.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: if_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat(cond_diags.clone(), then_diags.clone()), - else_diags.clone(), - ), - branch_diags.clone(), - ), - }) - } - None => { - let if_texpr2 = make_expr_node( - Rc::new(ExprData::ExprIf), - Rc::new(vec![cond_typed.clone(), then_typed.clone()]), - Some(Rc::new(InferredNode::Resolved { node: unit_type() })), - span.clone(), - ); - Rc::new(InferResult { - typed: if_texpr2.clone(), - diagnostics: v1_rt::concat(cond_diags.clone(), then_diags.clone()), - }) - } - } - } - ExprData::ExprLet => { - let let_name = - let_binding_name_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let span = texpr.span.clone(); - let val_expr = let_value(texpr.clone()); - let body_expr = let_body(texpr.clone()); - let is_tail_return = match body_expr.clone() { - Some(bd) => match (*bd.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - (authored_name_at( - scope.type_env.clone().source_indices.clone(), - bd.clone(), - ) == let_name.clone()) - } - _ => false, - }, - None => false, - }; - let val_expected = if ((texpr.type_annotation.clone() != None) - && is_type_expr_annotation(texpr.type_annotation.clone().clone().unwrap())) - { - Some(texpr.type_annotation.clone().clone().unwrap()) - } else { - if is_tail_return.clone() { - expected.clone() - } else { - None - } - }; - let val_result = infer_expr(val_expr.clone(), scope.clone(), val_expected.clone()); - let val_typed = val_result.typed.clone(); - let val_diags = val_result.diagnostics.clone(); - let val_type = resolved_type(val_typed.clone()); - if (body_expr.clone() == None) { - { - let let_texpr = make_named_expr_node( - let_name.clone(), - Rc::new(ExprData::ExprLet), - Rc::new(vec![val_typed.clone()]), - Some(Rc::new(InferredNode::Resolved { - node: val_type.clone(), - })), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: let_texpr.clone(), - diagnostics: val_diags.clone(), - }) - } - } else { - { - let extended = extend_scope( - scope.clone(), - let_name.clone(), - val_type.clone(), - classify_binding_provenance(val_typed.clone(), scope.clone()), - ); - let body_result = infer_expr( - body_expr.clone().unwrap(), - extended.clone(), - expected.clone(), - ); - let body_typed = body_result.typed.clone(); - let body_diags = body_result.diagnostics.clone(); - let let_texpr2 = make_named_expr_node( - let_name.clone(), - Rc::new(ExprData::ExprLet), - Rc::new(vec![val_typed.clone(), body_typed.clone()]), - body_typed.inferred.clone(), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: let_texpr2.clone(), - diagnostics: v1_rt::concat(val_diags.clone(), body_diags.clone()), - }) - } - } - } - ExprData::ExprRecordLit { parent_enum: _, .. } => { - let span = texpr.span.clone(); - let field_inits = texpr.children.clone(); - infer_record_lit( - record_lit_type_name_at( - texpr.clone(), - scope.type_env.clone().source_indices.clone(), - ), - field_inits.clone(), - span.clone(), - node_name_span(texpr.clone()), - scope.clone(), - expected.clone(), - ) - } - ExprData::ExprListLit => { - let span = texpr.span.clone(); - let elements = texpr.children.clone(); - let elem_expected = match expected.clone() { - Some(exp) => { - if node_is_element_collection( - exp.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - match exp.children.clone().first().cloned() { - Some(elem) => Some(child_type_node(elem.clone())), - None => None, - } - } else { - None - } - } - None => None, - }; - let elem_results = Rc::new({ - let mut __result = Vec::new(); - for e in elements.clone().iter().cloned() { - __result.push(infer_expr(e.clone(), scope.clone(), elem_expected.clone())); - } - __result - }); - let typed_elements = Rc::new({ - let mut __result = Vec::new(); - for r in elem_results.clone().iter().cloned() { - __result.push(r.typed.clone()); - } - __result - }); - let elem_diags = Rc::new({ - let mut __result = Vec::new(); - for r in elem_results.clone().iter().cloned() { - __result.extend((*r.diagnostics.clone()).iter().cloned()); - } - __result - }); - let elem_type_node = if ((elem_results.clone().len() as i64) > 0) { - match elem_results.clone().first().cloned() { - Some(r) => resolved_type(r.typed.clone()), - None => unit_type(), - } - } else { - match expected.clone() { - Some(exp) => { - if node_is_element_collection( - exp.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - match exp.children.clone().first().cloned() { - Some(elem) => child_type_node(elem.clone()), - None => unit_type(), - } - } else { - unit_type() - } - } - None => unit_type(), - } - }; - let empty_list_diags = if ((elem_results.clone().len() as i64) == 0) { - match expected.clone() { - Some(exp) => { - if node_is_element_collection( - exp.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - match exp.children.clone().first().cloned() { - Some(_) => Rc::new(vec![]), - None => Rc::new(vec![inference_error( - "empty list literal: expected type has no element type" - .to_string(), - span.clone(), - scope.module_name.clone(), - )]), - } - } else { - Rc::new(vec![inference_error( - "empty list literal: expected type is not a collection".to_string(), - span.clone(), - scope.module_name.clone(), - )]) - } - } - None => Rc::new(vec![]), - } - } else { - Rc::new(vec![]) - }; - let list_k = list_kernel_ty_from_element(elem_type_node.clone()); - let ll_texpr = make_expr_node( - Rc::new(ExprData::ExprListLit), - typed_elements.clone(), - Some(Rc::new(InferredNode::Resolved { - node: list_k.ty.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: ll_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat(elem_diags.clone(), empty_list_diags.clone()), - list_k.miss_diags.clone(), - ), - }) - } - ExprData::ExprBinOp { op, .. } => { - let span = texpr.span.clone(); - let left_expr = binop_left(texpr.clone()); - let right_expr = binop_right(texpr.clone()); - let left_result = infer_expr(left_expr.clone(), scope.clone(), None); - let left_typed = left_result.typed.clone(); - let left_diags = left_result.diagnostics.clone(); - let right_result = infer_expr(right_expr.clone(), scope.clone(), None); - let right_typed = right_result.typed.clone(); - let right_diags = right_result.diagnostics.clone(); - let binop_info = infer_binop_type_node( - op.clone(), - resolved_type(left_typed.clone()), - scope.type_env.clone().source_indices.clone(), - ); - let bo_texpr = make_expr_node( - Rc::new(ExprData::ExprBinOp { - op: op.clone(), - algebra_field: binop_info.algebra_field.clone(), - }), - Rc::new(vec![left_typed.clone(), right_typed.clone()]), - Some(Rc::new(InferredNode::Resolved { - node: binop_info.result_type.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: bo_texpr.clone(), - diagnostics: v1_rt::concat(left_diags.clone(), right_diags.clone()), - }) - } - ExprData::ExprUnaryOp { op: op, .. } => { - let span = texpr.span.clone(); - let operand_expr = unaryop_operand(texpr.clone()); - let operand_result = infer_expr(operand_expr.clone(), scope.clone(), None); - let operand_typed = operand_result.typed.clone(); - let operand_diags = operand_result.diagnostics.clone(); - let result_type = match op.clone() { - UnaryOpKind::Not => bool_type(), - UnaryOpKind::Neg => resolved_type(operand_typed.clone()), - }; - let uo_texpr = make_expr_node( - Rc::new(ExprData::ExprUnaryOp { op: op.clone() }), - Rc::new(vec![operand_typed.clone()]), - Some(Rc::new(InferredNode::Resolved { - node: result_type.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: uo_texpr.clone(), - diagnostics: operand_diags.clone(), - }) - } - ExprData::ExprLambda => { - let span = texpr.span.clone(); - let lam_body = lambda_body(texpr.clone()); - let lam_params = - lambda_param_names_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let lam_param_nodes = Rc::new( - texpr - .children - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - let elem_prov = - match v1_rt::map_get(&scope.lambda_param_provenance.clone(), "elem".to_string()) { - Some(p) => p.clone(), - None => Rc::new(SubValueRelation::SubValueUnknown), - }; - let lam_scope = if (expected.clone() != None) { - { - let exp = expected.clone().unwrap(); - if ((exp.params.clone().len() as i64) > 0) { - Rc::new( - lam_params - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - scope.clone(), - |acc: Rc, pair: (i64, String)| { - let param_prov = if (pair.0.clone() - == ((lam_params.clone().len() as i64) - 1)) - { - elem_prov.clone() - } else { - Rc::new(SubValueRelation::SubValueUnknown) - }; - match exp - .params - .clone() - .iter() - .cloned() - .skip(pair.0.clone() as usize) - .next() - { - Some(cp) => extend_scope( - acc.clone(), - pair.1.clone(), - param_node_type_expr(cp.clone()), - param_prov.clone(), - ), - None => extend_scope( - acc.clone(), - pair.1.clone(), - type_variable_node("callable_param".to_string()), - param_prov.clone(), - ), - } - }, - ) - } else { - if ((lam_params.clone().len() as i64) == 1) { - match lam_params.clone().first().cloned() { - Some(p) => extend_scope( - scope.clone(), - p.clone(), - exp.clone(), - elem_prov.clone(), - ), - None => scope.clone(), - } - } else { - Rc::new( - lam_params - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - scope.clone(), - |acc: Rc, pair: (i64, String)| { - let param_prov = if (pair.0.clone() - == ((lam_params.clone().len() as i64) - 1)) - { - elem_prov.clone() - } else { - Rc::new(SubValueRelation::SubValueUnknown) - }; - if (pair.0.clone() == ((lam_params.clone().len() as i64) - 1)) { - extend_scope( - acc.clone(), - pair.1.clone(), - exp.clone(), - param_prov.clone(), - ) - } else { - extend_scope( - acc.clone(), - pair.1.clone(), - type_variable_node("lambda_param".to_string()), - param_prov.clone(), - ) - } - }, - ) - } - } - } - } else { - extend_scope_with_params(scope.clone(), lam_params.clone()) - }; - let body_expected = if (expected.clone() != None) { - { - let exp = expected.clone().unwrap(); - if ((exp.params.clone().len() as i64) > 0) { - { - let declared_ret = resolved_type(exp.clone()); - if is_fully_resolved( - declared_ret.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(declared_ret.clone()) - } else { - None - } - } - } else { - None - } - } - } else { - None - }; - let body_scope = Rc::new(InferScope { - type_env: lam_scope.type_env.clone(), - func_env: lam_scope.func_env.clone(), - locals: lam_scope.locals.clone(), - body_locals: lam_scope.body_locals.clone(), - match_bound_names: lam_scope.match_bound_names.clone(), - module_name: lam_scope.module_name.clone(), - service_registry: lam_scope.service_registry.clone(), - item_registry: lam_scope.item_registry.clone(), - caller_decl_name: lam_scope.caller_decl_name.clone(), - lambda_param_provenance: v1_rt::rc_empty_map::>(), - }); - let body_result = - infer_expr(lam_body.clone(), body_scope.clone(), body_expected.clone()); - let body_typed = body_result.typed.clone(); - let body_diags = body_result.diagnostics.clone(); - let typed_param_nodes = Rc::new({ - let mut __result = Vec::new(); - for pair in Rc::new( - lam_param_nodes - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.push({ - let pn = pair.1.clone(); - let param_name = match lam_params - .clone() - .iter() - .cloned() - .skip(pair.0.clone() as usize) - .next() - { - Some(n) => n.clone(), - None => "".to_string(), - }; - let param_type = - match v1_rt::map_get(&lam_scope.locals.clone(), param_name.clone()) { - Some(binding) => Some(Rc::new(InferredNode::Resolved { - node: binding.resolved.clone(), - })), - None => None, - }; - Rc::new(Node { - name: pn.name.clone(), - ident: pn.ident.clone(), - span: pn.span.clone(), - ident_span: pn.ident_span.clone(), - children: pn.children.clone(), - connective: pn.connective.clone(), - params: pn.params.clone(), - inferred: param_type.clone(), - return_cardinality: pn.return_cardinality.clone(), - uses: pn.uses.clone(), - body: pn.body.clone(), - transport: pn.transport.clone(), - properties: pn.properties.clone(), - type_annotation: pn.type_annotation.clone(), - is_self_recursive: pn.is_self_recursive.clone(), - has_non_tail_self_call: pn.has_non_tail_self_call.clone(), - match_pattern: pn.match_pattern.clone(), - expr_data: pn.expr_data.clone(), - }) - }); - } - __result - }); - let lam_texpr = make_expr_node( - Rc::new(ExprData::ExprLambda), - v1_rt::concat(Rc::new(vec![body_typed.clone()]), typed_param_nodes.clone()), - body_typed.inferred.clone(), - span.clone(), - ); - Rc::new(InferResult { - typed: lam_texpr.clone(), - diagnostics: body_diags.clone(), - }) - } - ExprData::ExprStringInterp => { - let span = texpr.span.clone(); - let typed_part_nodes = Rc::new({ - let mut __result = Vec::new(); - for part_node in texpr.children.clone().iter().cloned() { - __result.push(match (*part_node.expr_data.clone()).clone() { - ExprData::ExprLiteral { value: _, .. } => part_node.clone(), - _ => match part_node.children.clone().first().cloned() { - Some(inner) => { - let r = infer_expr(inner.clone(), scope.clone(), None); - make_interp_part_node(r.typed.clone(), part_node.span.clone()) - } - None => part_node.clone(), - }, - }); - } - __result - }); - let interp_diags = Rc::new({ - let mut __result = Vec::new(); - for part_node in texpr.children.clone().iter().cloned() { - __result.extend( - (*match (*part_node.expr_data.clone()).clone() { - ExprData::ExprLiteral { value: _, .. } => Rc::new(vec![]), - _ => match part_node.children.clone().first().cloned() { - Some(inner) => { - let r = infer_expr(inner.clone(), scope.clone(), None); - r.diagnostics.clone() - } - None => Rc::new(vec![]), - }, - }) - .iter() - .cloned(), - ); - } - __result - }); - let si_texpr = make_expr_node( - Rc::new(ExprData::ExprStringInterp), - typed_part_nodes.clone(), - Some(Rc::new(InferredNode::Resolved { - node: string_type(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: si_texpr.clone(), - diagnostics: interp_diags.clone(), - }) - } - ExprData::ExprBlock => { - let span = texpr.span.clone(); - let stmts = texpr.children.clone(); - if ((stmts.clone().len() as i64) > 0) { - { - let state = infer_block_stmts( - stmts.clone(), - (stmts.clone().len() as i64), - scope.clone(), - Rc::new(vec![]), - Rc::new(vec![]), - unit_type(), - expected.clone(), - ); - let blk_texpr = make_expr_node( - Rc::new(ExprData::ExprBlock), - state.typed_stmts.clone(), - Some(Rc::new(InferredNode::Resolved { - node: state.last_type.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: blk_texpr.clone(), - diagnostics: Rc::new({ - let mut __result = Vec::new(); - for c in state.diag_chunks.clone().iter().cloned() { - __result.extend((*c.clone()).iter().cloned()); - } - __result - }), - }) - } - } else { - ok_infer(make_expr_node( - Rc::new(ExprData::ExprBlock), - Rc::new(vec![]), - Some(Rc::new(InferredNode::Resolved { node: unit_type() })), - span.clone(), - )) - } - } - ExprData::ExprCast => { - let span = texpr.span.clone(); - let cast_inner = cast_expr(texpr.clone()); - let target_type = cast_target(texpr.clone()); - let inner_result = infer_expr(cast_inner.clone(), scope.clone(), None); - let inner_typed = inner_result.typed.clone(); - let inner_diags = inner_result.diagnostics.clone(); - let si = scope.type_env.clone().source_indices.clone(); - let target_name = authored_name_at(si.clone(), target_type.clone()); - let cast_diag = validate_cast( - inner_typed.inferred.clone(), - target_name.clone(), - span.clone(), - si.clone(), - scope.module_name.clone(), - ); - let cast_diags = match cast_diag.clone() { - Some(d) => Rc::new(vec![d.clone()]), - None => Rc::new(vec![]), - }; - let cast_optional_diags = optional_cast_diags( - inner_typed.inferred.clone(), - target_type.clone(), - span.clone(), - si.clone(), - scope.module_name.clone(), - ); - let cast_sole_ctor_diags = sole_constructor_construction_diags( - target_name.clone(), - span.clone(), - scope.clone(), - ); - let cast_refinement_diags = where_refinement_mismatch_diags( - target_type.clone(), - inner_typed.clone(), - span.clone(), - scope.module_name.clone(), - scope.type_env.clone(), - ); - let cast_texpr = make_expr_node( - Rc::new(ExprData::ExprCast), - Rc::new(vec![inner_typed.clone(), target_type.clone()]), - Some(Rc::new(InferredNode::Resolved { - node: target_type.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: cast_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat(inner_diags.clone(), cast_diags.clone()), - cast_optional_diags.clone(), - ), - cast_sole_ctor_diags.clone(), - ), - cast_refinement_diags.clone(), - ), - }) - } - ExprData::ExprForEach => { - let variable = - foreach_variable_at(texpr.clone(), scope.type_env.clone().source_indices.clone()); - let span = texpr.span.clone(); - let coll = foreach_collection(texpr.clone()); - let body_expr = foreach_body(texpr.clone()); - let coll_result = infer_expr(coll.clone(), scope.clone(), None); - let coll_typed = coll_result.typed.clone(); - let coll_diags = coll_result.diagnostics.clone(); - let elem_type_node = for_each_element_type_node( - resolved_type(coll_typed.clone()), - scope.type_env.clone().source_indices.clone(), - ); - let elem_provenance = derive_element_provenance( - coll_typed.clone(), - elem_type_node.clone(), - scope.clone(), - ); - let body_scope = extend_scope( - scope.clone(), - variable.clone(), - elem_type_node.clone(), - elem_provenance.clone(), - ); - let body_result = infer_expr(body_expr.clone(), body_scope.clone(), None); - let body_typed = body_result.typed.clone(); - let body_diags = body_result.diagnostics.clone(); - let fe_texpr = make_named_expr_node( - variable.clone(), - Rc::new(ExprData::ExprForEach), - Rc::new(vec![coll_typed.clone(), body_typed.clone()]), - body_typed.inferred.clone(), - span.clone(), - node_name_span(texpr.clone()), - ); - Rc::new(InferResult { - typed: fe_texpr.clone(), - diagnostics: v1_rt::concat(coll_diags.clone(), body_diags.clone()), - }) - } - ExprData::ExprIndex => { - let span = texpr.span.clone(); - let base_expr = index_base(texpr.clone()); - let idx_key = index_expr(texpr.clone()); - let base_result = infer_expr(base_expr.clone(), scope.clone(), None); - let base_typed = base_result.typed.clone(); - let base_diags = base_result.diagnostics.clone(); - let index_result = infer_expr(idx_key.clone(), scope.clone(), None); - let index_typed = index_result.typed.clone(); - let index_diags = index_result.diagnostics.clone(); - let index_check = match base_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { - node: base_type, .. - }) => match index_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { - node: index_type, .. - }) => Some(check_index_access_node( - base_type.clone(), - index_type.clone(), - span.clone(), - scope.module_name.clone(), - scope.type_env.clone().source_indices.clone(), - )), - _ => None, - }, - _ => None, - }; - let access_failure_inferred = match base_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: _, .. }) => index_typed.inferred.clone(), - _ => base_typed.inferred.clone(), - }; - let idx_inferred = match index_check.clone() { - Some(checked) => checked.inferred.clone(), - None => Some(inferred_or_error( - access_failure_inferred.clone(), - "invalid index access".to_string(), - span.clone(), - )), - }; - let index_access_diags = match index_check.clone() { - Some(checked) => checked.diagnostics.clone(), - None => Rc::new(vec![]), - }; - let idx_texpr = make_expr_node( - Rc::new(ExprData::ExprIndex), - Rc::new(vec![base_typed.clone(), index_typed.clone()]), - idx_inferred.clone(), - span.clone(), - ); - Rc::new(InferResult { - typed: idx_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat(base_diags.clone(), index_diags.clone()), - index_access_diags.clone(), - ), - }) - } - ExprData::ExprSlice => { - let span = texpr.span.clone(); - let base_expr = slice_base(texpr.clone()); - let start_expr = slice_start(texpr.clone()); - let end_expr = slice_end(texpr.clone()); - let base_result = infer_expr(base_expr.clone(), scope.clone(), None); - let base_typed = base_result.typed.clone(); - let base_diags = base_result.diagnostics.clone(); - let start_result = infer_expr(start_expr.clone(), scope.clone(), None); - let start_typed = start_result.typed.clone(); - let start_diags = start_result.diagnostics.clone(); - let end_result = infer_expr(end_expr.clone(), scope.clone(), None); - let end_typed = end_result.typed.clone(); - let end_diags = end_result.diagnostics.clone(); - let slice_check = match base_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { - node: base_type, .. - }) => match start_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { - node: start_type, .. - }) => match end_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: end_type, .. }) => { - Some(check_slice_access_node( - base_type.clone(), - start_type.clone(), - end_type.clone(), - span.clone(), - scope.module_name.clone(), - scope.type_env.clone().source_indices.clone(), - )) - } - _ => None, - }, - _ => None, - }, - _ => None, - }; - let access_failure_inferred = match base_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: _, .. }) => { - match start_typed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: _, .. }) => end_typed.inferred.clone(), - _ => start_typed.inferred.clone(), - } - } - _ => base_typed.inferred.clone(), - }; - let slc_inferred = match slice_check.clone() { - Some(checked) => checked.inferred.clone(), - None => Some(inferred_or_error( - access_failure_inferred.clone(), - "invalid slice access".to_string(), - span.clone(), - )), - }; - let slice_access_diags = match slice_check.clone() { - Some(checked) => checked.diagnostics.clone(), - None => Rc::new(vec![]), - }; - let slc_texpr = make_expr_node( - Rc::new(ExprData::ExprSlice), - Rc::new(vec![ - base_typed.clone(), - start_typed.clone(), - end_typed.clone(), - ]), - slc_inferred.clone(), - span.clone(), - ); - Rc::new(InferResult { - typed: slc_texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat(base_diags.clone(), start_diags.clone()), - end_diags.clone(), - ), - slice_access_diags.clone(), - ), - }) - } - ExprData::ExprReturn => { - let span = texpr.span.clone(); - let inner_expr = return_value(texpr.clone()); - let inner_result = infer_expr(inner_expr.clone(), scope.clone(), expected.clone()); - let ret_texpr = make_expr_node( - Rc::new(ExprData::ExprReturn), - Rc::new(vec![inner_result.typed.clone()]), - inner_result.typed.clone().inferred.clone(), - span.clone(), - ); - Rc::new(InferResult { - typed: ret_texpr.clone(), - diagnostics: inner_result.diagnostics.clone(), - }) - } - _ => { - let span = texpr.span.clone(); - Rc::new(InferResult { - typed: make_expr_error_node( - ExprErrorKind::InternalExprError, - "unhandled expression variant in infer_expr".to_string(), - span.clone(), - ), - diagnostics: Rc::new(vec![inference_error( - "unhandled expression variant in infer_expr".to_string(), - span.clone(), - scope.module_name.clone(), - )]), - }) - } - } -} - -pub fn infer_variant_constructor_call( - func_name: String, - call_args: Rc>>, - span: Rc, - name_span: Rc, - scope: Rc, -) -> Option> { - match lookup_variant_parent_enum(scope.clone(), func_name.clone()) { - None => None, - Some(parent_enum) => { - let si = scope.type_env.clone().source_indices.clone(); - match lookup_type_by_name(scope.type_env.clone(), parent_enum.clone()) { - Some(parent_node) => { - match find_child_named(parent_node.clone(), func_name.clone(), si.clone()) { - Some(variant_node) => { - if variant_has_positional_payload_shape( - variant_node.clone(), - si.clone(), - ) { - if ((call_args.clone().len() as i64) == 1) { - match call_args.clone().first().cloned() { - Some(arg) => match arg_name_at(arg.clone(), si.clone()) { - Some(arg_name) => { - let msg = v1_rt::concat(v1_rt::concat(v1_rt::concat(v1_rt::concat("positional variant constructor '".to_string(), func_name.clone()), "' does not accept named arguments (got '".to_string()), arg_name.clone()), ": ...')".to_string()); - Some(Rc::new(InferResult { - typed: semantic_expr_error_node( - msg.clone(), - arg.span.clone(), - ), - diagnostics: Rc::new(vec![inference_error( - msg.clone(), - arg.span.clone(), - scope.module_name.clone(), - )]), - })) - } - None => { - let payload_expr = arg_value(arg.clone()); - let payload_init = make_field_init_node( - "0".to_string(), - payload_expr.clone(), - payload_expr.span.clone(), - kernel_span("0".to_string()), - ); - Some(infer_record_lit( - Some(func_name.clone()), - Rc::new(vec![payload_init.clone()]), - span.clone(), - name_span.clone(), - scope.clone(), - None, - )) - } - }, - None => None, - } - } else { - { - let arity_msg = v1_rt::concat( - v1_rt::concat( - "positional variant constructor '".to_string(), - func_name.clone(), - ), - "' expects exactly one argument".to_string(), - ); - Some(Rc::new(InferResult { - typed: semantic_expr_error_node( - arity_msg.clone(), - span.clone(), - ), - diagnostics: Rc::new(vec![inference_error( - arity_msg.clone(), - span.clone(), - scope.module_name.clone(), - )]), - })) - } - } - } else { - None - } - } - None => None, - } - } - None => None, - } - } - } -} - -pub fn is_deferred_field_access_base(n: Rc, env: Rc) -> bool { - if ((n.inferred.clone() != None) && is_type_variable(n.inferred.clone().clone().unwrap())) { - true - } else { - if (((n.connective.clone() == Connective::NoConnective) - && ((n.children.clone().len() as i64) == 0)) - && (n.inferred.clone() == None)) - { - { - let name = authored_name_at(env.source_indices.clone(), n.clone()); - match lookup_type_by_name(env.clone(), name.clone()) { - Some(decl) => ((decl.params.clone().len() as i64) > 0), - None => false, - } - } - } else { - false - } - } -} - -pub fn needs_alias_field_expansion(n: Rc, env: Rc) -> bool { - if is_deferred_field_access_base(n.clone(), env.clone()) { - false - } else { - if ((n.connective.clone() == Connective::Conj) - || (n.connective.clone() == Connective::Disj)) - { - false - } else { - if (((n.connective.clone() == Connective::NoConnective) - && ((n.children.clone().len() as i64) > 0)) - && (n.inferred.clone() == None)) - { - is_user_generic_use_site(n.clone(), env.clone()) - } else { - match lookup_type_for(env.clone(), n.clone()) { - Some(binding) => { - if ((binding.connective.clone() == Connective::Conj) - || (binding.connective.clone() == Connective::Disj)) - { - ((n.connective.clone() == Connective::NoConnective) - && ((n.children.clone().len() as i64) == 0)) - } else { - if (((binding.connective.clone() == Connective::NoConnective) - && ((binding.children.clone().len() as i64) == 0)) - && (binding.inferred.clone() != None)) - { - true - } else { - if ((binding.connective.clone() == Connective::NoConnective) - && ((binding.children.clone().len() as i64) > 0)) - { - (is_user_generic_use_site(binding.clone(), env.clone()) - || (binding.inferred.clone() != None)) - } else { - false - } - } - } - } - None => false, - } - } - } - } -} - -pub fn call_locals_shadow_note() -> String { - thread_local! { - static CACHED: String = { - "Body-scope binders shadow the fn-sig lookup in the ExprCall arm (nearest-first precedence: body locals > module fns > census global_bare). Without this gate a corpus-unique census homonym out-precedes a `let` callee: refinement.dag's `let classify = by.classify; match classify(base)` typed the scrutinee as a v2 lens test module's `fn classify -> Optional`, refusing the match arms against the wrong enum (variant not found in Optional + non-exhaustive missing Absent/Present). The gate reads body_locals — the strict body-grain subset (let / match pattern / fn+lambda params) of scope.locals — because the module context pre-seeds locals with variant and service census bindings that must NOT eclipse fn sigs (an imported 0-arg fn would lose its sig to its own census row: html_fragment.dag's html_markup_medium() typed as an unresolved primitive). Absent sends the call down the local-callable path exactly as the pre-census seed did. Companion precedence law lives in func_sig_from_global_bare (infer_lookup): the census fallback never serves an algebra method-template name (filter/any/contains/…) — a whole-pool census entry for the UNLOADED v2.std.algebra must not preempt the known-method bridge (main-parity: on main such free calls type through the bridge; a census-served sig typed filter(xs, f) as a plain call to a never-loaded module and the runtime died NoSuchFunction).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn peel_alias_fixpoint_guard_note() -> String { - thread_local! { - static CACHED: String = { - "Termination (§4 boundedness) and diagnostic completeness (§5): peel iterates resolve_node toward a groundable form; a node that resolves to ITSELF (a self-resolving generic constructor such as List — NoConnective, children>0, inferred=none, unbound-or-identity under resolve) is a resolve FIXED POINT, the expansion frontier. Without the once==n check the recurse arm loops forever on that shape (measured: one peel call spun 3M+ iterations / 396M resolve calls on the #6640 total-census tree, witness test.claim.bmc_bootstrap_provision_witness, fp trace c1f861179e→d33138c3f8→256ee7d351 repeating — progress-then-self-loop, no >1-cycle, so consecutive-equal suffices; a memo cannot terminate it, only make each spin fast). The fixed-point/non-alias arm is a legitimate speculative probe miss ONLY when resolve_node returns no diagnostics. The old Node return projected .resolved and discarded .diagnostics, making that quiet miss byte-identical to a real resolver refusal and zeroing the refusal's frequency before CompileResult, compile-clean, and the diagnostic census could observe it. The peel now returns the existing NodeResolveResult authority and accumulates every hop's diagnostics. ExprFieldAccess and record-literal alias field discovery are judgment-producing callers and must carry those diagnostics. Variant-membership and emit-shaping callers are metadata-only probes: they may inspect .resolved but do not admit an executable artifact or own a diagnostic ledger, so making them emit would turn speculative shape lookup into a false red. No second peel outcome vocabulary is minted beside the resolver's own typed carrier.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn peel_alias_once_for_field_access( - n: Rc, - env: Rc, - module_name: String, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - let once = resolve_node(n.clone(), env.clone(), module_name.clone()); - let resolved_once = once.resolved.clone(); - if ((resolved_once.connective.clone() == Connective::Conj) - || (resolved_once.connective.clone() == Connective::Disj)) - { - once - } else { - if (((resolved_once.connective.clone() == Connective::NoConnective) - && ((resolved_once.children.clone().len() as i64) > 0)) - && (resolved_once.inferred.clone() == None)) - { - if (resolved_once.clone() == n.clone()) { - once - } else { - { - let rest = peel_alias_once_for_field_access( - resolved_once.clone(), - env.clone(), - module_name.clone(), - ); - Rc::new(NodeResolveResult { - resolved: rest.resolved.clone(), - diagnostics: v1_rt::concat( - once.diagnostics.clone(), - rest.diagnostics.clone(), - ), - }) - } - } - } else { - once - } - } - }) -} - -pub fn structural_from_expanded_type(normed: Rc) -> Rc { - match normed.connective.clone() { - Connective::Conj => normed, - Connective::Disj => normed, - _ => match normed.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: target, .. }) => match target.connective.clone() { - Connective::Conj => target.clone(), - Connective::Disj => target.clone(), - _ => normed, - }, - _ => normed, - }, - } -} - -pub fn record_field_type_is_unresolved_param( - field: Rc, - param_names: Rc>, - env: Rc, -) -> bool { - match product_field_result_type(field.clone()) { - Some(ft) => { - if ((ft.connective.clone() == Connective::NoConnective) - && ((ft.children.clone().len() as i64) == 0)) - { - match ft.inferred.clone() { - Some(inf) => is_type_variable(inf.clone()), - None => { - let fname = authored_name_at(env.source_indices.clone(), ft.clone()); - let in_params = { - let mut __found = false; - for pn in param_names.clone().iter().cloned() { - if (pn.clone() == fname.clone()) { - __found = true; - break; - } - } - __found - }; - let conv = is_type_variable_name(fname.clone()); - (in_params.clone() || conv.clone()) - } - } - } else { - false - } - } - None => false, - } -} - -pub fn record_has_unresolved_param_field(record: Rc, env: Rc) -> bool { - { - let param_names = Rc::new({ - let mut __result = Vec::new(); - for p in record.params.clone().iter().cloned() { - __result.push(generic_param_name_at(p.clone(), env.source_indices.clone())); - } - __result - }); - { - let mut __found = false; - for f in record.children.clone().iter().cloned() { - if record_field_type_is_unresolved_param( - f.clone(), - param_names.clone(), - env.clone(), - ) { - __found = true; - break; - } - } - __found - } - } -} - -pub fn alias_chain_generic_decl(env: Rc, carrier: Rc, target: Rc) -> Rc { - if ((target.params.clone().len() as i64) > 0) { - target - } else { - resolve_generic_use_decl(env.clone(), carrier.clone()) - } -} - -pub fn alias_chain_type_arg_subst( - env: Rc, - carrier: Rc, - target: Rc, - type_args: Rc>>, -) -> Rc>> { - { - let decl = alias_chain_generic_decl(env.clone(), carrier.clone(), target.clone()); - Rc::new( - decl.params - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, pair: (i64, Rc)| { - let slot = generic_param_name_at(pair.1.clone(), env.source_indices.clone()); - match type_args - .clone() - .iter() - .cloned() - .skip(pair.0.clone() as usize) - .next() - { - Some(arg) => v1_rt::rc_map_insert( - acc.clone(), - slot.clone(), - resolve_scrutinee_type_node(env.clone(), arg.clone()), - ), - None => acc.clone(), - } - }, - ) - } -} - -pub fn alias_chain_target_after_args( - target: Rc, - carrier: Rc, - env: Rc, -) -> Rc { - { - let type_args = carrier.children.clone(); - if ((type_args.clone().len() as i64) == 0) { - target.clone() - } else { - { - let decl = alias_chain_generic_decl(env.clone(), carrier.clone(), target.clone()); - let subst = alias_chain_type_arg_subst( - env.clone(), - carrier.clone(), - target.clone(), - type_args.clone(), - ); - let is_parameterized_alias = (((decl.inferred.clone() != None) - && ((decl.children.clone().len() as i64) == 0)) - && (decl.connective.clone() == Connective::NoConnective)); - if is_parameterized_alias.clone() { - match decl.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { - node: alias_body, .. - }) => substitute_generics( - alias_body.clone(), - subst.clone(), - env.source_indices.clone(), - ), - _ => target.clone(), - } - } else { - substitute_generics(decl.clone(), subst.clone(), env.source_indices.clone()) - } - } - } - } -} - -pub fn alias_chain_carrier(n: Rc) -> Rc { - if ((n.connective.clone() == Connective::NoConnective) && (n.name.clone() != "".to_string())) { - n - } else { - structural_from_expanded_type(n) - } -} - -pub fn expand_alias_chain_for_field_access( - n: Rc, - env: Rc, - module_name: String, - origin_name: String, - seen: Rc>, - lossy: bool, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - let peel_result = if needs_alias_field_expansion(n.clone(), env.clone()) { - peel_alias_once_for_field_access(n.clone(), env.clone(), module_name.clone()) - } else { - Rc::new(NodeResolveResult { - resolved: n.clone(), - diagnostics: Rc::new(vec![]), - }) - }; - let peeled = peel_result.resolved.clone(); - let carrier = alias_chain_carrier(peeled.clone()); - let carrier_name = if (carrier.name.clone() != "".to_string()) { - carrier.name.clone() - } else { - authored_name_at(env.source_indices.clone(), carrier.clone()) - }; - let structural = - structural_from_expanded_type(resolve_scrutinee_type_node(env.clone(), peeled.clone())); - let is_record = ((structural.connective.clone() == Connective::Conj) - || (structural.connective.clone() == Connective::Disj)); - if is_record.clone() { - { - let resolved_record = - if ((record_has_unresolved_param_field(structural.clone(), env.clone()) - && ((carrier.children.clone().len() as i64) > 0)) - && (carrier_name.clone() != "".to_string())) - { - match lookup_type_by_name(env.clone(), carrier_name.clone()) { - Some(target) => { - let subst = alias_chain_type_arg_subst( - env.clone(), - carrier.clone(), - target.clone(), - carrier.children.clone(), - ); - substitute_generics( - structural.clone(), - subst.clone(), - env.source_indices.clone(), - ) - } - None => structural.clone(), - } - } else { - structural.clone() - }; - let fail_closed = (lossy.clone() - && record_has_unresolved_param_field(resolved_record.clone(), env.clone())); - if fail_closed.clone() { - Rc::new(NodeResolveResult { - resolved: nominal_type_ref(origin_name.clone()), - diagnostics: peel_result.diagnostics.clone(), - }) - } else { - Rc::new(NodeResolveResult { - resolved: resolved_record.clone(), - diagnostics: peel_result.diagnostics.clone(), - }) - } - } - } else { - { - let next_name = carrier_name.clone(); - let is_optional = - (structural.return_cardinality.clone() == Cardinality::CardOptional); - if is_optional.clone() { - { - let expanded_inner = expand_alias_chain_for_field_access( - with_required_cardinality(structural.clone()), - env.clone(), - module_name.clone(), - origin_name.clone(), - seen.clone(), - lossy.clone(), - ); - Rc::new(NodeResolveResult { - resolved: with_optional_cardinality(expanded_inner.resolved.clone()), - diagnostics: v1_rt::concat( - peel_result.diagnostics.clone(), - expanded_inner.diagnostics.clone(), - ), - }) - } - } else { - { - let stop = ((next_name.clone() == "".to_string()) - || emit_map_has(seen.clone(), next_name.clone())); - if stop.clone() { - Rc::new(NodeResolveResult { - resolved: structural.clone(), - diagnostics: peel_result.diagnostics.clone(), - }) - } else { - match lookup_type_by_name(env.clone(), next_name.clone()) { - Some(target) => { - let next_seen = - v1_rt::rc_map_insert(seen.clone(), next_name.clone(), true); - let type_arg_count = (carrier.children.clone().len() as i64); - let decl = alias_chain_generic_decl( - env.clone(), - carrier.clone(), - target.clone(), - ); - let param_count = (decl.params.clone().len() as i64); - let dropped_args = (((type_arg_count.clone() > 0) - && (param_count.clone() > 0)) - && (param_count.clone() != type_arg_count.clone())); - let next_lossy = (lossy.clone() || dropped_args.clone()); - let next_n = if ((type_arg_count.clone() > 0) - && !dropped_args.clone()) - { - alias_chain_target_after_args( - target.clone(), - carrier.clone(), - env.clone(), - ) - } else { - target.clone() - }; - let expanded_next = expand_alias_chain_for_field_access( - next_n.clone(), - env.clone(), - module_name.clone(), - origin_name.clone(), - next_seen.clone(), - next_lossy.clone(), - ); - Rc::new(NodeResolveResult { - resolved: expanded_next.resolved.clone(), - diagnostics: v1_rt::concat( - peel_result.diagnostics.clone(), - expanded_next.diagnostics.clone(), - ), - }) - } - None => Rc::new(NodeResolveResult { - resolved: structural.clone(), - diagnostics: peel_result.diagnostics.clone(), - }), - } - } - } - } - } - } - }) -} - -pub fn expand_type_for_field_access_with_seen( - n: Rc, - env: Rc, - module_name: String, - seen: Rc>, -) -> Rc { - if is_deferred_field_access_base(n.clone(), env.clone()) { - Rc::new(NodeResolveResult { - resolved: n.clone(), - diagnostics: Rc::new(vec![]), - }) - } else { - { - let origin_name = authored_name_at(env.source_indices.clone(), n.clone()); - expand_alias_chain_for_field_access( - n.clone(), - env.clone(), - module_name.clone(), - origin_name.clone(), - seen.clone(), - false, - ) - } - } -} - -pub fn expand_type_for_field_access( - n: Rc, - env: Rc, - module_name: String, -) -> Rc { - expand_type_for_field_access_with_seen( - n.clone(), - env.clone(), - module_name.clone(), - v1_rt::rc_empty_map::(), - ) -} - -pub fn record_lit_alias_struct_expansion( - type_name: String, - scope: Rc, -) -> Option> { - match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { - Some(decl) => { - let to_expand = if (((decl.connective.clone() == Connective::NoConnective) - && ((decl.children.clone().len() as i64) == 0)) - && (decl.inferred.clone() != None)) - { - match decl.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: target, .. }) => target.clone(), - _ => decl.clone(), - } - } else { - decl.clone() - }; - Some(expand_type_for_field_access( - to_expand.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - )) - } - None => None, - } -} - -pub fn record_lit_construction_field_names( - type_name: String, - scope: Rc, -) -> Option>> { - { - let si = scope.type_env.clone().source_indices.clone(); - match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { - Some(decl) => { - if ((((decl.params.clone().len() as i64) == 0) - && (decl.connective.clone() == Connective::Conj)) - && ((decl.children.clone().len() as i64) > 0)) - { - Some(Rc::new({ - let mut __result = Vec::new(); - for f in decl.children.clone().iter().cloned() { - __result.push(authored_name_at(si.clone(), f.clone())); - } - __result - })) - } else { - None - } - } - None => None, - } - } -} - -pub fn field_in_any_variant_named(type_name: String, field: String, scope: Rc) -> bool { - { - let si = scope.type_env.clone().source_indices.clone(); - match variant_owner_node(scope.clone(), type_name.clone()) { - Some(owner) => { - let mut __found = false; - for arm in owner.children.clone().iter().cloned() { - if if (authored_name_at(si.clone(), arm.clone()) == type_name.clone()) { - { - let ea = expand_type_for_field_access( - arm.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ) - .resolved - .clone(); - let fields = if (ea.connective.clone() == Connective::Conj) { - ea.children.clone() - } else { - arm.children.clone() - }; - { - let mut __found = false; - for f in fields.clone().iter().cloned() { - if (authored_name_at(si.clone(), f.clone()) == field.clone()) { - __found = true; - break; - } - } - __found - } - } - } else { - false - } { - __found = true; - break; - } - } - __found - } - None => false, - } - } -} - -pub fn type_has_sole_constructor(type_name: String, scope: Rc) -> bool { - match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { - Some(decl) => { - let mut __found = false; - for p in decl.properties.clone().iter().cloned() { - if (p.name.clone() == "sole_constructor".to_string()) { - __found = true; - break; - } - } - __found - } - None => false, - } -} - -pub fn sole_constructor_construction_diags( - type_name: String, - span: Rc, - scope: Rc, -) -> Rc>> { - if type_has_sole_constructor(type_name.clone(), scope.clone()) { - match lookup_type_by_name(scope.type_env.clone(), type_name.clone()) { - Some(decl) => { - if (decl.span.clone().file.clone() == span.file.clone()) { - Rc::new(vec![]) - } else { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::SoleConstructorViolation { - type_name: type_name.clone(), - span: span.clone(), - }), - scope.module_name.clone(), - )]) - } - } - None => Rc::new(vec![]), - } - } else { - Rc::new(vec![]) - } -} - -pub fn zero_field_variant_tag_reference_frontier_note() -> String { - thread_local! { - static CACHED: String = { - "P0 field-wall frontier (operator Ruling 1a, 2026-07-15): a ZERO-field literal of a coproduct VARIANT (field_inits empty AND variant_owner_node != none) is sanctioned as a TAG REFERENCE, not a construction — the `discriminant(v: PrefixToken {})` idiom (16+ sites in src/v2/std/compilers/target_model.dag) names a variant to obtain its stable tag identity without materializing a value. Presence checking is skipped for exactly this shape; PARTIAL literals (any field present) stay red, and zero-field literals of NON-variant records (variant_owner_node == none) stay red — so the audit F1 probes (CacheProvider/CostAccount partial literals) are unaffected. This is a decidable structural exemption (not an absorbing fallback: it refuses precisely, never widens on failure). DISSOLVE-ON: a first-class variant-tag carrier that types the discriminant argument position, at which point the exemption is deleted and the sites migrate to the carrier.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn presence_check_census_gate_note() -> String { - thread_local! { - static CACHED: String = { - "Field-presence enforcement (P0 wall, #6663) stands down when the literal's bare type name is AMBIGUOUS in the corpus-wide census (global_bare, order-independent): with two same-named decls in the closure, every name-keyed template lookup below resolves by overlay-wins import order (a LEDGERED binding fork, see guarded_cache_union_note), so enforcing would GUESS which decl the author meant and red correct literals against the wrong layer's fields (2026-07-16 main-red: v2 nested Monoid/BooleanAlgebra/OrderedRing literals checked against dag/std flat shapes). Skipping on ambiguity is the pre-wall behavior for exactly those names; enforcement stays live for census-unique names (~98 percent of the corpus) AND for names this module DECLARES LOCALLY. The local carve-out is the one census-ambiguous case that still enforces, and it is read from TypeEnv.str_bindings ONLY: build_type_env sets str_bindings = local_str_bindings (this module's own declarations; the direct-import overlay lands in ancestry_str_bindings), and lookup_binding_by_name_local consults str_bindings FIRST, so a locally-declared name resolves to the local decl deterministically and order-independently - the precedence note's 'locals > kernel > direct-selected > transitive union' with no fork to guess (direct_import_export_precedence_note). The gate must NOT reach lookup_type_by_name here: that walks on into ancestry_str_bindings, i.e. the import-order overlay, which makes the WALL ITSELF order-dependent - the same source text refusing under one import order and passing under the other (reproduced 2026-07-20, target/probe-presencewall ARM SET A: probe.c1 'import a then b' passes while probe.c2 'import b then a' reds on one identical literal), which is exactly the GUESS this gate exists to refuse. Dissolve-on: containment SymbolIndex (namespace lane) makes the expected type scope-resolved; then this gate is dead code and the wall goes total. Ratchet (PR #6709 review, accepted): before the wall goes total, stand-downs become counted out-of-band ledger rows (binding_forks channel shape — LEDGERED, never diagnostics; a red refusal would re-red correct literals), landing with the SymbolIndex work that dissolves this gate.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn map_literal_expected_keyed_node( - type_name: Option, - expected: Option>, - scope: Rc, -) -> Option> { - match type_name.clone() { - Some(_) => None, - None => match expected.clone() { - Some(e) => { - if node_is_keyed_collection( - e.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(e.clone()) - } else { - None - } - } - None => None, - }, - } -} - -pub fn infer_map_literal( - map_node: Rc, - field_inits: Rc>>, - span: Rc, - scope: Rc, -) -> Rc { - { - let value_expected = match map_node - .children - .clone() - .iter() - .cloned() - .skip(1 as usize) - .next() - { - Some(v) => Some(v.clone()), - None => None, - }; - let fi_results = Rc::new({ - let mut __result = Vec::new(); - for fi in field_inits.clone().iter().cloned() { - __result.push({ - let ar = infer_expr( - field_init_node_value(fi.clone()), - scope.clone(), - value_expected.clone(), - ); - Rc::new(FieldInferResult { - typed_field: make_field_init_node( - field_init_node_name_at( - fi.clone(), - scope.type_env.clone().source_indices.clone(), - ), - ar.typed.clone(), - fi.span.clone(), - node_name_span(fi.clone()), - ), - infer_result: ar.clone(), - diagnostics: ar.diagnostics.clone(), - }) - }); - } - __result - }); - Rc::new(InferResult { - typed: make_expr_node( - Rc::new(ExprData::ExprRecordLit { parent_enum: None }), - Rc::new({ - let mut __result = Vec::new(); - for fir in fi_results.clone().iter().cloned() { - __result.push(fir.typed_field.clone()); - } - __result - }), - Some(Rc::new(InferredNode::Resolved { - node: map_node.clone(), - })), - span.clone(), - ), - diagnostics: Rc::new({ - let mut __result = Vec::new(); - for fir in fi_results.clone().iter().cloned() { - __result.extend((*fir.diagnostics.clone()).iter().cloned()); - } - __result - }), - }) - } -} - -pub fn infer_record_lit( - type_name: Option, - field_inits: Rc>>, - span: Rc, - name_span: Rc, - scope: Rc, - expected: Option>, -) -> Rc { - match map_literal_expected_keyed_node(type_name.clone(), expected.clone(), scope.clone()) { - Some(map_node) => infer_map_literal( - map_node.clone(), - field_inits.clone(), - span.clone(), - scope.clone(), - ), - None => infer_record_lit_structural( - type_name.clone(), - field_inits.clone(), - span.clone(), - name_span.clone(), - scope.clone(), - expected.clone(), - ), - } -} - -pub fn infer_record_lit_structural( - type_name: Option, - field_inits: Rc>>, - span: Rc, - name_span: Rc, - scope: Rc, - expected: Option>, -) -> Rc { - { - let instantiated_struct_fields = - record_lit_instantiated_fields(type_name.clone(), expected.clone(), scope.clone()); - let expected_struct_fields = if (instantiated_struct_fields.clone() == None) { - record_lit_fields_from_expected(type_name.clone(), expected.clone(), scope.clone()) - } else { - None - }; - let expected_variant_node = if ((instantiated_struct_fields.clone() == None) - && (expected_struct_fields.clone() == None)) - { - match type_name.clone() { - Some(_) => record_lit_variant_from_expected( - type_name.clone(), - expected.clone(), - scope.clone(), - ), - None => None, - } - } else { - None - }; - let alias_struct_expansion = match type_name.clone() { - Some(tn) => { - if ((((instantiated_struct_fields.clone() == None) - && (expected_struct_fields.clone() == None)) - && (expected_variant_node.clone() == None)) - && (expected.clone() == None)) - { - record_lit_alias_struct_expansion(tn.clone(), scope.clone()) - } else { - None - } - } - None => None, - }; - let struct_fields = match type_name.clone() { - Some(_) => match instantiated_struct_fields.clone() { - Some(fields) => fields.clone(), - None => match expected_struct_fields.clone() { - Some(fields) => fields.clone(), - None => match expected_variant_node.clone() { - Some(variant_node) => variant_node.children.clone(), - None => match expected.clone() { - Some(_) => record_lit_expected_fields(type_name.clone(), scope.clone()), - None => match alias_struct_expansion.clone() { - Some(expansion) => { - if ((expansion.resolved.clone().connective.clone() - == Connective::Conj) - && ((expansion.resolved.clone().children.clone().len() - as i64) - > 0)) - { - expansion.resolved.clone().children.clone() - } else { - record_lit_expected_fields(type_name.clone(), scope.clone()) - } - } - None => { - record_lit_expected_fields(type_name.clone(), scope.clone()) - } - }, - }, - }, - }, - }, - None => match instantiated_struct_fields.clone() { - Some(fields) => fields.clone(), - None => match expected_struct_fields.clone() { - Some(fields) => fields.clone(), - None => record_lit_expected_fields(type_name.clone(), scope.clone()), - }, - }, - }; - let alias_struct_diags = match alias_struct_expansion.clone() { - Some(expansion) => expansion.diagnostics.clone(), - None => Rc::new(vec![]), - }; - let construction_field_names = match type_name.clone() { - Some(tn) => record_lit_construction_field_names(tn.clone(), scope.clone()), - None => None, - }; - let tn_str = match type_name.clone() { - Some(tn) => tn.clone(), - None => "".to_string(), - }; - let si_presence = scope.type_env.clone().source_indices.clone(); - let presence_variant_owner = variant_owner_node(scope.clone(), tn_str.clone()); - let presence_fields = if (tn_str.clone() == "".to_string()) { - Rc::new(vec![]) - } else { - match presence_variant_owner.clone() { - Some(variant_owner) => match Rc::new({ - let mut __result = Vec::new(); - for v in variant_owner.children.clone().iter().cloned() { - if (authored_name_at(si_presence.clone(), v.clone()) - == qualified_last_segment(tn_str.clone())) - { - __result.push(v); - } - } - __result - }) - .first() - .cloned() - { - Some(variant_node) => variant_node.children.clone(), - None => Rc::new(vec![]), - }, - None => match record_lit_variant_from_expected( - type_name.clone(), - expected.clone(), - scope.clone(), - ) { - Some(variant_node) => variant_node.children.clone(), - None => match instantiated_struct_fields.clone() { - Some(inst_fields) => inst_fields.clone(), - None => match lookup_type_by_name(scope.type_env.clone(), tn_str.clone()) { - Some(decl) => { - if (((decl.connective.clone() == Connective::Conj) - && ((decl.params.clone().len() as i64) == 0)) - && ((decl.children.clone().len() as i64) > 0)) - { - decl.children.clone() - } else { - Rc::new(vec![]) - } - } - None => record_lit_expected_fields(type_name.clone(), scope.clone()), - }, - }, - }, - } - }; - let is_zero_field_variant_tag_reference = - (((field_inits.clone().len() as i64) == 0) && (presence_variant_owner.clone() != None)); - let presence_name_is_ambiguous = - (global_bare_is_ambiguous(scope.type_env.clone(), tn_str.clone()) - && (v1_rt::map_get(&scope.type_env.clone().str_bindings.clone(), tn_str.clone()) - == None)); - let presence_ambiguity_refusal_diags = if ((tn_str.clone() != "".to_string()) - && (v1_rt::map_get(&scope.type_env.clone().str_bindings.clone(), tn_str.clone()) - == None)) - { - { - let strict_cands = - global_bare_strict_ambiguity_candidates(scope.type_env.clone(), tn_str.clone()); - if ((strict_cands.clone().len() as i64) > 0) { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::AmbiguousReference { - name: tn_str.clone(), - candidates: strict_cands.clone(), - span: name_span.clone(), - }), - scope.module_name.clone(), - )]) - } else { - Rc::new(vec![]) - } - } - } else { - Rc::new(vec![]) - }; - let missing_field_diags = if ((((tn_str.clone() == "".to_string()) - || ((presence_fields.clone().len() as i64) == 0)) - || is_zero_field_variant_tag_reference.clone()) - || presence_name_is_ambiguous.clone()) - { - Rc::new(vec![]) - } else { - Rc::new({ - let mut __result = Vec::new(); - for sf in Rc::new({ - let mut __result = Vec::new(); - for sf in presence_fields.clone().iter().cloned() { - if { - let sf_type = match sf.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), - _ => field_node_type_expr(sf.clone()), - }; - (((sf_type.return_cardinality.clone() != Cardinality::CardOptional) - && (sf.body.clone() == None)) - && ({ - let mut __found = false; - for fi in field_inits.clone().iter().cloned() { - if (field_init_node_name_at( - fi.clone(), - si_presence.clone(), - ) == authored_name_at(si_presence.clone(), sf.clone())) - { - __found = true; - break; - } - } - __found - } == false)) - } { - __result.push(sf); - } - } - __result - }) - .iter() - .cloned() - { - __result.push(make_error_node( - Rc::new(CompilerDiagnostic::MissingField { - field: authored_name_at(si_presence.clone(), sf.clone()), - type_name: tn_str.clone(), - span: name_span.clone(), - }), - scope.module_name.clone(), - )); - } - __result - }) - }; - let fi_infer_results = Rc::new({ - let mut __result = Vec::new(); - for fi in field_inits.clone().iter().cloned() { - __result.push({ - let fi_name = field_init_node_name_at( - fi.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let unknown_field_diags = match construction_field_names.clone() { - Some(names) => { - if ({ - let mut __found = false; - for n in names.clone().iter().cloned() { - if (n.clone() == fi_name.clone()) { - __found = true; - break; - } - } - __found - } || field_in_any_variant_named( - tn_str.clone(), - fi_name.clone(), - scope.clone(), - )) { - Rc::new(vec![]) - } else { - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::FieldNotFound { - field: fi_name.clone(), - type_name: tn_str.clone(), - span: fi.span.clone(), - }), - scope.module_name.clone(), - )]) - } - } - None => Rc::new(vec![]), - }; - let field_declared_type = match Rc::new({ - let mut __result = Vec::new(); - for sf in struct_fields.clone().iter().cloned() { - if (authored_name_at( - scope.type_env.clone().source_indices.clone(), - sf.clone(), - ) == fi_name.clone()) - { - __result.push(sf); - } - } - __result - }) - .first() - .cloned() - { - Some(sf) => Some(field_declared_type_node(sf.clone())), - None => None, - }; - let field_expected = match field_declared_type.clone() { - Some(ft) => { - if ((((ft.ident_span.clone() != None) - || type_node_is_callable(ft.clone())) - || (ft.return_cardinality.clone() == Cardinality::CardOptional)) - || field_type_is_optional_coproduct( - ft.clone(), - scope.type_env.clone(), - )) - { - Some(ft.clone()) - } else { - None - } - } - None => None, - }; - let ar = infer_expr( - field_init_node_value(fi.clone()), - scope.clone(), - field_expected.clone(), - ); - let ar_typed = ar.typed.clone(); - let ar_diags = ar.diagnostics.clone(); - let field_type_diags = match field_declared_type.clone() { - Some(expected_node) => { - let got_node = resolved_type(ar_typed.clone()); - if rejects_string_for_optional_coproduct_field( - expected_node.clone(), - got_node.clone(), - scope.type_env.clone().source_indices.clone(), - scope.type_env.clone(), - ) { - { - let expected_for_shape = match lookup_type_for( - scope.type_env.clone(), - with_required_cardinality(expected_node.clone()), - ) { - Some(resolved) => resolved.clone(), - None => expected_node.clone(), - }; - Rc::new(vec![type_mismatch_error( - node_type_shape( - expected_for_shape.clone(), - scope.type_env.clone().source_indices.clone(), - ), - node_type_shape( - got_node.clone(), - scope.type_env.clone().source_indices.clone(), - ), - ar_typed.span.clone(), - scope.module_name.clone(), - )]) - } - } else { - { - let expected_required = match lookup_type_for( - scope.type_env.clone(), - with_required_cardinality(expected_node.clone()), - ) { - Some(resolved) => resolved.clone(), - None => with_required_cardinality(expected_node.clone()), - }; - let formal_peeled = peel_nominal_alias_identity( - expected_required.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ); - let actual_peeled = peel_nominal_alias_identity( - got_node.clone(), - scope.type_env.clone(), - scope.module_name.clone(), - ); - if kernel_value_declared_type_mismatch( - formal_peeled.clone(), - actual_peeled.clone(), - scope.type_env.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Rc::new(vec![type_mismatch_error( - node_type_shape( - formal_peeled.clone(), - scope.type_env.clone().source_indices.clone(), - ), - node_type_shape( - actual_peeled.clone(), - scope.type_env.clone().source_indices.clone(), - ), - ar_typed.span.clone(), - scope.module_name.clone(), - )]) - } else { - if structured_application_site_type_mismatch( - expected_node.clone(), - field_init_node_value(fi.clone()), - scope.clone(), - ) { - Rc::new(vec![type_mismatch_error( - node_type_shape( - formal_peeled.clone(), - scope.type_env.clone().source_indices.clone(), - ), - node_type_shape( - actual_peeled.clone(), - scope.type_env.clone().source_indices.clone(), - ), - ar_typed.span.clone(), - scope.module_name.clone(), - )]) - } else { - Rc::new(vec![]) - } - } - } - } - } - None => Rc::new(vec![]), - }; - Rc::new(FieldInferResult { - typed_field: make_field_init_node( - fi_name.clone(), - ar_typed.clone(), - fi.span.clone(), - node_name_span(fi.clone()), - ), - infer_result: ar.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat(ar_diags.clone(), field_type_diags.clone()), - unknown_field_diags.clone(), - ), - bare_none_field_construction_diags( - fi.clone(), - fi_name.clone(), - field_declared_type.clone(), - tn_str.clone(), - scope.clone(), - ), - ), - }) - }); - } - __result - }); - let typed_fields = Rc::new({ - let mut __result = Vec::new(); - for fir in fi_infer_results.clone().iter().cloned() { - __result.push(fir.typed_field.clone()); - } - __result - }); - let fi_diags = Rc::new({ - let mut __result = Vec::new(); - for fir in fi_infer_results.clone().iter().cloned() { - __result.extend((*fir.diagnostics.clone()).iter().cloned()); - } - __result - }); - if (type_name.clone() == None) { - { - let child_nodes = Rc::new({ - let mut __result = Vec::new(); - for fir in fi_infer_results.clone().iter().cloned() { - __result.push(Rc::new(Node { - name: field_init_node_name_at( - fir.typed_field.clone(), - scope.type_env.clone().source_indices.clone(), - ), - span: fir.typed_field.clone().span.clone(), - ident_span: fir.typed_field.clone().ident_span.clone(), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: fir.infer_result.clone().typed.clone().inferred.clone(), - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - })); - } - __result - }); - let anon_node = Rc::new(Node { - name: "".to_string(), - span: no_span(), - ident_span: None, - children: child_nodes.clone(), - connective: Connective::Conj, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let typed_field_nodes = typed_fields.clone(); - let texpr = make_expr_node( - Rc::new(ExprData::ExprRecordLit { parent_enum: None }), - typed_field_nodes.clone(), - Some(Rc::new(InferredNode::Resolved { - node: anon_node.clone(), - })), - span.clone(), - ); - Rc::new(InferResult { - typed: texpr.clone(), - diagnostics: v1_rt::concat(fi_diags.clone(), alias_struct_diags.clone()), - }) - } - } else { - { - let type_lookup = - lookup_type_by_name(scope.type_env.clone(), type_name.clone().unwrap()); - let local_variant_parent = - match lookup_variant_parent_enum(scope.clone(), type_name.clone().unwrap()) { - Some(p) => Some(p.clone()), - None => match variant_owner_node(scope.clone(), type_name.clone().unwrap()) - { - Some(owner) => Some(authored_name_at( - scope.type_env.clone().source_indices.clone(), - owner.clone(), - )), - None => record_lit_parent_enum_from_expected( - type_name.clone().unwrap(), - expected.clone(), - scope.clone(), - ), - }, - }; - let effective_lookup = match type_lookup.clone() { - Some(_) => type_lookup.clone(), - None => { - let local_lookup = - lookup_in_scope(scope.locals.clone(), type_name.clone().unwrap()); - match local_lookup.clone() { - Some(local_node) => { - lookup_type_for(scope.type_env.clone(), local_node.clone()) - } - None => match record_lit_variant_from_expected( - type_name.clone(), - expected.clone(), - scope.clone(), - ) { - Some(_) => { - record_lit_expected_coproduct(expected.clone(), scope.clone()) - } - None => None, - }, - } - } - }; - let variant_lookup_resolved = match effective_lookup.clone() { - Some(tn) => tn.clone(), - None => error_type(), - }; - let type_name_declares_own_type = match lookup_binding_by_name( - scope.type_env.clone(), - type_name.clone().unwrap(), - ) { - Some(name_binding) => binding_declares_name( - name_binding.clone(), - type_name.clone().unwrap(), - scope.type_env.clone().source_indices.clone(), - ), - None => false, - }; - let raw_resolved = match local_variant_parent.clone() { - Some(parent_name) => { - if ((parent_name.clone() == "Optional".to_string()) - || type_name_declares_own_type.clone()) - { - variant_lookup_resolved.clone() - } else { - match lookup_type_by_name(scope.type_env.clone(), parent_name.clone()) { - Some(parent_decl) => parent_decl.clone(), - None => variant_lookup_resolved.clone(), - } - } - } - None => variant_lookup_resolved.clone(), - }; - let expected_optional_parent = Some("Optional".to_string()); - let is_present_ctor = ((type_name.clone().unwrap() == "Present".to_string()) - && (local_variant_parent.clone().as_deref() - == expected_optional_parent.clone().as_deref())); - let resolved_node = if is_present_ctor.clone() { - { - let val_field = Rc::new({ - let mut __result = Vec::new(); - for fir in fi_infer_results.clone().iter().cloned() { - if (field_init_node_name_at( - fir.typed_field.clone(), - scope.type_env.clone().source_indices.clone(), - ) == "value".to_string()) - { - __result.push(fir); - } - } - __result - }) - .first() - .cloned(); - match val_field.clone() { - Some(val_fir) => with_optional_cardinality(resolved_type( - val_fir.infer_result.clone().typed.clone(), - )), - None => raw_resolved.clone(), - } - } - } else { - raw_resolved.clone() - }; - let type_diags = match effective_lookup.clone() { - Some(_) => Rc::new(vec![]), - None => Rc::new(vec![make_error_node( - bare_name_miss_diagnostic( - scope.type_env.clone(), - type_name.clone().unwrap(), - span.clone(), - ), - scope.module_name.clone(), - )]), - }; - let sole_ctor_diags = sole_constructor_construction_diags( - type_name.clone().unwrap(), - span.clone(), - scope.clone(), - ); - let typed_field_nodes2 = typed_fields.clone(); - let rl_name = match type_name.clone() { - Some(tn_val) => tn_val.clone(), - None => "".to_string(), - }; - let texpr = make_named_expr_node( - rl_name.clone(), - Rc::new(ExprData::ExprRecordLit { - parent_enum: local_variant_parent.clone(), - }), - typed_field_nodes2.clone(), - Some(Rc::new(InferredNode::Resolved { - node: resolved_node.clone(), - })), - span.clone(), - name_span.clone(), - ); - let presence_ambiguity_diags = if ((type_diags.clone().len() as i64) > 0) { - Rc::new(vec![]) - } else { - presence_ambiguity_refusal_diags.clone() - }; - Rc::new(InferResult { - typed: texpr.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat(fi_diags.clone(), alias_struct_diags.clone()), - type_diags.clone(), - ), - sole_ctor_diags.clone(), - ), - missing_field_diags.clone(), - ), - presence_ambiguity_diags.clone(), - ), - }) - } - } - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -#[serde(tag = "_variant")] -pub enum DescentSizeExpr { - ParamSize { param: String }, - DividedSize { param: String, divisor: i64 }, -} -impl DescentSizeExpr { - pub fn param(&self) -> String { - match self { - DescentSizeExpr::ParamSize { param: __val, .. } => __val.clone(), - DescentSizeExpr::DividedSize { param: __val, .. } => __val.clone(), - } - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct DescentContext { - pub fn_name: String, - pub param_names: Rc>, - pub param_order: Rc>, - pub type_env: Rc, - pub sub_value_vars: Rc>>, - pub size_aliases: Rc>>, - pub scope_locals: Rc>>, - pub func_env: Rc, - pub per_field_vars: Rc>>>>, -} - -pub fn classify_size_expr(val: Rc, ctx: Rc) -> Option> { - match (*val.expr_data.clone()).clone() { - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let mname = - expr_method_name_at(val.clone(), ctx.type_env.clone().source_indices.clone()); - if (mname.clone() == "count".to_string()) { - { - let receiver = method_receiver(val.clone()); - match (*receiver.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let rname = expr_var_name_at( - receiver.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.param_names.clone(), rname.clone()) { - Some(_) => Some(Rc::new(DescentSizeExpr::ParamSize { - param: rname.clone(), - })), - None => None, - } - } - _ => None, - } - } - } else { - None - } - } - ExprData::ExprBinOp { .. } => { - let left = binop_left(val.clone()); - let right = binop_right(val.clone()); - match (*val.expr_data.clone()).clone() { - ExprData::ExprBinOp { op: BinOp::Div, .. } => { - match (*left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let lname = expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.size_aliases.clone(), lname.clone()) - .as_deref() - .cloned() - { - Some(DescentSizeExpr::ParamSize { param: p, .. }) => { - match expr_literal_int_optional(right.clone()) { - Some(d) => { - if (d.clone() > 0) { - Some(Rc::new(DescentSizeExpr::DividedSize { - param: p.clone(), - divisor: d.clone(), - })) - } else { - None - } - } - None => None, - } - } - _ => None, - } - } - _ => None, - } - } - _ => None, - } - } - _ => None, - } -} - -pub fn proportional_skip_alias_plus_literal( - alias_expr: Rc, - lit_expr: Rc, - param_name: String, - ctx: Rc, -) -> Option> { - match (*alias_expr.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let aname = expr_var_name_at( - alias_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.size_aliases.clone(), aname.clone()) - .as_deref() - .cloned() - { - Some(DescentSizeExpr::DividedSize { - param: p, - divisor: d, - .. - }) => { - if (p.clone() == param_name.clone()) { - match expr_literal_int_optional(lit_expr.clone()) { - Some(k) => { - if (k.clone() > 0) { - match proportional_divisor_from_int_at_least_two(d.clone()) { - Some(div_w) => { - let synth_field = Rc::new(InductiveField { - type_name: param_name.clone(), - variant_name: "".to_string(), - field_name: "skip".to_string(), - shape: RecursionShape::ListRecursion, - element_type: param_name.clone(), - }); - Some(Rc::new(SubValueRelation::StrictSubValue { - field: synth_field.clone(), - factor: Rc::new(ShrinkFactor::ProportionalShrink { - divisor: div_w.clone(), - }), - })) - } - None => None, - } - } else { - None - } - } - None => None, - } - } else { - None - } - } - _ => None, - } - } - _ => None, - } -} - -pub fn classify_collection_shrink( - arg_expr: Rc, - param_name: String, - ctx: Rc, -) -> Rc { - match (*arg_expr.expr_data.clone()).clone() { - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let mname = expr_method_name_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if ((mname.clone() == "take".to_string()) || (mname.clone() == "skip".to_string())) { - { - let receiver = method_receiver(arg_expr.clone()); - match (*receiver.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let rname = expr_var_name_at( - receiver.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if (rname.clone() == param_name.clone()) { - { - let args = method_arg_nodes(arg_expr.clone()); - match args.clone().first().cloned() { - Some(arg_node) => { - let arg_val = arg_value(arg_node.clone()); - match expr_literal_int_optional(arg_val.clone()) { - Some(k) => { - if ((k.clone() > 0) - && (mname.clone() == "skip".to_string())) - { - match positive_descent_amount_from_positive_int(k.clone()) { - Some(steps) => { - let synth_field = Rc::new(InductiveField { - type_name: param_name.clone(), - variant_name: "".to_string(), - field_name: mname.clone(), - shape: RecursionShape::ListRecursion, - element_type: param_name.clone(), -}); -Rc::new(SubValueRelation::StrictSubValue { - field: synth_field.clone(), - factor: Rc::new(ShrinkFactor::ConstantShrink { - steps: steps.clone(), -}), -}) -}, - None => Rc::new(SubValueRelation::SubValueUnknown), -} - } else { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - None => { - match (*arg_val.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, - .. - } => { - let aname = expr_var_name_at( - arg_val.clone(), - ctx.type_env - .clone() - .source_indices - .clone(), - ); - match v1_rt::map_get(&ctx.size_aliases.clone(), aname.clone()).as_deref().cloned() { - Some(DescentSizeExpr::DividedSize { param: p, divisor: d, .. }) => if (p.clone() == param_name.clone()) { - match proportional_divisor_from_int_at_least_two(d.clone()) { - Some(div_w) => { - let synth_field = Rc::new(InductiveField { - type_name: param_name.clone(), - variant_name: "".to_string(), - field_name: mname.clone(), - shape: RecursionShape::ListRecursion, - element_type: param_name.clone(), -}); -Rc::new(SubValueRelation::StrictSubValue { - field: synth_field.clone(), - factor: Rc::new(ShrinkFactor::ProportionalShrink { - divisor: div_w.clone(), -}), -}) -}, - None => Rc::new(SubValueRelation::SubValueUnknown), -} - } else { - Rc::new(SubValueRelation::SubValueUnknown) - }, - _ => Rc::new(SubValueRelation::SubValueUnknown), -} - } - ExprData::ExprBinOp { op, .. } => match op - .clone() - { - BinOp::Add => { - if (mname.clone() - == "skip".to_string()) - { - { - let left = binop_left( - arg_val.clone(), - ); - let right = binop_right( - arg_val.clone(), - ); - match proportional_skip_alias_plus_literal(left.clone(), right.clone(), param_name.clone(), ctx.clone()) { - Some(rel) => rel.clone(), - None => match proportional_skip_alias_plus_literal(right.clone(), left.clone(), param_name.clone(), ctx.clone()) { - Some(rel) => rel.clone(), - None => Rc::new(SubValueRelation::SubValueUnknown), -}, -} - } - } else { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - BinOp::Sub => Rc::new( - SubValueRelation::SubValueUnknown, - ), - _ => Rc::new( - SubValueRelation::SubValueUnknown, - ), - }, - _ => Rc::new( - SubValueRelation::SubValueUnknown, - ), - } - } - } - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - } else { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } - } - } else { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BlockAnnotateAcc { - pub ctx: Rc, - pub children: Rc>>, -} - -pub fn method_callback_element_position(semantics: Option>) -> Option { - match semantics.clone().as_deref().cloned() { - Some(MethodSemantics::AlgebraMethodSemantics { - algebra_template: at, - .. - }) => match at.clone() { - Some(template) => template.callback_element_position.clone(), - None => None, - }, - _ => None, - } -} - -pub fn maybe_insert_composed_field_relation( - acc: Rc>>, - fname: String, - composed: Option>, -) -> Rc>> { - match composed.clone() { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::SubValueUnknown => acc, - _ => v1_rt::rc_map_insert(acc, fname.clone(), rel.clone()), - }, - None => acc, - } -} - -pub fn maybe_insert_output_field_relation( - acc: Rc>>, - idx: i64, - fname: String, - sig: Rc, - val: Rc, - ctx: Rc, -) -> Rc>> { - { - let composed = match sig - .output_provenance - .clone() - .iter() - .cloned() - .skip(idx.clone() as usize) - .next() - { - Some(param_map) => { - classify_call_via_provenance(val.clone(), param_map.clone(), ctx.clone()) - } - None => None, - }; - maybe_insert_composed_field_relation(acc.clone(), fname.clone(), composed.clone()) - } -} - -pub fn maybe_insert_match_field_relation( - fp_acc: Rc>>, - pname: String, - field_label: String, - vname: String, - scrut_rel: Option>, - param_types: Rc>, - type_env: Rc, -) -> Rc>> { - match scrut_rel.clone() { - Some(rel) => { - let lookup_type = match (*rel.clone()).clone() { - SubValueRelation::PreservedValue => { - match v1_rt::map_get(¶m_types, pname.clone()) { - Some(t) => t.clone(), - None => "".to_string(), - } - } - SubValueRelation::StrictSubValue { field: f, .. } => f.element_type.clone(), - SubValueRelation::IteratedSubValue { field: f, .. } => f.element_type.clone(), - _ => "".to_string(), - }; - if (lookup_type.clone() != "".to_string()) { - { - let ind_fields = inductive_fields_for(type_env.clone(), lookup_type.clone()); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in ind_fields.clone().iter().cloned() { - if ((f.field_name.clone() == field_label.clone()) - && ((f.variant_name.clone() == vname.clone()) - || (f.variant_name.clone() == "".to_string()))) - { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => v1_rt::rc_map_insert( - fp_acc.clone(), - pname.clone(), - compose_sub_value(rel.clone(), ind_field.clone()), - ), - None => fp_acc.clone(), - } - } - } else { - fp_acc.clone() - } - } - None => fp_acc.clone(), - } -} - -pub fn build_per_field_for_let( - val: Rc, - binding_name: String, - ctx: Rc, -) -> Rc>>>> { - match (*val.expr_data.clone()).clone() { - ExprData::ExprCall { .. } => { - let callee = - expr_call_func_at(val.clone(), ctx.type_env.clone().source_indices.clone()); - match func_sig_if_resolved(lookup_func_sig( - ctx.func_env.clone(), - ctx.type_env.clone(), - callee.clone(), - )) { - Some(sig) => { - if ((sig.output_provenance.clone().len() as i64) > 1) { - { - let return_type = sig.inferred.clone(); - let field_map = Rc::new( - return_type - .children - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, - pair: (i64, Rc)| { - let idx = pair.0.clone(); - let field_node = pair.1.clone(); - let fname = authored_name_at( - ctx.type_env.clone().source_indices.clone(), - field_node.clone(), - ); - maybe_insert_output_field_relation( - acc, - idx.clone(), - fname.clone(), - sig.clone(), - val.clone(), - ctx.clone(), - ) - }, - ); - if ((Rc::new(v1_rt::map_keys(&field_map)).len() as i64) > 0) { - v1_rt::rc_map_insert( - ctx.per_field_vars.clone(), - binding_name.clone(), - field_map.clone(), - ) - } else { - ctx.per_field_vars.clone() - } - } - } else { - ctx.per_field_vars.clone() - } - } - None => ctx.per_field_vars.clone(), - } - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let callee = - expr_method_name_at(val.clone(), ctx.type_env.clone().source_indices.clone()); - match func_sig_if_resolved(lookup_func_sig( - ctx.func_env.clone(), - ctx.type_env.clone(), - callee.clone(), - )) { - Some(sig) => { - if ((sig.output_provenance.clone().len() as i64) > 1) { - { - let return_type = sig.inferred.clone(); - let field_map = Rc::new( - return_type - .children - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, - pair: (i64, Rc)| { - let idx = pair.0.clone(); - let field_node = pair.1.clone(); - let fname = authored_name_at( - ctx.type_env.clone().source_indices.clone(), - field_node.clone(), - ); - maybe_insert_output_field_relation( - acc, - idx.clone(), - fname.clone(), - sig.clone(), - val.clone(), - ctx.clone(), - ) - }, - ); - if ((Rc::new(v1_rt::map_keys(&field_map)).len() as i64) > 0) { - v1_rt::rc_map_insert( - ctx.per_field_vars.clone(), - binding_name.clone(), - field_map.clone(), - ) - } else { - ctx.per_field_vars.clone() - } - } - } else { - ctx.per_field_vars.clone() - } - } - None => ctx.per_field_vars.clone(), - } - } - _ => ctx.per_field_vars.clone(), - } -} - -pub fn resolve_collection_field( - mut expr: Rc, - mut ctx: Rc, -) -> Option> { - loop { - match (*expr.expr_data.clone()).clone() { - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(expr.clone()); - let fname = field_access_field_at( - expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = expr_var_name_at( - base.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let base_type = - match v1_rt::map_get(&ctx.param_names.clone(), bname.clone()) { - Some(t) => t.clone(), - None => { - match v1_rt::map_get(&ctx.sub_value_vars.clone(), bname.clone()) - { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { - field: f, .. - } => f.element_type.clone(), - SubValueRelation::IteratedSubValue { - field: f, .. - } => f.element_type.clone(), - _ => "".to_string(), - }, - None => "".to_string(), - } - } - }; - if (base_type.clone() != "".to_string()) { - break Rc::new({ - let mut __result = Vec::new(); - for f in Rc::new({ - let mut __result = Vec::new(); - for f in inductive_fields_for( - ctx.type_env.clone(), - base_type.clone(), - ) - .iter() - .cloned() - { - if (f.field_name.clone() == fname.clone()) { - __result.push(f); - } - } - __result - }) - .iter() - .cloned() - { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, - } { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - } else { - break None; - } - } - _ => { - break None; - } - } - } - ExprData::ExprVar { - binding_kind: _, .. - } => { - let rname = - expr_var_name_at(expr.clone(), ctx.type_env.clone().source_indices.clone()); - match v1_rt::map_get(&ctx.sub_value_vars.clone(), rname.clone()) { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { field: f, .. } => { - match f.shape.clone() { - RecursionShape::ListRecursion => { - break Some(f.clone()); - } - _ => { - break None; - } - } - } - SubValueRelation::IteratedSubValue { field: f, .. } => { - match f.shape.clone() { - RecursionShape::ListRecursion => { - break Some(f.clone()); - } - _ => { - break None; - } - } - } - _ => { - break None; - } - }, - None => { - break None; - } - } - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let inner_mname = - expr_method_name_at(expr.clone(), ctx.type_env.clone().source_indices.clone()); - let is_collection_preserving = (((((inner_mname.clone() - == "enumerate".to_string()) - || (inner_mname.clone() == "skip".to_string())) - || (inner_mname.clone() == "take".to_string())) - || (inner_mname.clone() == "filter".to_string())) - || (inner_mname.clone() == "reverse".to_string())); - if is_collection_preserving.clone() { - { - let __tco_0 = method_receiver(expr); - expr = __tco_0; - continue; - } - } else { - break None; - } - } - _ => { - break None; - } - } - } -} - -pub fn classify_binding_provenance(val: Rc, scope: Rc) -> Rc { - match (*val.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let vname = - expr_var_name_at(val.clone(), scope.type_env.clone().source_indices.clone()); - match v1_rt::map_get(&scope.locals.clone(), vname.clone()) { - Some(binding) => binding.provenance.clone(), - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(val.clone()); - let field = - field_access_field_at(val.clone(), scope.type_env.clone().source_indices.clone()); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = expr_var_name_at( - base.clone(), - scope.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&scope.locals.clone(), bname.clone()) { - Some(binding) => { - let fields = inductive_fields_for( - scope.type_env.clone(), - authored_name_at( - scope.type_env.clone().source_indices.clone(), - binding.resolved.clone(), - ), - ); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if (f.field_name.clone() == field.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => { - compose_sub_value(binding.provenance.clone(), ind_field.clone()) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } -} - -pub fn classify_let_value(val: Rc, ctx: Rc) -> Option> { - match (*val.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let vname = expr_var_name_at(val.clone(), ctx.type_env.clone().source_indices.clone()); - match v1_rt::map_get(&ctx.scope_locals.clone(), vname.clone()) { - Some(binding) => match (*binding.provenance.clone()).clone() { - SubValueRelation::SubValueUnknown => None, - _ => Some(binding.provenance.clone()), - }, - None => None, - } - } - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(val.clone()); - let field = - field_access_field_at(val.clone(), ctx.type_env.clone().source_indices.clone()); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = - expr_var_name_at(base.clone(), ctx.type_env.clone().source_indices.clone()); - let from_per_field = - match v1_rt::map_get(&ctx.per_field_vars.clone(), bname.clone()) { - Some(field_map) => v1_rt::map_get(&field_map, field.clone()), - None => None, - }; - match from_per_field.clone() { - Some(rel) => Some(rel.clone()), - None => { - let type_name = - match v1_rt::map_get(&ctx.scope_locals.clone(), bname.clone()) { - Some(binding) => authored_name_at( - ctx.type_env.clone().source_indices.clone(), - binding.resolved.clone(), - ), - None => match v1_rt::map_get( - &ctx.param_names.clone(), - bname.clone(), - ) { - Some(t) => t.clone(), - None => "".to_string(), - }, - }; - if (type_name.clone() != "".to_string()) { - { - let fields = inductive_fields_for( - ctx.type_env.clone(), - type_name.clone(), - ); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if (f.field_name.clone() == field.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => { - Some(Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), - })) - } - None => None, - } - } - } else { - None - } - } - } - } - _ => None, - } - } - ExprData::ExprCall { .. } => { - let callee = - expr_call_func_at(val.clone(), ctx.type_env.clone().source_indices.clone()); - let from_provenance = match func_sig_if_resolved(lookup_func_sig( - ctx.func_env.clone(), - ctx.type_env.clone(), - callee.clone(), - )) { - Some(sig) => match sig.output_provenance.clone().first().cloned() { - Some(param_map) => { - classify_call_via_provenance(val.clone(), param_map.clone(), ctx.clone()) - } - None => None, - }, - None => None, - }; - match from_provenance.clone() { - Some(_) => from_provenance.clone(), - None => { - if (is_child_accessor_in_model(callee.clone()) - || is_tree_size_reducing(callee.clone())) - { - { - let call_args = val.children.clone(); - match call_args.clone().first().cloned() { - Some(first_arg) => { - let inner = arg_value(first_arg.clone()); - match (*inner.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let iname = expr_var_name_at( - inner.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let inner_type = match v1_rt::map_get( - &ctx.param_names.clone(), - iname.clone(), - ) { - Some(t) => t.clone(), - None => match v1_rt::map_get( - &ctx.sub_value_vars.clone(), - iname.clone(), - ) { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { - field: f, - .. - } => f.element_type.clone(), - SubValueRelation::IteratedSubValue { - field: f, - .. - } => f.element_type.clone(), - _ => "".to_string(), - }, - None => "".to_string(), - }, - }; - if (inner_type.clone() != "".to_string()) { - { - let fields = inductive_fields_for( - ctx.type_env.clone(), - inner_type.clone(), - ); - let cf = - Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() - { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, -} { __result.push(f); } - } - __result - }) - .first() - .cloned(); - match cf.clone() { - Some(ind_field) => Some(Rc::new( - SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new( - ShrinkFactor::UnitShrink, - ), - }, - )), - None => None, - } - } - } else { - None - } - } - _ => None, - } - } - None => None, - } - } - } else { - None - } - } - } - } - _ => { - let type_based = match val.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => { - if is_container_type(authored_name_at( - ctx.type_env.clone().source_indices.clone(), - rt.clone(), - )) { - { - let elem = match rt.children.clone().first().cloned() { - Some(c) => authored_name_at( - ctx.type_env.clone().source_indices.clone(), - c.clone(), - ), - None => "".to_string(), - }; - if ((elem.clone() != "".to_string()) - && is_recursive_type_by_name(ctx.type_env.clone(), elem.clone())) - { - { - let fields = - inductive_fields_for(ctx.type_env.clone(), elem.clone()); - let cf = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, - } { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match cf.clone() { - Some(ind_field) => { - Some(Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), - })) - } - None => None, - } - } - } else { - None - } - } - } else { - None - } - } - _ => None, - }; - match type_based.clone() { - Some(_) => type_based.clone(), - None => match (*val.expr_data.clone()).clone() { - ExprData::ExprBinOp { op: op, .. } => { - let left = binop_left(val.clone()); - let right = binop_right(val.clone()); - match op.clone() { - BinOp::Sub => match (*left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let lname = expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if ((v1_rt::map_get(&ctx.param_names.clone(), lname.clone()) - != None) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - lname.clone(), - ) != None)) - { - match expr_literal_int_optional(right.clone()) { - Some(k) => { - match positive_descent_amount_from_positive_int( - k.clone(), - ) { - Some(steps) => Some(Rc::new( - SubValueRelation::ArithmeticDescent { - param: lname.clone(), - factor: Rc::new( - ShrinkFactor::ConstantShrink { - steps: steps.clone(), - }, - ), - }, - )), - None => None, - } - } - None => None, - } - } else { - None - } - } - _ => None, - }, - BinOp::Div => { - let left_name = match (*left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let lname = expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if ((v1_rt::map_get( - &ctx.param_names.clone(), - lname.clone(), - ) != None) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - lname.clone(), - ) != None)) - { - lname.clone() - } else { - "".to_string() - } - } - ExprData::ExprBinOp { op: BinOp::Sub, .. } => { - let inner_left = binop_left(left.clone()); - match (*inner_left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let lname = expr_var_name_at( - inner_left.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if ((v1_rt::map_get( - &ctx.param_names.clone(), - lname.clone(), - ) != None) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - lname.clone(), - ) != None)) - { - lname.clone() - } else { - "".to_string() - } - } - _ => "".to_string(), - } - } - _ => "".to_string(), - }; - if (left_name.clone() != "".to_string()) { - match expr_literal_int_optional(right.clone()) { - Some(k) => { - match proportional_divisor_from_int_at_least_two( - k.clone(), - ) { - Some(div_w) => Some(Rc::new( - SubValueRelation::ArithmeticDescent { - param: left_name.clone(), - factor: Rc::new( - ShrinkFactor::ProportionalShrink { - divisor: div_w.clone(), - }, - ), - }, - )), - None => None, - } - } - None => None, - } - } else { - None - } - } - BinOp::Add => None, - _ => None, - } - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let mname = expr_method_name_at( - val.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let is_collection_preserving = (((((mname.clone() - == "skip".to_string()) - || (mname.clone() == "filter".to_string())) - || (mname.clone() == "take".to_string())) - || (mname.clone() == "enumerate".to_string())) - || (mname.clone() == "reverse".to_string())); - if is_collection_preserving.clone() { - { - let receiver = method_receiver(val.clone()); - let coll_field = - resolve_collection_field(receiver.clone(), ctx.clone()); - match coll_field.clone() { - Some(ind_field) => { - Some(Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), - })) - } - None => { - if (mname.clone() == "skip".to_string()) { - { - let skip_args = method_arg_nodes(val.clone()); - let skip_amount = - match skip_args.clone().first().cloned() { - Some(a) => match expr_literal_int_optional( - arg_value(a.clone()), - ) { - Some(k) => { - if (k.clone() > 0) { - k.clone() - } else { - 0 - } - } - None => 0, - }, - None => 0, - }; - if (skip_amount.clone() > 0) { - match (*receiver.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, - .. - } => { - let rname = expr_var_name_at( - receiver.clone(), - ctx.type_env - .clone() - .source_indices - .clone(), - ); - if ((v1_rt::map_get( - &ctx.param_names.clone(), - rname.clone(), - ) != None) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - rname.clone(), - ) != None)) - { - match positive_descent_amount_from_positive_int(skip_amount.clone()) { - Some(steps) => { - let synth_field = Rc::new(InductiveField { - type_name: rname.clone(), - variant_name: "".to_string(), - field_name: mname.clone(), - shape: RecursionShape::ListRecursion, - element_type: rname.clone(), -}); -Some(Rc::new(SubValueRelation::StrictSubValue { - field: synth_field.clone(), - factor: Rc::new(ShrinkFactor::ConstantShrink { - steps: steps.clone(), -}), -})) -}, - None => None, -} - } else { - None - } - } - _ => None, - } - } else { - None - } - } - } else { - None - } - } - } - } - } else { - None - } - } - _ => None, - }, - } - } - } -} - -pub fn classify_call_via_provenance( - call: Rc, - param_map: Rc>>, - ctx: Rc, -) -> Option> { - { - let call_args = call.children.clone(); - let arg_by_name = call_args.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, arg_node: Rc| match arg_name_at( - arg_node.clone(), - ctx.type_env.clone().source_indices.clone(), - ) { - Some(aname) => { - v1_rt::rc_map_insert(acc.clone(), aname.clone(), arg_value(arg_node.clone())) - } - None => acc.clone(), - }, - ); - Rc::new(v1_rt::map_keys(¶m_map)).iter().cloned().fold( - None, - |result: _, callee_pname: String| match v1_rt::map_get(¶m_map, callee_pname.clone()) - { - Some(callee_rel) => match v1_rt::map_get(&arg_by_name, callee_pname.clone()) { - Some(arg_expr) => { - let arg_rel = classify_call_arg_provenance(arg_expr.clone(), ctx.clone()); - match arg_rel.clone() { - Some(arel) => { - let composed = - compose_output_relations(arel.clone(), callee_rel.clone()); - match result.clone() { - Some(prev) => { - Some(meet_sub_value(prev.clone(), composed.clone())) - } - None => Some(composed.clone()), - } - } - None => result.clone(), - } - } - None => result.clone(), - }, - None => result.clone(), - }, - ) - } -} - -pub fn classify_call_arg_provenance( - arg_expr: Rc, - ctx: Rc, -) -> Option> { - match (*arg_expr.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let name = expr_var_name_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if (v1_rt::map_get(&ctx.param_names.clone(), name.clone()) != None) { - Some(Rc::new(SubValueRelation::PreservedValue)) - } else { - v1_rt::map_get(&ctx.sub_value_vars.clone(), name.clone()) - } - } - _ => classify_let_value(arg_expr.clone(), ctx.clone()), - } -} - -pub fn merge_argument_relations(rels: Rc>>) -> Rc { - match rels.clone().first().cloned() { - None => Rc::new(SubValueRelation::SubValueUnknown), - Some(first_rel) => Rc::new( - rels.clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - first_rel.clone(), - |acc: Rc, rel: Rc| meet_sub_value(acc, rel.clone()), - ), - } -} - -pub fn classify_argument( - arg_expr: Rc, - param_name: String, - ctx: Rc, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*arg_expr.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let vname = expr_var_name_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if (vname.clone() == param_name.clone()) { - Rc::new(SubValueRelation::PreservedValue) - } else { - match v1_rt::map_get(&ctx.sub_value_vars.clone(), vname.clone()) { - Some(rel) => rel.clone(), - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - } - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(arg_expr.clone()); - let field = field_access_field_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = expr_var_name_at( - base.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let type_name = - match v1_rt::map_get(&ctx.param_names.clone(), bname.clone()) { - Some(t) => t.clone(), - None => { - match v1_rt::map_get(&ctx.sub_value_vars.clone(), bname.clone()) - { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { - field: f, .. - } => f.element_type.clone(), - SubValueRelation::IteratedSubValue { - field: f, .. - } => f.element_type.clone(), - _ => "".to_string(), - }, - None => "".to_string(), - } - } - }; - let fields = inductive_fields_for(ctx.type_env.clone(), type_name.clone()); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if (f.field_name.clone() == field.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), - }), - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } - } - ExprData::ExprCall { .. } => { - let call_args = arg_expr.children.clone(); - match call_args.clone().first().cloned() { - Some(first_arg) => { - let inner = arg_value(first_arg.clone()); - let inner_rel = - classify_argument(inner.clone(), param_name.clone(), ctx.clone()); - match (*inner_rel.clone()).clone() { - SubValueRelation::StrictSubValue { .. } => inner_rel.clone(), - SubValueRelation::IteratedSubValue { field: _, .. } => { - inner_rel.clone() - } - SubValueRelation::ArithmeticDescent { .. } => inner_rel.clone(), - SubValueRelation::PreservedValue => { - let callee = expr_call_func_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let from_provenance = match func_sig_if_resolved(lookup_func_sig( - ctx.func_env.clone(), - ctx.type_env.clone(), - callee.clone(), - )) { - Some(sig) => { - match sig.output_provenance.clone().first().cloned() { - Some(param_map) => classify_call_via_provenance( - arg_expr.clone(), - param_map.clone(), - ctx.clone(), - ), - None => None, - } - } - None => None, - }; - match from_provenance.clone() { - Some(prov_rel) => prov_rel.clone(), - None => { - if (is_child_accessor_in_model(callee.clone()) - || is_tree_size_reducing(callee.clone())) - { - { - let type_name = match v1_rt::map_get( - &ctx.param_names.clone(), - param_name.clone(), - ) { - Some(t) => t.clone(), - None => "".to_string(), - }; - let fields = inductive_fields_for( - ctx.type_env.clone(), - type_name.clone(), - ); - let cf = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, - } { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match cf.clone() { - Some(ind_field) => { - Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new( - ShrinkFactor::UnitShrink, - ), - }) - } - None => { - Rc::new(SubValueRelation::PreservedValue) - } - } - } - } else { - if is_property_contraction(callee.clone()) { - Rc::new(SubValueRelation::ArithmeticDescent { - param: param_name.clone(), - factor: Rc::new(ShrinkFactor::ConstantShrink { - steps: Rc::new( - PositiveDescentAmount::OneStep, - ), - }), - }) - } else { - Rc::new(SubValueRelation::PreservedValue) - } - } - } - } - } - SubValueRelation::NonIncreasingValue => { - Rc::new(SubValueRelation::NonIncreasingValue) - } - SubValueRelation::StrictAxisErased => { - Rc::new(SubValueRelation::StrictAxisErased) - } - SubValueRelation::MixedTop => Rc::new(SubValueRelation::MixedTop), - SubValueRelation::SubValueUnknown => { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => classify_collection_shrink(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprBinOp { op: op, .. } => { - let left = binop_left(arg_expr.clone()); - let right = binop_right(arg_expr.clone()); - match op.clone() { - BinOp::Sub => { - let left_is_param = match (*left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - ((expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ) == param_name.clone()) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ), - ) != None)) - } - _ => false, - }; - if left_is_param.clone() { - match expr_literal_int_optional(right.clone()) { - Some(k) => { - match positive_descent_amount_from_positive_int(k.clone()) { - Some(steps) => { - Rc::new(SubValueRelation::ArithmeticDescent { - param: param_name.clone(), - factor: Rc::new(ShrinkFactor::ConstantShrink { - steps: steps.clone(), - }), - }) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } else { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - BinOp::Div => { - let left_is_param = match (*left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - ((expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ) == param_name.clone()) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - expr_var_name_at( - left.clone(), - ctx.type_env.clone().source_indices.clone(), - ), - ) != None)) - } - ExprData::ExprBinOp { op: BinOp::Sub, .. } => { - let inner_left = binop_left(left.clone()); - match (*inner_left.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - ((expr_var_name_at( - inner_left.clone(), - ctx.type_env.clone().source_indices.clone(), - ) == param_name.clone()) - || (v1_rt::map_get( - &ctx.sub_value_vars.clone(), - expr_var_name_at( - inner_left.clone(), - ctx.type_env.clone().source_indices.clone(), - ), - ) != None)) - } - _ => false, - } - } - _ => false, - }; - if left_is_param.clone() { - match expr_literal_int_optional(right.clone()) { - Some(k) => { - match proportional_divisor_from_int_at_least_two(k.clone()) { - Some(div_w) => { - Rc::new(SubValueRelation::ArithmeticDescent { - param: param_name.clone(), - factor: Rc::new(ShrinkFactor::ProportionalShrink { - divisor: div_w.clone(), - }), - }) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } else { - Rc::new(SubValueRelation::SubValueUnknown) - } - } - BinOp::Add => Rc::new(SubValueRelation::SubValueUnknown), - _ => Rc::new(SubValueRelation::SubValueUnknown), - } - } - ExprData::ExprMatch => { - let arm_rels = Rc::new({ - let mut __result = Vec::new(); - for arm in match_arm_nodes(arg_expr.clone()).iter().cloned() { - __result.push(classify_argument( - arm_body(arm.clone()), - param_name.clone(), - ctx.clone(), - )); - } - __result - }); - merge_argument_relations(arm_rels.clone()) - } - ExprData::ExprIf => { - let then_rel = classify_argument( - if_then_branch(arg_expr.clone()), - param_name.clone(), - ctx.clone(), - ); - let else_rel = match if_else_branch(arg_expr.clone()) { - Some(e) => classify_argument(e.clone(), param_name.clone(), ctx.clone()), - None => Rc::new(SubValueRelation::SubValueUnknown), - }; - merge_argument_relations(Rc::new(vec![then_rel.clone(), else_rel.clone()])) - } - ExprData::ExprBlock => match arg_expr.children.clone().last().cloned() { - Some(last_expr) => { - classify_argument(last_expr.clone(), param_name.clone(), ctx.clone()) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - }, - ExprData::ExprLet => match let_body(arg_expr.clone()) { - Some(body) => classify_argument(body.clone(), param_name.clone(), ctx.clone()), - None => Rc::new(SubValueRelation::SubValueUnknown), - }, - ExprData::ExprCast => { - classify_argument(cast_expr(arg_expr.clone()), param_name.clone(), ctx.clone()) - } - ExprData::ExprReturn => match arg_expr.children.clone().first().cloned() { - Some(inner) => classify_argument(inner.clone(), param_name.clone(), ctx.clone()), - None => Rc::new(SubValueRelation::SubValueUnknown), - }, - _ => Rc::new(SubValueRelation::SubValueUnknown), - } - }) -} - -pub fn read_arg_provenance( - arg_expr: Rc, - param_name: String, - ctx: Rc, -) -> Rc { - match (*arg_expr.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let vname = expr_var_name_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.scope_locals.clone(), vname.clone()) { - Some(binding) => match (*binding.provenance.clone()).clone() { - SubValueRelation::SubValueUnknown => { - classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) - } - _ => binding.provenance.clone(), - }, - None => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - } - } - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(arg_expr.clone()); - let field = field_access_field_at( - arg_expr.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = - expr_var_name_at(base.clone(), ctx.type_env.clone().source_indices.clone()); - match v1_rt::map_get(&ctx.scope_locals.clone(), bname.clone()) { - Some(binding) => match (*binding.provenance.clone()).clone() { - SubValueRelation::SubValueUnknown => { - classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) - } - _ => { - let fields = inductive_fields_for( - ctx.type_env.clone(), - authored_name_at( - ctx.type_env.clone().source_indices.clone(), - binding.resolved.clone(), - ), - ); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if (f.field_name.clone() == field.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => compose_sub_value( - binding.provenance.clone(), - ind_field.clone(), - ), - None => Rc::new(SubValueRelation::SubValueUnknown), - } - } - }, - None => { - classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) - } - } - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } - } - ExprData::ExprCall { .. } => { - classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprBinOp { op: _, .. } => { - classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) - } - ExprData::ExprMatch => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprIf => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprBlock => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprLet => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprCast => classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()), - ExprData::ExprReturn => { - classify_argument(arg_expr.clone(), param_name.clone(), ctx.clone()) - } - _ => Rc::new(SubValueRelation::SubValueUnknown), - } -} - -pub fn build_call_evidence( - call_node: Rc, - ctx: Rc, -) -> Rc>> { - { - let arg_map = Rc::new( - call_node - .children - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, pair: (i64, Rc)| { - let idx = pair.0.clone(); - let arg_node = pair.1.clone(); - let aname = arg_name_at( - arg_node.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match aname.clone() { - Some(pname) => v1_rt::rc_map_insert( - acc.clone(), - pname.clone(), - arg_value(arg_node.clone()), - ), - None => acc.clone(), - } - }, - ); - let positional_args = Rc::new({ - let mut __result = Vec::new(); - for arg_node in Rc::new({ - let mut __result = Vec::new(); - for arg_node in call_node.children.clone().iter().cloned() { - if (arg_name_at( - arg_node.clone(), - ctx.type_env.clone().source_indices.clone(), - ) == None) - { - __result.push(arg_node); - } - } - __result - }) - .iter() - .cloned() - { - __result.push(arg_value(arg_node.clone())); - } - __result - }); - let positional_idx = 0; - Rc::new({ - let mut __result = Vec::new(); - for pair in Rc::new( - ctx.param_order - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.push({ - let def_idx = pair.0.clone(); - let pname = pair.1.clone(); - match v1_rt::map_get(&arg_map, pname.clone()) { - Some(arg_val) => { - read_arg_provenance(arg_val.clone(), pname.clone(), ctx.clone()) - } - None => match positional_args - .clone() - .iter() - .cloned() - .skip(def_idx.clone() as usize) - .next() - { - Some(arg_val) => { - read_arg_provenance(arg_val.clone(), pname.clone(), ctx.clone()) - } - None => Rc::new(SubValueRelation::SubValueUnknown), - }, - } - }); - } - __result - }) - } -} - -pub fn descent_source_type(found: String, arg_node: Rc, ctx: Rc) -> String { - if (found.clone() != "".to_string()) { - found.clone() - } else { - match (*arg_value(arg_node.clone()).expr_data.clone()).clone() { - ExprData::ExprLambda => found.clone(), - _ => { - let arg_val = arg_value(arg_node.clone()); - match (*arg_val.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let vname = expr_var_name_at( - arg_val.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.param_names.clone(), vname.clone()) { - Some(t) => t.clone(), - None => "".to_string(), - } - } - _ => "".to_string(), - } - } - } - } -} - -pub fn annotate_descent(body: Rc, ctx: Rc) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*body.expr_data.clone()).clone() { - ExprData::ExprCall { - call_semantics: cs, .. - } => { - let evidence = build_call_evidence(body.clone(), ctx.clone()); - let source_type = body.children.clone().iter().cloned().fold( - "".to_string(), - |found: String, arg_node: Rc| { - descent_source_type(found, arg_node.clone(), ctx.clone()) - }, - ); - let annotated_children = Rc::new({ - let mut __result = Vec::new(); - for child in body.children.clone().iter().cloned() { - __result.push({ - let arg_val = arg_value(child.clone()); - match (*arg_val.expr_data.clone()).clone() { - ExprData::ExprLambda => { - if (source_type.clone() != "".to_string()) { - { - let lparams = lambda_param_names_at( - arg_val.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let p1 = match lparams.clone().first().cloned() { - Some(n) => n.clone(), - None => "".to_string(), - }; - let p2 = match lparams - .clone() - .iter() - .cloned() - .skip(1 as usize) - .next() - { - Some(n) => n.clone(), - None => "".to_string(), - }; - let lambda_ctx = Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: if (p2.clone() != "".to_string()) { - v1_rt::rc_map_insert( - v1_rt::rc_map_insert( - ctx.param_names.clone(), - p1.clone(), - source_type.clone(), - ), - p2.clone(), - source_type.clone(), - ) - } else { - if (p1.clone() != "".to_string()) { - v1_rt::rc_map_insert( - ctx.param_names.clone(), - p1.clone(), - source_type.clone(), - ) - } else { - ctx.param_names.clone() - } - }, - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: if (p1.clone() != "".to_string()) { - { - let source_fields = inductive_fields_for( - ctx.type_env.clone(), - source_type.clone(), - ); - let cf = Rc::new({ - let mut __result = Vec::new(); - for f in source_fields - .clone() - .iter() - .cloned() - { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, -} { __result.push(f); } - } - __result - }) - .first() - .cloned(); - let rel = match cf.clone() { - Some(f) => Rc::new(SubValueRelation::IteratedSubValue { - field: f.clone(), -}), - None => Rc::new(SubValueRelation::PreservedValue), -}; - if (p2.clone() != "".to_string()) { - v1_rt::rc_map_insert( - v1_rt::rc_map_insert( - ctx.sub_value_vars.clone(), - p1.clone(), - rel.clone(), - ), - p2.clone(), - rel.clone(), - ) - } else { - v1_rt::rc_map_insert( - ctx.sub_value_vars.clone(), - p1.clone(), - rel.clone(), - ) - } - } - } else { - ctx.sub_value_vars.clone() - }, - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), - }); - make_arg_node( - arg_name_at( - child.clone(), - ctx.type_env.clone().source_indices.clone(), - ), - annotate_descent( - arg_val.clone(), - lambda_ctx.clone(), - ), - child.span.clone(), - child.span.clone(), - ) - } - } else { - make_arg_node( - arg_name_at( - child.clone(), - ctx.type_env.clone().source_indices.clone(), - ), - annotate_descent(arg_val.clone(), ctx.clone()), - child.span.clone(), - child.span.clone(), - ) - } - } - _ => make_arg_node( - arg_name_at( - child.clone(), - ctx.type_env.clone().source_indices.clone(), - ), - annotate_descent(arg_val.clone(), ctx.clone()), - child.span.clone(), - child.span.clone(), - ), - } - }); - } - __result - }); - Rc::new(Node { - name: body.name.clone(), - span: body.span.clone(), - ident_span: body.ident_span.clone(), - children: annotated_children.clone(), - connective: body.connective.clone(), - params: body.params.clone(), - inferred: body.inferred.clone(), - return_cardinality: body.return_cardinality.clone(), - uses: body.uses.clone(), - body: body.body.clone(), - transport: body.transport.clone(), - properties: body.properties.clone(), - type_annotation: body.type_annotation.clone(), - is_self_recursive: body.is_self_recursive.clone(), - has_non_tail_self_call: body.has_non_tail_self_call.clone(), - match_pattern: body.match_pattern.clone(), - expr_data: Rc::new(ExprData::ExprCall { - call_semantics: cs.clone(), - descent_evidence: Some(evidence.clone()), - }), - ident: None, - }) - } - ExprData::ExprMatch => { - let scrut = match_scrutinee(body.clone()); - let scrut_type = match (*scrut.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let sname = expr_var_name_at( - scrut.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.param_names.clone(), sname.clone()) { - Some(t) => t.clone(), - None => { - match v1_rt::map_get(&ctx.sub_value_vars.clone(), sname.clone()) { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { field: f, .. } => { - f.element_type.clone() - } - SubValueRelation::IteratedSubValue { field: f, .. } => { - f.element_type.clone() - } - _ => "".to_string(), - }, - None => "".to_string(), - } - } - } - } - _ => "".to_string(), - }; - let scrut_inducing_field = match (*scrut.expr_data.clone()).clone() { - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(scrut.clone()); - let fname = field_access_field_at( - scrut.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = expr_var_name_at( - base.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let base_type = - match v1_rt::map_get(&ctx.param_names.clone(), bname.clone()) { - Some(t) => t.clone(), - None => "".to_string(), - }; - if (base_type.clone() != "".to_string()) { - { - let ind_fields = inductive_fields_for( - ctx.type_env.clone(), - base_type.clone(), - ); - Rc::new({ - let mut __result = Vec::new(); - for f in ind_fields.clone().iter().cloned() { - if (f.field_name.clone() == fname.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned() - } - } else { - None - } - } - _ => None, - } - } - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let mname = expr_method_name_at( - scrut.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if ((mname.clone() == "first".to_string()) - || (mname.clone() == "last".to_string())) - { - { - let receiver = method_receiver(scrut.clone()); - resolve_collection_field(receiver.clone(), ctx.clone()) - } - } else { - None - } - } - _ => None, - }; - let scrut_has_inductive = (((scrut_type.clone() != "".to_string()) - && ((inductive_fields_for(ctx.type_env.clone(), scrut_type.clone()).len() - as i64) - > 0)) - || (scrut_inducing_field.clone() != None)); - let scrut_variant_sig = match (*scrut.expr_data.clone()).clone() { - ExprData::ExprCall { .. } => { - let callee = expr_call_func_at( - scrut.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match func_sig_if_resolved(lookup_func_sig( - ctx.func_env.clone(), - ctx.type_env.clone(), - callee.clone(), - )) { - Some(sig) => { - if ((Rc::new(v1_rt::map_keys(&sig.variant_provenance.clone())).len() - as i64) - > 0) - { - Some(sig.clone()) - } else { - None - } - } - None => None, - } - } - _ => None, - }; - let annotated_scrut = annotate_descent(scrut.clone(), ctx.clone()); - let annotated_arms = Rc::new({ - let mut __result = Vec::new(); - for arm_node in match_arm_nodes(body.clone()).iter().cloned() { - __result.push({ - let variant_arm_ctx = match scrut_variant_sig.clone() { - Some(sig) => arm_ctx_from_variant_provenance(arm_node.clone(), sig.clone(), scrut.clone(), ctx.clone()), - None => None, -}; -let arm_ctx = match variant_arm_ctx.clone() { - Some(c) => c.clone(), - None => if scrut_has_inductive.clone() { - match (*arm_pattern(arm_node.clone())).clone() { - MatchPattern::VariantPattern { name: vname, field_bindings: bindings, .. } => match scrut_inducing_field.clone() { - Some(ind_field) => if (vname.clone() == "Present".to_string()) { - bindings.clone().iter().cloned().fold(ctx.clone(), |c: Rc, fb: Rc| match (*field_binding_pattern(fb.clone())).clone() { - MatchPattern::Bind { declaration: declaration, .. } => Rc::new(DescentContext { - fn_name: c.fn_name.clone(), - param_names: v1_rt::rc_map_insert(c.param_names.clone(), declaration.name.clone(), ind_field.element_type.clone()), - param_order: c.param_order.clone(), - type_env: c.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert(c.sub_value_vars.clone(), declaration.name.clone(), Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), -})), - size_aliases: c.size_aliases.clone(), - scope_locals: c.scope_locals.clone(), - func_env: c.func_env.clone(), - per_field_vars: c.per_field_vars.clone(), -}), - MatchPattern::VariantPattern { name: inner_vname, field_bindings: inner_bindings, .. } => { - let inner_ind_fields = inductive_fields_for(c.type_env.clone(), ind_field.element_type.clone()); -inner_bindings.clone().iter().cloned().fold(c.clone(), |ic: Rc, inner_fb: Rc| { - let inner_field_name = field_binding_name_at(inner_fb.clone(), ctx.type_env.clone().source_indices.clone()); -let inner_bind_name = match (*field_binding_pattern(inner_fb.clone())).clone() { - MatchPattern::Bind { declaration: declaration, .. } => declaration.name.clone(), - _ => "".to_string(), -}; -let inner_matching = Rc::new({ let mut __result = Vec::new(); for f in inner_ind_fields.clone().iter().cloned() { if ((f.variant_name.clone() == inner_vname.clone()) && (f.field_name.clone() == inner_field_name.clone())) { __result.push(f); } } __result }).first().cloned(); -match inner_matching.clone() { - Some(inner_ind_field) => if (inner_bind_name.clone() != "".to_string()) { - Rc::new(DescentContext { - fn_name: ic.fn_name.clone(), - param_names: v1_rt::rc_map_insert(ic.param_names.clone(), inner_bind_name.clone(), inner_ind_field.element_type.clone()), - param_order: ic.param_order.clone(), - type_env: ic.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert(ic.sub_value_vars.clone(), inner_bind_name.clone(), Rc::new(SubValueRelation::StrictSubValue { - field: inner_ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), -})), - size_aliases: ic.size_aliases.clone(), - scope_locals: ic.scope_locals.clone(), - func_env: ic.func_env.clone(), - per_field_vars: ic.per_field_vars.clone(), -}) - } else { - ic.clone() - }, - None => ic.clone(), -} -}) -}, - _ => c.clone(), -}) - } else { - ctx.clone() - }, - None => { - let ind_fields = inductive_fields_for(ctx.type_env.clone(), scrut_type.clone()); -bindings.clone().iter().cloned().fold(ctx.clone(), |c: Rc, fb: Rc| { - let field_name = field_binding_name_at(fb.clone(), ctx.type_env.clone().source_indices.clone()); -let bind_name = match (*field_binding_pattern(fb.clone())).clone() { - MatchPattern::Bind { declaration: declaration, .. } => declaration.name.clone(), - _ => "".to_string(), -}; -let matching = Rc::new({ let mut __result = Vec::new(); for f in ind_fields.clone().iter().cloned() { if ((f.variant_name.clone() == vname.clone()) && (f.field_name.clone() == field_name.clone())) { __result.push(f); } } __result }).first().cloned(); -match matching.clone() { - Some(ind_field) => if (bind_name.clone() != "".to_string()) { - Rc::new(DescentContext { - fn_name: c.fn_name.clone(), - param_names: c.param_names.clone(), - param_order: c.param_order.clone(), - type_env: c.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert(c.sub_value_vars.clone(), bind_name.clone(), Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), -})), - size_aliases: c.size_aliases.clone(), - scope_locals: c.scope_locals.clone(), - func_env: c.func_env.clone(), - per_field_vars: c.per_field_vars.clone(), -}) - } else { - c.clone() - }, - None => c.clone(), -} -}) -}, -}, - MatchPattern::Bind { declaration: declaration, .. } => if (scrut_type.clone() != "".to_string()) { - Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: v1_rt::rc_map_insert(ctx.param_names.clone(), declaration.name.clone(), scrut_type.clone()), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert(ctx.sub_value_vars.clone(), declaration.name.clone(), Rc::new(SubValueRelation::PreservedValue)), - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), -}) - } else { - match scrut_inducing_field.clone() { - Some(ind_field) => Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: v1_rt::rc_map_insert(ctx.param_names.clone(), declaration.name.clone(), ind_field.element_type.clone()), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert(ctx.sub_value_vars.clone(), declaration.name.clone(), Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new(ShrinkFactor::UnitShrink), -})), - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), -}), - None => ctx.clone(), -} - }, - _ => ctx.clone(), -} - } else { - ctx.clone() - }, -}; -let annotated_body = annotate_descent(arm_body(arm_node.clone()), arm_ctx.clone()); -make_arm_node(arm_pattern(arm_node.clone()), arm_guard(arm_node.clone()), annotated_body.clone(), arm_node.span.clone()) -}); - } - __result - }); - Rc::new(Node { - name: body.name.clone(), - span: body.span.clone(), - ident_span: body.ident_span.clone(), - children: v1_rt::concat( - Rc::new(vec![annotated_scrut.clone()]), - annotated_arms.clone(), - ), - connective: body.connective.clone(), - params: body.params.clone(), - inferred: body.inferred.clone(), - return_cardinality: body.return_cardinality.clone(), - uses: body.uses.clone(), - body: body.body.clone(), - transport: body.transport.clone(), - properties: body.properties.clone(), - type_annotation: body.type_annotation.clone(), - is_self_recursive: body.is_self_recursive.clone(), - has_non_tail_self_call: body.has_non_tail_self_call.clone(), - match_pattern: body.match_pattern.clone(), - expr_data: body.expr_data.clone(), - ident: None, - }) - } - ExprData::ExprLet => { - let val = let_value(body.clone()); - let binding_name = - let_binding_name_at(body.clone(), ctx.type_env.clone().source_indices.clone()); - let val_relation = classify_let_value(val.clone(), ctx.clone()); - let size_alias = classify_size_expr(val.clone(), ctx.clone()); - let inner_size_aliases = match size_alias.clone() { - Some(se) => v1_rt::rc_map_insert( - ctx.size_aliases.clone(), - binding_name.clone(), - se.clone(), - ), - None => ctx.size_aliases.clone(), - }; - let inner_per_field = - build_per_field_for_let(val.clone(), binding_name.clone(), ctx.clone()); - let inner_ctx = match val_relation.clone() { - Some(rel) => { - let sub_type = match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { field: f, .. } => { - f.element_type.clone() - } - SubValueRelation::IteratedSubValue { field: f, .. } => { - f.element_type.clone() - } - _ => "".to_string(), - }; - Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: if (sub_type.clone() != "".to_string()) { - v1_rt::rc_map_insert( - ctx.param_names.clone(), - binding_name.clone(), - sub_type.clone(), - ) - } else { - ctx.param_names.clone() - }, - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert( - ctx.sub_value_vars.clone(), - binding_name.clone(), - rel.clone(), - ), - size_aliases: inner_size_aliases.clone(), - scope_locals: v1_rt::rc_map_insert( - ctx.scope_locals.clone(), - binding_name.clone(), - Rc::new(TypeBinding { - name: binding_name.clone(), - resolved: resolved_type(val.clone()), - provenance: rel.clone(), - }), - ), - func_env: ctx.func_env.clone(), - per_field_vars: inner_per_field.clone(), - }) - } - None => Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: ctx.param_names.clone(), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: ctx.sub_value_vars.clone(), - size_aliases: inner_size_aliases.clone(), - scope_locals: v1_rt::rc_map_insert( - ctx.scope_locals.clone(), - binding_name.clone(), - Rc::new(TypeBinding { - name: binding_name.clone(), - resolved: resolved_type(val.clone()), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ), - func_env: ctx.func_env.clone(), - per_field_vars: inner_per_field.clone(), - }), - }; - let annotated_value = annotate_descent(val.clone(), ctx.clone()); - let annotated_children = match let_body(body.clone()) { - Some(body_child) => Rc::new(vec![ - annotated_value.clone(), - annotate_descent(body_child.clone(), inner_ctx.clone()), - ]), - None => Rc::new(vec![annotated_value.clone()]), - }; - Rc::new(Node { - name: body.name.clone(), - span: body.span.clone(), - ident_span: body.ident_span.clone(), - children: annotated_children.clone(), - connective: body.connective.clone(), - params: body.params.clone(), - inferred: body.inferred.clone(), - return_cardinality: body.return_cardinality.clone(), - uses: body.uses.clone(), - body: body.body.clone(), - transport: body.transport.clone(), - properties: body.properties.clone(), - type_annotation: body.type_annotation.clone(), - is_self_recursive: body.is_self_recursive.clone(), - has_non_tail_self_call: body.has_non_tail_self_call.clone(), - match_pattern: body.match_pattern.clone(), - expr_data: body.expr_data.clone(), - ident: None, - }) - } - ExprData::ExprBlock => { - let threaded = body.children.clone().iter().cloned().fold( - Rc::new(BlockAnnotateAcc { - ctx: ctx.clone(), - children: Rc::new(vec![]), - }), - |acc: Rc, child: Rc| { - let annotated = annotate_descent(child.clone(), acc.ctx.clone()); - let next_ctx = match (*child.expr_data.clone()).clone() { - ExprData::ExprLet => { - let val = let_value(child.clone()); - let bname = let_binding_name_at( - child.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let val_rel = classify_let_value(val.clone(), acc.ctx.clone()); - let sa = classify_size_expr(val.clone(), acc.ctx.clone()); - let new_sa = match sa.clone() { - Some(se) => v1_rt::rc_map_insert( - acc.ctx.clone().size_aliases.clone(), - bname.clone(), - se.clone(), - ), - None => acc.ctx.clone().size_aliases.clone(), - }; - match val_rel.clone() { - Some(rel) => { - let sub_type = match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { - field: f, .. - } => f.element_type.clone(), - SubValueRelation::IteratedSubValue { - field: f, .. - } => f.element_type.clone(), - _ => "".to_string(), - }; - Rc::new(DescentContext { - fn_name: acc.ctx.clone().fn_name.clone(), - param_names: if (sub_type.clone() != "".to_string()) { - v1_rt::rc_map_insert( - acc.ctx.clone().param_names.clone(), - bname.clone(), - sub_type.clone(), - ) - } else { - acc.ctx.clone().param_names.clone() - }, - param_order: acc.ctx.clone().param_order.clone(), - type_env: acc.ctx.clone().type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert( - acc.ctx.clone().sub_value_vars.clone(), - bname.clone(), - rel.clone(), - ), - size_aliases: new_sa.clone(), - scope_locals: v1_rt::rc_map_insert( - acc.ctx.clone().scope_locals.clone(), - bname.clone(), - Rc::new(TypeBinding { - name: bname.clone(), - resolved: resolved_type(val.clone()), - provenance: rel.clone(), - }), - ), - func_env: acc.ctx.clone().func_env.clone(), - per_field_vars: acc.ctx.clone().per_field_vars.clone(), - }) - } - None => Rc::new(DescentContext { - fn_name: acc.ctx.clone().fn_name.clone(), - param_names: acc.ctx.clone().param_names.clone(), - param_order: acc.ctx.clone().param_order.clone(), - type_env: acc.ctx.clone().type_env.clone(), - sub_value_vars: acc.ctx.clone().sub_value_vars.clone(), - size_aliases: new_sa.clone(), - scope_locals: v1_rt::rc_map_insert( - acc.ctx.clone().scope_locals.clone(), - bname.clone(), - Rc::new(TypeBinding { - name: bname.clone(), - resolved: resolved_type(val.clone()), - provenance: Rc::new( - SubValueRelation::SubValueUnknown, - ), - }), - ), - func_env: acc.ctx.clone().func_env.clone(), - per_field_vars: acc.ctx.clone().per_field_vars.clone(), - }), - } - } - _ => acc.ctx.clone(), - }; - Rc::new(BlockAnnotateAcc { - ctx: next_ctx.clone(), - children: v1_rt::concat( - acc.children.clone(), - Rc::new(vec![annotated.clone()]), - ), - }) - }, - ); - Rc::new(Node { - name: body.name.clone(), - span: body.span.clone(), - ident_span: body.ident_span.clone(), - children: threaded.children.clone(), - connective: body.connective.clone(), - params: body.params.clone(), - inferred: body.inferred.clone(), - return_cardinality: body.return_cardinality.clone(), - uses: body.uses.clone(), - body: body.body.clone(), - transport: body.transport.clone(), - properties: body.properties.clone(), - type_annotation: body.type_annotation.clone(), - is_self_recursive: body.is_self_recursive.clone(), - has_non_tail_self_call: body.has_non_tail_self_call.clone(), - match_pattern: body.match_pattern.clone(), - expr_data: body.expr_data.clone(), - ident: None, - }) - } - ExprData::ExprMethodCall { - method_semantics: ms, - .. - } => { - let mname = - expr_method_name_at(body.clone(), ctx.type_env.clone().source_indices.clone()); - let elem_position = method_callback_element_position(ms.clone()); - if (elem_position.clone() != None) { - { - let raw_receiver = method_receiver(body.clone()); - let receiver = match (*raw_receiver.expr_data.clone()).clone() { - ExprData::ExprMethodCall { - method_semantics: _, - .. - } => { - let inner_mname = expr_method_name_at( - raw_receiver.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - if (inner_mname.clone() == "enumerate".to_string()) { - method_receiver(raw_receiver.clone()) - } else { - raw_receiver.clone() - } - } - _ => raw_receiver.clone(), - }; - let receiver_field = match (*receiver.expr_data.clone()).clone() { - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(receiver.clone()); - let fname = field_access_field_at( - receiver.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match (*base.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let bname = expr_var_name_at( - base.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let base_type = match v1_rt::map_get( - &ctx.param_names.clone(), - bname.clone(), - ) { - Some(t) => t.clone(), - None => match v1_rt::map_get( - &ctx.sub_value_vars.clone(), - bname.clone(), - ) { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { - field: f, - .. - } => f.element_type.clone(), - SubValueRelation::IteratedSubValue { - field: f, - .. - } => f.element_type.clone(), - _ => "".to_string(), - }, - None => "".to_string(), - }, - }; - if (base_type.clone() != "".to_string()) { - Rc::new({ - let mut __result = Vec::new(); - for f in inductive_fields_for( - ctx.type_env.clone(), - base_type.clone(), - ) - .iter() - .cloned() - { - if (f.field_name.clone() == fname.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned() - } else { - None - } - } - _ => None, - } - } - ExprData::ExprVar { - binding_kind: _, .. - } => { - let rname = expr_var_name_at( - receiver.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - match v1_rt::map_get(&ctx.sub_value_vars.clone(), rname.clone()) { - Some(rel) => match (*rel.clone()).clone() { - SubValueRelation::StrictSubValue { field: f, .. } => { - match f.shape.clone() { - RecursionShape::ListRecursion => Some(f.clone()), - _ => None, - } - } - SubValueRelation::IteratedSubValue { field: f, .. } => { - match f.shape.clone() { - RecursionShape::ListRecursion => Some(f.clone()), - _ => None, - } - } - _ => None, - }, - None => None, - } - } - _ => None, - }; - let method_args = method_arg_nodes(body.clone()); - let lambda_arg = Rc::new({ - let mut __result = Vec::new(); - for a in method_args.clone().iter().cloned() { - if match (*arg_value(a.clone()).expr_data.clone()).clone() { - ExprData::ExprLambda => true, - _ => false, - } { - __result.push(a); - } - } - __result - }) - .first() - .cloned(); - let lambda_elem_info = match lambda_arg.clone() { - Some(la) => { - let lambda_node = arg_value(la.clone()); - let lparams = lambda_param_names_at( - lambda_node.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - lparams - .clone() - .iter() - .cloned() - .skip(elem_position.clone().unwrap() as usize) - .next() - } - None => None, - }; - let is_fold = (elem_position.clone().unwrap() > 0); - let inner_ctx = match lambda_elem_info.clone() { - Some(elem_name) => match receiver_field.clone() { - Some(ind_field) => Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: v1_rt::rc_map_insert( - ctx.param_names.clone(), - elem_name.clone(), - ind_field.element_type.clone(), - ), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: if is_fold.clone() { - v1_rt::rc_map_insert( - v1_rt::rc_empty_map::>(), - elem_name.clone(), - Rc::new(SubValueRelation::IteratedSubValue { - field: ind_field.clone(), - }), - ) - } else { - v1_rt::rc_map_insert( - ctx.sub_value_vars.clone(), - elem_name.clone(), - Rc::new(SubValueRelation::IteratedSubValue { - field: ind_field.clone(), - }), - ) - }, - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), - }), - None => Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: ctx.param_names.clone(), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: if is_fold.clone() { - v1_rt::rc_empty_map::>() - } else { - ctx.sub_value_vars.clone() - }, - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), - }), - }, - None => ctx.clone(), - }; - let annotated_receiver = - annotate_descent(method_receiver(body.clone()), ctx.clone()); - let annotated_args = Rc::new({ - let mut __result = Vec::new(); - for arg_node in method_arg_nodes(body.clone()).iter().cloned() { - __result.push({ - let arg_val = arg_value(arg_node.clone()); - let is_lambda = match (*arg_val.expr_data.clone()).clone() { - ExprData::ExprLambda => true, - _ => false, - }; - if is_lambda.clone() { - make_arg_node( - match arg_name_at( - arg_node.clone(), - ctx.type_env.clone().source_indices.clone(), - ) { - Some(n) => Some(n.clone()), - None => None, - }, - annotate_descent(arg_val.clone(), inner_ctx.clone()), - arg_node.span.clone(), - arg_node.span.clone(), - ) - } else { - make_arg_node( - match arg_name_at( - arg_node.clone(), - ctx.type_env.clone().source_indices.clone(), - ) { - Some(n) => Some(n.clone()), - None => None, - }, - annotate_descent(arg_val.clone(), ctx.clone()), - arg_node.span.clone(), - arg_node.span.clone(), - ) - } - }); - } - __result - }); - Rc::new(Node { - name: body.name.clone(), - span: body.span.clone(), - ident_span: body.ident_span.clone(), - children: v1_rt::concat( - Rc::new(vec![annotated_receiver.clone()]), - annotated_args.clone(), - ), - connective: body.connective.clone(), - params: body.params.clone(), - inferred: body.inferred.clone(), - return_cardinality: body.return_cardinality.clone(), - uses: body.uses.clone(), - body: body.body.clone(), - transport: body.transport.clone(), - properties: body.properties.clone(), - type_annotation: body.type_annotation.clone(), - is_self_recursive: body.is_self_recursive.clone(), - has_non_tail_self_call: body.has_non_tail_self_call.clone(), - match_pattern: body.match_pattern.clone(), - expr_data: body.expr_data.clone(), - ident: None, - }) - } - } else { - map_children(body.clone(), |child| { - annotate_descent(child.clone(), ctx.clone()) - }) - } - } - ExprData::ExprForEach => { - let coll = foreach_collection(body.clone()); - let fe_body = foreach_body(body.clone()); - let fe_var = - foreach_variable_at(body.clone(), ctx.type_env.clone().source_indices.clone()); - let coll_field = resolve_collection_field(coll.clone(), ctx.clone()); - let inner_ctx = match coll_field.clone() { - Some(ind_field) => Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: v1_rt::rc_map_insert( - ctx.param_names.clone(), - fe_var.clone(), - ind_field.element_type.clone(), - ), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert( - v1_rt::rc_empty_map::>(), - fe_var.clone(), - Rc::new(SubValueRelation::IteratedSubValue { - field: ind_field.clone(), - }), - ), - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), - }), - None => Rc::new(DescentContext { - fn_name: ctx.fn_name.clone(), - param_names: ctx.param_names.clone(), - param_order: ctx.param_order.clone(), - type_env: ctx.type_env.clone(), - sub_value_vars: v1_rt::rc_empty_map::>(), - size_aliases: ctx.size_aliases.clone(), - scope_locals: ctx.scope_locals.clone(), - func_env: ctx.func_env.clone(), - per_field_vars: ctx.per_field_vars.clone(), - }), - }; - let annotated_coll = annotate_descent(coll.clone(), ctx.clone()); - let annotated_body = annotate_descent(fe_body.clone(), inner_ctx.clone()); - Rc::new(Node { - name: body.name.clone(), - span: body.span.clone(), - ident_span: body.ident_span.clone(), - children: Rc::new(vec![annotated_coll.clone(), annotated_body.clone()]), - connective: body.connective.clone(), - params: body.params.clone(), - inferred: body.inferred.clone(), - return_cardinality: body.return_cardinality.clone(), - uses: body.uses.clone(), - body: body.body.clone(), - transport: body.transport.clone(), - properties: body.properties.clone(), - type_annotation: body.type_annotation.clone(), - is_self_recursive: body.is_self_recursive.clone(), - has_non_tail_self_call: body.has_non_tail_self_call.clone(), - match_pattern: body.match_pattern.clone(), - expr_data: body.expr_data.clone(), - ident: None, - }) - } - _ => map_children(body.clone(), |child| { - annotate_descent(child.clone(), ctx.clone()) - }), - } - }) -} - -pub fn resolved_type_name( - n: Rc, - source_indices: Rc>>, -) -> String { - match n.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => { - authored_name_at(source_indices.clone(), rt.clone()) - } - _ => match n.children.clone().first().cloned() { - Some(c) => authored_name_at(source_indices.clone(), c.clone()), - None => "".to_string(), - }, - } -} - -pub fn infer_output_provenance( - body: Rc, - params: Rc>>, - type_env: Rc, - scope_locals: Rc>>, - func_env: Rc, -) -> Rc>>>> { - { - let param_names = Rc::new({ - let mut __result = Vec::new(); - for p in params.clone().iter().cloned() { - __result.push(param_node_name_at( - p.clone(), - type_env.source_indices.clone(), - )); - } - __result - }); - let param_types = params.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, p: Rc| { - let pname = param_node_name_at(p.clone(), type_env.source_indices.clone()); - let ptype = resolved_type_name(p.clone(), type_env.source_indices.clone()); - if ((pname.clone() != "".to_string()) && (ptype.clone() != "".to_string())) { - v1_rt::rc_map_insert(acc.clone(), pname.clone(), ptype.clone()) - } else { - acc.clone() - } - }, - ); - let scalar = classify_body_provenance( - body.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - v1_rt::rc_empty_map::>>>(), - ); - if ((Rc::new(v1_rt::map_keys(&scalar)).len() as i64) > 0) { - Rc::new(vec![scalar.clone()]) - } else { - { - let per_field = classify_body_per_field( - body.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - v1_rt::rc_empty_map::>>>(), - ); - if (((per_field.clone().len() as i64) > 0) && { - let mut __found = false; - for m in per_field.clone().iter().cloned() { - if ((Rc::new(v1_rt::map_keys(&m)).len() as i64) > 0) { - __found = true; - break; - } - } - __found - }) { - per_field.clone() - } else { - Rc::new(vec![]) - } - } - } - } -} - -pub fn classify_body_provenance( - expr: Rc, - param_names: Rc>, - param_types: Rc>, - type_env: Rc, - func_env: Rc, - let_prov: Rc>>>>, -) -> Rc>> { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*expr.expr_data.clone()).clone() { - ExprData::ExprVar { - binding_kind: _, .. - } => { - let vname = expr_var_name_at(expr.clone(), type_env.source_indices.clone()); - match v1_rt::map_get(&let_prov, vname.clone()) { - Some(prov) => prov.clone(), - None => { - if { - let mut __found = false; - for pn in param_names.clone().iter().cloned() { - if (pn.clone() == vname.clone()) { - __found = true; - break; - } - } - __found - } { - v1_rt::rc_map_insert( - v1_rt::rc_empty_map::>(), - vname.clone(), - Rc::new(SubValueRelation::PreservedValue), - ) - } else { - v1_rt::rc_empty_map::>() - } - } - } - } - ExprData::ExprFieldAccess { summary: _, .. } => { - let base = field_access_base(expr.clone()); - let field = field_access_field_at(expr.clone(), type_env.source_indices.clone()); - let base_prov = classify_body_provenance( - base.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - Rc::new(v1_rt::map_keys(&base_prov)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, pname: String| { - match v1_rt::map_get(&base_prov, pname.clone()) { - Some(base_rel) => { - let type_for_lookup = match (*base_rel.clone()).clone() { - SubValueRelation::PreservedValue => { - match v1_rt::map_get(¶m_types, pname.clone()) { - Some(t) => t.clone(), - None => "".to_string(), - } - } - SubValueRelation::StrictSubValue { field: f, .. } => { - f.element_type.clone() - } - SubValueRelation::IteratedSubValue { field: f, .. } => { - f.element_type.clone() - } - _ => "".to_string(), - }; - if (type_for_lookup.clone() != "".to_string()) { - { - let fields = inductive_fields_for( - type_env.clone(), - type_for_lookup.clone(), - ); - let matching = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if (f.field_name.clone() == field.clone()) { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match matching.clone() { - Some(ind_field) => v1_rt::rc_map_insert( - acc.clone(), - pname.clone(), - compose_sub_value( - base_rel.clone(), - ind_field.clone(), - ), - ), - None => acc.clone(), - } - } - } else { - acc.clone() - } - } - None => acc.clone(), - } - }, - ) - } - ExprData::ExprCall { .. } => { - let callee = expr_call_func_at(expr.clone(), type_env.source_indices.clone()); - compose_callee_provenance( - callee.clone(), - call_args_by_name(expr.clone(), type_env.source_indices.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ) - } - ExprData::ExprMethodCall { - method_semantics: ms, - .. - } => { - let mname = expr_method_name_at(expr.clone(), type_env.source_indices.clone()); - let callee_result = compose_callee_provenance( - mname.clone(), - method_call_args_by_name( - expr.clone(), - func_env.clone(), - type_env.clone(), - type_env.source_indices.clone(), - ), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - if ((Rc::new(v1_rt::map_keys(&callee_result)).len() as i64) > 0) { - callee_result.clone() - } else { - { - let is_shrink = match ms.clone().as_deref().cloned() { - Some(MethodSemantics::AlgebraMethodSemantics { - size_effect: se, - .. - }) => match se.clone() { - Some(CollectionSizeEffect::ShrinkEffect) => true, - _ => false, - }, - _ => false, - }; - if (is_shrink.clone() - && match method_arg_nodes(expr.clone()).first().cloned() { - Some(arg_node) => { - match expr_literal_int_optional(arg_value(arg_node.clone())) { - Some(n) => (n.clone() > 0), - None => false, - } - } - None => false, - }) - { - { - let recv = method_receiver(expr.clone()); - let recv_prov = classify_body_provenance( - recv.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - Rc::new(v1_rt::map_keys(&recv_prov)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, - pname: String| { - match v1_rt::map_get(&recv_prov, pname.clone()) { - Some(recv_rel) => { - let synth_field = Rc::new(InductiveField { - type_name: pname.clone(), - variant_name: "".to_string(), - field_name: mname.clone(), - shape: RecursionShape::ListRecursion, - element_type: pname.clone(), - }); - v1_rt::rc_map_insert( - acc.clone(), - pname.clone(), - compose_sub_value( - recv_rel.clone(), - synth_field.clone(), - ), - ) - } - None => acc.clone(), - } - }, - ) - } - } else { - v1_rt::rc_empty_map::>() - } - } - } - } - ExprData::ExprMatch => { - let scrut = match_scrutinee(expr.clone()); - let scrut_prov = classify_body_provenance( - scrut.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - let arms = match_arm_nodes(expr.clone()); - let arm_provs = Rc::new({ - let mut __result = Vec::new(); - for arm in arms.clone().iter().cloned() { - __result.push({ - let arm_let_prov = match (*arm_pattern(arm.clone())).clone() { - MatchPattern::VariantPattern { name: vname, field_bindings: bindings, .. } => bindings.clone().iter().cloned().fold(let_prov.clone(), |acc: Rc>>>>, binding: Rc| { - let field_label = field_binding_name_at(binding.clone(), type_env.source_indices.clone()); -let bind_name = match (*field_binding_pattern(binding.clone())).clone() { - MatchPattern::Bind { declaration: declaration, .. } => declaration.name.clone(), - _ => "".to_string(), -}; -if ((bind_name.clone() != "".to_string()) && (field_label.clone() != "".to_string())) { - { - let field_prov = Rc::new(v1_rt::map_keys(&scrut_prov)).iter().cloned().fold(empty_prov_map(), |fp_acc: Rc>>, pname: String| maybe_insert_match_field_relation(fp_acc, pname.clone(), field_label.clone(), vname.clone(), v1_rt::map_get(&scrut_prov, pname.clone()), param_types.clone(), type_env.clone())); -v1_rt::rc_map_insert(acc.clone(), bind_name.clone(), field_prov.clone()) -} - } else { - acc.clone() - } -}), - MatchPattern::Bind { declaration: declaration, .. } => v1_rt::rc_map_insert(let_prov.clone(), declaration.name.clone(), scrut_prov.clone()), - _ => let_prov.clone(), -}; -classify_body_provenance(arm_body(arm.clone()), param_names.clone(), param_types.clone(), type_env.clone(), func_env.clone(), arm_let_prov.clone()) -}); - } - __result - }); - meet_body_provenance_maps(arm_provs.clone()) - } - ExprData::ExprIf => { - let then_prov = classify_body_provenance( - if_then_branch(expr.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - match if_else_branch(expr.clone()) { - Some(else_expr) => { - let else_prov = classify_body_provenance( - else_expr.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - meet_body_provenance_maps(Rc::new(vec![ - then_prov.clone(), - else_prov.clone(), - ])) - } - None => then_prov.clone(), - } - } - ExprData::ExprLet => { - let value = let_value(expr.clone()); - let bname = let_binding_name_at(expr.clone(), type_env.source_indices.clone()); - let value_prov = classify_body_provenance( - value.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - let updated = - v1_rt::rc_map_insert(let_prov.clone(), bname.clone(), value_prov.clone()); - match let_body(expr.clone()) { - Some(body) => classify_body_provenance( - body.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - updated.clone(), - ), - None => v1_rt::rc_empty_map::>(), - } - } - ExprData::ExprBlock => { - let block_result = expr.children.clone().iter().cloned().fold( - Rc::new(BlockProvFoldState { - prov: let_prov.clone(), - last: empty_prov_map(), - }), - |state: Rc, stmt: Rc| match (*stmt.expr_data.clone()) - .clone() - { - ExprData::ExprLet => { - let bname = - let_binding_name_at(stmt.clone(), type_env.source_indices.clone()); - let value = let_value(stmt.clone()); - let value_prov = classify_body_provenance( - value.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - state.prov.clone(), - ); - let updated_prov = v1_rt::rc_map_insert( - state.prov.clone(), - bname.clone(), - value_prov.clone(), - ); - match let_body(stmt.clone()) { - Some(body) => Rc::new(BlockProvFoldState { - prov: state.prov.clone(), - last: classify_body_provenance( - body.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - updated_prov.clone(), - ), - }), - None => Rc::new(BlockProvFoldState { - prov: updated_prov.clone(), - last: value_prov.clone(), - }), - } - } - _ => Rc::new(BlockProvFoldState { - prov: state.prov.clone(), - last: classify_body_provenance( - stmt.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - state.prov.clone(), - ), - }), - }, - ); - block_result.last.clone() - } - ExprData::ExprCast => classify_body_provenance( - cast_expr(expr.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ), - ExprData::ExprReturn => match expr.children.clone().first().cloned() { - Some(inner) => classify_body_provenance( - inner.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ), - None => v1_rt::rc_empty_map::>(), - }, - _ => v1_rt::rc_empty_map::>(), - } - }) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BlockProvFoldState { - pub prov: Rc>>>>, - pub last: Rc>>, -} - -pub fn call_args_by_name( - call: Rc, - source_indices: Rc>>, -) -> Rc>> { - call.children.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, arg_node: Rc| match arg_name_at( - arg_node.clone(), - source_indices.clone(), - ) { - Some(aname) => { - v1_rt::rc_map_insert(acc.clone(), aname.clone(), arg_value(arg_node.clone())) - } - None => acc.clone(), - }, - ) -} - -pub fn method_call_args_by_name( - call: Rc, - func_env: Rc, - type_env: Rc, - source_indices: Rc>>, -) -> Rc>> { - { - let mname = expr_method_name_at(call.clone(), source_indices.clone()); - let recv = method_receiver(call.clone()); - let mc_args = method_arg_nodes(call.clone()); - let base = match func_sig_if_resolved(lookup_func_sig( - func_env.clone(), - type_env.clone(), - mname.clone(), - )) { - Some(sig) => match sig.params.clone().first().cloned() { - Some(first_p) => { - let first_pname = param_node_name_at(first_p.clone(), source_indices.clone()); - if (first_pname.clone() != "".to_string()) { - v1_rt::rc_map_insert( - v1_rt::rc_empty_map::>(), - first_pname.clone(), - recv.clone(), - ) - } else { - v1_rt::rc_empty_map::>() - } - } - None => v1_rt::rc_empty_map::>(), - }, - None => v1_rt::rc_empty_map::>(), - }; - mc_args.clone().iter().cloned().fold( - base.clone(), - |acc: Rc>>, arg_node: Rc| match arg_name_at( - arg_node.clone(), - source_indices.clone(), - ) { - Some(aname) => { - v1_rt::rc_map_insert(acc.clone(), aname.clone(), arg_value(arg_node.clone())) - } - None => acc.clone(), - }, - ) - } -} - -pub fn compose_callee_provenance( - callee: String, - arg_by_name: Rc>>, - param_names: Rc>, - param_types: Rc>, - type_env: Rc, - func_env: Rc, - let_prov: Rc>>>>, -) -> Rc>> { - match func_sig_if_resolved(lookup_func_sig( - func_env.clone(), - type_env.clone(), - callee.clone(), - )) { - Some(sig) => match sig.output_provenance.clone().first().cloned() { - Some(callee_prov) => Rc::new(v1_rt::map_keys(&callee_prov)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, callee_pname: String| { - match v1_rt::map_get(&callee_prov, callee_pname.clone()) { - Some(callee_rel) => { - match v1_rt::map_get(&arg_by_name, callee_pname.clone()) { - Some(arg) => { - let arg_prov = classify_body_provenance( - arg.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - Rc::new(v1_rt::map_keys(&arg_prov)).iter().cloned().fold( - acc.clone(), - |inner: Rc>>, - pname: String| { - match v1_rt::map_get(&arg_prov, pname.clone()) { - Some(arg_rel) => { - let composed = compose_sub_value_relations( - arg_rel.clone(), - callee_rel.clone(), - ); - match (*composed.clone()).clone() { - SubValueRelation::SubValueUnknown => { - inner.clone() - } - _ => match v1_rt::map_get( - &inner, - pname.clone(), - ) { - Some(existing) => v1_rt::rc_map_insert( - inner.clone(), - pname.clone(), - meet_sub_value( - existing.clone(), - composed.clone(), - ), - ), - None => v1_rt::rc_map_insert( - inner.clone(), - pname.clone(), - composed.clone(), - ), - }, - } - } - None => inner.clone(), - } - }, - ) - } - None => acc.clone(), - } - } - None => acc.clone(), - } - }, - ), - None => v1_rt::rc_empty_map::>(), - }, - None => v1_rt::rc_empty_map::>(), - } -} - -pub fn classify_body_per_field( - expr: Rc, - param_names: Rc>, - param_types: Rc>, - type_env: Rc, - func_env: Rc, - let_prov: Rc>>>>, -) -> Rc>>>> { - { - let unwrapped = unwrap_body_terminal(expr.clone(), let_prov.clone(), type_env.clone()); - let terminal = unwrapped.expr.clone(); - let terminal_prov = unwrapped.let_prov.clone(); - classify_terminal_per_field( - terminal.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - terminal_prov.clone(), - ) - } -} - -pub fn classify_terminal_per_field( - expr: Rc, - param_names: Rc>, - param_types: Rc>, - type_env: Rc, - func_env: Rc, - let_prov: Rc>>>>, -) -> Rc>>>> { - match (*expr.expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ - let mut __result = Vec::new(); - for fi in expr.children.clone().iter().cloned() { - __result.push(classify_body_provenance( - field_init_node_value(fi.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - )); - } - __result - }), - ExprData::ExprMatch => { - let arm_results = Rc::new({ - let mut __result = Vec::new(); - for arm in match_arm_nodes(expr.clone()).iter().cloned() { - __result.push({ - let arm_unwrapped = unwrap_body_terminal( - arm_body(arm.clone()), - let_prov.clone(), - type_env.clone(), - ); - match (*arm_unwrapped.expr.clone().expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ - let mut __result = Vec::new(); - for fi in - arm_unwrapped.expr.clone().children.clone().iter().cloned() - { - __result.push(classify_body_provenance( - field_init_node_value(fi.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - arm_unwrapped.let_prov.clone(), - )); - } - __result - }), - _ => Rc::new(vec![]), - } - }); - } - __result - }); - meet_per_field_results(arm_results.clone()) - } - ExprData::ExprIf => { - let then_unwrapped = unwrap_body_terminal( - if_then_branch(expr.clone()), - let_prov.clone(), - type_env.clone(), - ); - let then_result = match (*then_unwrapped.expr.clone().expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ - let mut __result = Vec::new(); - for fi in then_unwrapped.expr.clone().children.clone().iter().cloned() { - __result.push(classify_body_provenance( - field_init_node_value(fi.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - then_unwrapped.let_prov.clone(), - )); - } - __result - }), - _ => Rc::new(vec![]), - }; - match if_else_branch(expr.clone()) { - Some(else_expr) => { - let else_unwrapped = - unwrap_body_terminal(else_expr.clone(), let_prov.clone(), type_env.clone()); - let else_result = match (*else_unwrapped.expr.clone().expr_data.clone()).clone() - { - ExprData::ExprRecordLit { parent_enum: _, .. } => Rc::new({ - let mut __result = Vec::new(); - for fi in else_unwrapped.expr.clone().children.clone().iter().cloned() { - __result.push(classify_body_provenance( - field_init_node_value(fi.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - else_unwrapped.let_prov.clone(), - )); - } - __result - }), - _ => Rc::new(vec![]), - }; - meet_per_field_results(Rc::new(vec![then_result.clone(), else_result.clone()])) - } - None => then_result.clone(), - } - } - _ => Rc::new(vec![]), - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BodyTerminal { - pub expr: Rc, - pub let_prov: Rc>>>>, -} - -pub fn unwrap_body_terminal( - expr: Rc, - let_prov: Rc>>>>, - type_env: Rc, -) -> Rc { - match (*expr.expr_data.clone()).clone() { - ExprData::ExprBlock => match expr.children.clone().last().cloned() { - Some(last_stmt) => Rc::new(BodyTerminal { - expr: last_stmt.clone(), - let_prov: let_prov.clone(), - }), - None => Rc::new(BodyTerminal { - expr: expr.clone(), - let_prov: let_prov.clone(), - }), - }, - _ => Rc::new(BodyTerminal { - expr: expr.clone(), - let_prov: let_prov.clone(), - }), - } -} - -pub fn meet_per_field_results( - results: Rc>>>>>>, -) -> Rc>>>> { - match results.clone().first().cloned() { - None => Rc::new(vec![]), - Some(first_result) => { - if ((first_result.clone().len() as i64) == 0) { - Rc::new(vec![]) - } else { - { - let all_same_count = { - let mut __all = true; - for r in results.clone().iter().cloned() { - if !((r.clone().len() as i64) == (first_result.clone().len() as i64)) { - __all = false; - break; - } - } - __all - }; - if !all_same_count.clone() { - Rc::new(vec![]) - } else { - Rc::new({ - let mut __result = Vec::new(); - for pair in Rc::new( - first_result - .clone() - .iter() - .cloned() - .enumerate() - .map(|(i, v)| (i as i64, v)) - .collect::>(), - ) - .iter() - .cloned() - { - __result.push({ - let idx = pair.0.clone(); - let field_provs = Rc::new({ - let mut __result = Vec::new(); - for r in results.clone().iter().cloned() { - __result.push( - match r - .clone() - .iter() - .cloned() - .skip(idx.clone() as usize) - .next() - { - Some(m) => m.clone(), - None => empty_prov_map(), - }, - ); - } - __result - }); - meet_body_provenance_maps(field_provs.clone()) - }); - } - __result - }) - } - } - } - } - } -} - -pub fn empty_prov_map() -> Rc>> { - v1_rt::rc_empty_map::>() -} - -pub fn meet_body_provenance_maps( - provs: Rc>>>>, -) -> Rc>> { - match provs.clone().first().cloned() { - None => empty_prov_map(), - Some(first_prov) => Rc::new( - provs - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - first_prov.clone(), - |acc: Rc>>, - prov: Rc>>| { - intersect_prov_maps(acc, prov.clone()) - }, - ), - } -} - -pub fn intersect_prov_maps( - a: Rc>>, - b: Rc>>, -) -> Rc>> { - Rc::new(v1_rt::map_keys(&a)).iter().cloned().fold( - empty_prov_map(), - |result: Rc>>, key: String| match v1_rt::map_get( - &b, - key.clone(), - ) { - Some(b_rel) => match v1_rt::map_get(&a, key.clone()) { - Some(a_rel) => v1_rt::rc_map_insert( - result.clone(), - key.clone(), - meet_sub_value(a_rel.clone(), b_rel.clone()), - ), - None => result.clone(), - }, - None => result.clone(), - }, - ) -} - -pub fn arm_ctx_from_variant_provenance( - arm_node: Rc, - sig: Rc, - scrut: Rc, - ctx: Rc, -) -> Option> { - match (*arm_pattern(arm_node.clone())).clone() { - MatchPattern::VariantPattern { - name: vname, - field_bindings: bindings, - .. - } => match v1_rt::map_get(&sig.variant_provenance.clone(), vname.clone()) { - Some(variant_field_map) => { - let call_args = - call_args_by_name(scrut.clone(), ctx.type_env.clone().source_indices.clone()); - let extended = bindings.clone().iter().cloned().fold( - ctx.clone(), - |c: Rc, fb: Rc| { - let field_label = field_binding_name_at( - fb.clone(), - ctx.type_env.clone().source_indices.clone(), - ); - let bind_name = match (*field_binding_pattern(fb.clone())).clone() { - MatchPattern::Bind { - declaration: declaration, - .. - } => declaration.name.clone(), - _ => "".to_string(), - }; - if ((bind_name.clone() == "".to_string()) - || (field_label.clone() == "".to_string())) - { - c.clone() - } else { - match v1_rt::map_get(&variant_field_map, field_label.clone()) { - Some(param_map) => { - let composed = compose_callee_param_map( - param_map.clone(), - call_args.clone(), - c.param_order.clone(), - c.param_names.clone(), - c.type_env.clone(), - c.func_env.clone(), - v1_rt::rc_empty_map::< - String, - Rc>>, - >(), - ); - let all_rels = Rc::new({ - let mut __result = Vec::new(); - for k in Rc::new(v1_rt::map_keys(&composed)).iter().cloned() - { - __result.push( - match v1_rt::map_get(&composed, k.clone()) { - Some(r) => r.clone(), - None => { - Rc::new(SubValueRelation::SubValueUnknown) - } - }, - ); - } - __result - }); - let best = merge_argument_relations(all_rels.clone()); - match (*best.clone()).clone() { - SubValueRelation::SubValueUnknown => c.clone(), - _ => Rc::new(DescentContext { - fn_name: c.fn_name.clone(), - param_names: c.param_names.clone(), - param_order: c.param_order.clone(), - type_env: c.type_env.clone(), - sub_value_vars: v1_rt::rc_map_insert( - c.sub_value_vars.clone(), - bind_name.clone(), - best.clone(), - ), - size_aliases: c.size_aliases.clone(), - scope_locals: c.scope_locals.clone(), - func_env: c.func_env.clone(), - per_field_vars: c.per_field_vars.clone(), - }), - } - } - None => c.clone(), - } - } - }, - ); - Some(extended.clone()) - } - None => None, - }, - _ => None, - } -} - -pub fn compose_callee_param_map( - callee_prov: Rc>>, - arg_by_name: Rc>>, - param_names: Rc>, - param_types: Rc>, - type_env: Rc, - func_env: Rc, - let_prov: Rc>>>>, -) -> Rc>> { - Rc::new(v1_rt::map_keys(&callee_prov)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, callee_pname: String| match v1_rt::map_get( - &callee_prov, - callee_pname.clone(), - ) { - Some(callee_rel) => match v1_rt::map_get(&arg_by_name, callee_pname.clone()) { - Some(arg) => { - let arg_prov = classify_body_provenance( - arg.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - Rc::new(v1_rt::map_keys(&arg_prov)).iter().cloned().fold( - acc.clone(), - |inner: Rc>>, pname: String| { - match v1_rt::map_get(&arg_prov, pname.clone()) { - Some(arg_rel) => { - let composed = compose_sub_value_relations( - arg_rel.clone(), - callee_rel.clone(), - ); - match (*composed.clone()).clone() { - SubValueRelation::SubValueUnknown => inner.clone(), - _ => v1_rt::rc_map_insert( - inner.clone(), - pname.clone(), - composed.clone(), - ), - } - } - None => inner.clone(), - } - }, - ) - } - None => acc.clone(), - }, - None => acc.clone(), - }, - ) -} - -pub fn compose_output_relations( - arg_rel: Rc, - callee_rel: Rc, -) -> Rc { - compose_sub_value_relations(arg_rel.clone(), callee_rel.clone()) -} - -pub fn compute_variant_provenance( - body: Rc, - return_type: Rc, - params: Rc>>, - type_env: Rc, - func_env: Rc, -) -> Rc>>>>>> { - { - let rt_name = authored_name_at(type_env.source_indices.clone(), return_type.clone()); - let rt_def = lookup_type_by_name(type_env.clone(), rt_name.clone()); - match rt_def.clone() { - Some(def_node) => match def_node.connective.clone() { - Connective::Disj => { - let param_names = Rc::new({ - let mut __result = Vec::new(); - for p in params.clone().iter().cloned() { - __result.push(param_node_name_at( - p.clone(), - type_env.source_indices.clone(), - )); - } - __result - }); - let param_types = params.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, p: Rc| { - let pname = - param_node_name_at(p.clone(), type_env.source_indices.clone()); - let ptype = - resolved_type_name(p.clone(), type_env.source_indices.clone()); - if ((pname.clone() != "".to_string()) - && (ptype.clone() != "".to_string())) - { - v1_rt::rc_map_insert(acc.clone(), pname.clone(), ptype.clone()) - } else { - acc.clone() - } - }, - ); - collect_variant_constructors( - body.clone(), - rt_name.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - v1_rt::rc_empty_map::>>>(), - v1_rt::rc_empty_map::< - String, - Rc>>>>, - >(), - ) - } - _ => v1_rt::rc_empty_map::< - String, - Rc>>>>, - >(), - }, - None => v1_rt::rc_empty_map::< - String, - Rc>>>>, - >(), - } - } -} - -pub fn collect_variant_constructors( - body: Rc, - parent_enum: String, - param_names: Rc>, - param_types: Rc>, - type_env: Rc, - func_env: Rc, - let_prov: Rc>>>>, - acc: Rc>>>>>>, -) -> Rc>>>>>> { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match (*body.expr_data.clone()).clone() { - ExprData::ExprRecordLit { - parent_enum: pe, .. - } => match pe.clone() { - Some(enum_name) => { - if (enum_name.clone() == parent_enum.clone()) { - { - let variant_name = body.name.clone(); - let field_prov_map = body.children.clone().iter().cloned().fold( - v1_rt::rc_empty_map::< - String, - Rc>>, - >(), - |m: Rc< - HashMap>>>, - >, - fi: Rc| { - let fname = field_init_node_name_at( - fi.clone(), - type_env.source_indices.clone(), - ); - let fprov = classify_body_provenance( - field_init_node_value(fi.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - if (fname.clone() != "".to_string()) { - v1_rt::rc_map_insert( - m.clone(), - fname.clone(), - fprov.clone(), - ) - } else { - m.clone() - } - }, - ); - match v1_rt::map_get(&acc, variant_name.clone()) { - Some(existing) => { - let merged = merge_field_prov_maps( - existing.clone(), - field_prov_map.clone(), - ); - v1_rt::rc_map_insert( - acc.clone(), - variant_name.clone(), - merged.clone(), - ) - } - None => v1_rt::rc_map_insert( - acc.clone(), - variant_name.clone(), - field_prov_map.clone(), - ), - } - } - } else { - acc.clone() - } - } - None => acc.clone(), - }, - ExprData::ExprCall { .. } => { - let callee = expr_call_func_at(body.clone(), type_env.source_indices.clone()); - match func_sig_if_resolved(lookup_func_sig( - func_env.clone(), - type_env.clone(), - callee.clone(), - )) { - Some(sig) => { - if ((authored_name_at( - type_env.source_indices.clone(), - sig.inferred.clone(), - ) == parent_enum.clone()) - && ((Rc::new(v1_rt::map_keys(&sig.variant_provenance.clone())).len() - as i64) - > 0)) - { - { - let call_args = call_args_by_name( - body.clone(), - type_env.source_indices.clone(), - ); - Rc::new(v1_rt::map_keys(&sig.variant_provenance.clone())).iter().cloned().fold(acc.clone(), |variant_acc: Rc>>>>>>, variant_name: String| match v1_rt::map_get(&sig.variant_provenance.clone(), variant_name.clone()) { - Some(field_map) => { - let composed_field_map = Rc::new(v1_rt::map_keys(&field_map)).iter().cloned().fold(v1_rt::rc_empty_map::>>>(), |fm_acc: Rc>>>>, field_name: String| match v1_rt::map_get(&field_map, field_name.clone()) { - Some(param_map) => { - let composed = compose_callee_param_map(param_map.clone(), call_args.clone(), param_names.clone(), param_types.clone(), type_env.clone(), func_env.clone(), let_prov.clone()); -if ((Rc::new(v1_rt::map_keys(&composed)).len() as i64) > 0) { - v1_rt::rc_map_insert(fm_acc.clone(), field_name.clone(), composed.clone()) - } else { - fm_acc.clone() - } -}, - None => fm_acc.clone(), -}); -if ((Rc::new(v1_rt::map_keys(&composed_field_map)).len() as i64) > 0) { - match v1_rt::map_get(&variant_acc, variant_name.clone()) { - Some(existing) => v1_rt::rc_map_insert(variant_acc.clone(), variant_name.clone(), merge_field_prov_maps(existing.clone(), composed_field_map.clone())), - None => v1_rt::rc_map_insert(variant_acc.clone(), variant_name.clone(), composed_field_map.clone()), -} - } else { - variant_acc.clone() - } -}, - None => variant_acc.clone(), -}) - } - } else { - acc.clone() - } - } - None => acc.clone(), - } - } - ExprData::ExprMatch => match_arm_nodes(body.clone()).iter().cloned().fold( - acc.clone(), - |a: Rc< - HashMap>>>>>, - >, - arm: Rc| { - collect_variant_constructors( - arm_body(arm.clone()), - parent_enum.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - a, - ) - }, - ), - ExprData::ExprIf => { - let then_acc = collect_variant_constructors( - if_then_branch(body.clone()), - parent_enum.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - acc.clone(), - ); - match if_else_branch(body.clone()) { - Some(eb) => collect_variant_constructors( - eb.clone(), - parent_enum.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - then_acc.clone(), - ), - None => then_acc.clone(), - } - } - ExprData::ExprLet => match let_body(body.clone()) { - Some(b) => { - let bname = let_binding_name_at(body.clone(), type_env.source_indices.clone()); - let value_prov = classify_body_provenance( - let_value(body.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - let_prov.clone(), - ); - let new_lp = - v1_rt::rc_map_insert(let_prov.clone(), bname.clone(), value_prov.clone()); - collect_variant_constructors( - b.clone(), - parent_enum.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - new_lp.clone(), - acc.clone(), - ) - } - None => acc.clone(), - }, - ExprData::ExprBlock => { - let stmts = body.children.clone(); - let stmt_count = (stmts.clone().len() as i64); - if (stmt_count.clone() == 0) { - acc.clone() - } else { - { - let final_lp = Rc::new( - stmts - .clone() - .iter() - .cloned() - .take((stmt_count.clone() - 1) as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - let_prov.clone(), - |lp: Rc>>>>, - stmt: Rc| match (*stmt - .expr_data - .clone()) - .clone() - { - ExprData::ExprLet => { - let bname = let_binding_name_at( - stmt.clone(), - type_env.source_indices.clone(), - ); - let vprov = classify_body_provenance( - let_value(stmt.clone()), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - lp.clone(), - ); - v1_rt::rc_map_insert(lp.clone(), bname.clone(), vprov.clone()) - } - _ => lp.clone(), - }, - ); - match stmts - .clone() - .iter() - .cloned() - .skip((stmt_count.clone() - 1) as usize) - .next() - { - Some(last) => collect_variant_constructors( - last.clone(), - parent_enum.clone(), - param_names.clone(), - param_types.clone(), - type_env.clone(), - func_env.clone(), - final_lp.clone(), - acc.clone(), - ), - None => acc.clone(), - } - } - } - } - _ => acc.clone(), - } - }) -} - -pub fn merge_field_prov_maps( - a: Rc>>>>, - b: Rc>>>>, -) -> Rc>>>> { - { - let from_a = Rc::new(v1_rt::map_keys(&a)).iter().cloned().fold( - v1_rt::rc_empty_map::>>>(), - |result: Rc>>>>, - fname: String| match v1_rt::map_get(&a, fname.clone()) { - Some(a_prov) => match v1_rt::map_get(&b, fname.clone()) { - Some(b_prov) => v1_rt::rc_map_insert( - result.clone(), - fname.clone(), - union_prov_maps(a_prov.clone(), b_prov.clone()), - ), - None => v1_rt::rc_map_insert(result.clone(), fname.clone(), a_prov.clone()), - }, - None => result.clone(), - }, - ); - Rc::new(v1_rt::map_keys(&b)).iter().cloned().fold( - from_a.clone(), - |result: Rc>>>>, - fname: String| { - if (v1_rt::map_get(&result, fname.clone()) != None) { - result.clone() - } else { - match v1_rt::map_get(&b, fname.clone()) { - Some(b_prov) => { - v1_rt::rc_map_insert(result.clone(), fname.clone(), b_prov.clone()) - } - None => result.clone(), - } - } - }, - ) - } -} - -pub fn union_prov_maps( - a: Rc>>, - b: Rc>>, -) -> Rc>> { - { - let from_a = Rc::new(v1_rt::map_keys(&a)).iter().cloned().fold( - empty_prov_map(), - |result: Rc>>, key: String| match v1_rt::map_get( - &a, - key.clone(), - ) { - Some(a_rel) => match v1_rt::map_get(&b, key.clone()) { - Some(b_rel) => v1_rt::rc_map_insert( - result.clone(), - key.clone(), - join_sub_value(a_rel.clone(), b_rel.clone()), - ), - None => v1_rt::rc_map_insert(result.clone(), key.clone(), a_rel.clone()), - }, - None => result.clone(), - }, - ); - Rc::new(v1_rt::map_keys(&b)).iter().cloned().fold( - from_a.clone(), - |result: Rc>>, key: String| { - if (v1_rt::map_get(&result, key.clone()) != None) { - result.clone() - } else { - match v1_rt::map_get(&b, key.clone()) { - Some(b_rel) => { - v1_rt::rc_map_insert(result.clone(), key.clone(), b_rel.clone()) - } - None => result.clone(), - } - } - }, - ) - } -} - -pub fn populate_output_provenance( - typed_items: Rc>>, - func_env: Rc, - type_env: Rc, - locals: Rc>>, -) -> Rc { - { - let updated_local = typed_items.clone().iter().cloned().fold( - func_env.local.clone(), - |acc: Rc>>, item: Rc| { - if ((item.params.clone().len() as i64) > 0) { - { - let fn_name = - authored_name_at(type_env.source_indices.clone(), item.clone()); - if (is_child_accessor_in_model(fn_name.clone()) - || is_tree_size_reducing(fn_name.clone())) - { - match item.params.clone().first().cloned() { - Some(first_param) => { - let pname = param_node_name_at( - first_param.clone(), - type_env.source_indices.clone(), - ); - let ptype = resolved_type_name( - first_param.clone(), - type_env.source_indices.clone(), - ); - if ((ptype.clone() != "".to_string()) - && (pname.clone() != "".to_string())) - { - { - let fields = inductive_fields_for( - type_env.clone(), - ptype.clone(), - ); - let list_field = Rc::new({ - let mut __result = Vec::new(); - for f in fields.clone().iter().cloned() { - if match f.shape.clone() { - RecursionShape::ListRecursion => true, - _ => false, - } { - __result.push(f); - } - } - __result - }) - .first() - .cloned(); - match list_field.clone() { - Some(ind_field) => { - let relation = - Rc::new(SubValueRelation::StrictSubValue { - field: ind_field.clone(), - factor: Rc::new( - ShrinkFactor::UnitShrink, - ), - }); - let provenance = - Rc::new(vec![v1_rt::rc_map_insert( - v1_rt::rc_empty_map::< - String, - Rc, - >( - ), - pname.clone(), - relation.clone(), - )]); - match v1_rt::map_get(&acc, fn_name.clone()) { - Some(sig) => v1_rt::rc_map_insert( - acc.clone(), - fn_name.clone(), - Rc::new(ResolvedFuncSig { - name: sig.name.clone(), - params: sig.params.clone(), - inferred: sig.inferred.clone(), - is_async: sig.is_async.clone(), - output_provenance: provenance - .clone(), - variant_provenance: sig - .variant_provenance - .clone(), - }), - ), - None => acc.clone(), - } - } - None => acc.clone(), - } - } - } else { - acc.clone() - } - } - None => acc.clone(), - } - } else { - match item.body.clone() { - Some(body) => { - if !expr_has_self_call( - body.clone(), - fn_name.clone(), - type_env.source_indices.clone(), - ) { - { - let working_env = Rc::new(ResolvedFuncEnv { - name: func_env.name.clone(), - local: acc.clone(), - parents: func_env.parents.clone(), - }); - let provenance = infer_output_provenance( - body.clone(), - item.params.clone(), - type_env.clone(), - locals.clone(), - working_env.clone(), - ); - let variant_prov = - match item.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { - node: rt, - .. - }) => compute_variant_provenance( - body.clone(), - rt.clone(), - item.params.clone(), - type_env.clone(), - working_env.clone(), - ), - _ => v1_rt::rc_empty_map::< - String, - Rc< - HashMap< - String, - Rc< - HashMap< - String, - Rc, - >, - >, - >, - >, - >( - ), - }; - let has_scalar = - ((provenance.clone().len() as i64) > 0); - let has_variant = - ((Rc::new(v1_rt::map_keys(&variant_prov)).len() - as i64) - > 0); - if (has_scalar.clone() || has_variant.clone()) { - match v1_rt::map_get(&acc, fn_name.clone()) { - Some(sig) => v1_rt::rc_map_insert( - acc.clone(), - fn_name.clone(), - Rc::new(ResolvedFuncSig { - name: sig.name.clone(), - params: sig.params.clone(), - inferred: sig.inferred.clone(), - is_async: sig.is_async.clone(), - output_provenance: if has_scalar.clone() - { - provenance.clone() - } else { - sig.output_provenance.clone() - }, - variant_provenance: if has_variant - .clone() - { - variant_prov.clone() - } else { - sig.variant_provenance.clone() - }, - }), - ), - None => acc.clone(), - } - } else { - acc.clone() - } - } - } else { - acc.clone() - } - } - None => acc.clone(), - } - } - } - } else { - acc.clone() - } - }, - ); - Rc::new(ResolvedFuncEnv { - name: func_env.name.clone(), - local: updated_local.clone(), - parents: func_env.parents.clone(), - }) - } -} - -pub fn annotate_descent_evidence( - body: Rc, - fn_name: String, - params: Rc>>, - type_env: Rc, - scope_locals: Rc>>, - func_env: Rc, -) -> Rc { - { - let param_name_map = params.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, p: Rc| { - let pname = param_node_name_at(p.clone(), type_env.source_indices.clone()); - let ptype = resolved_type_name(p.clone(), type_env.source_indices.clone()); - v1_rt::rc_map_insert(acc, pname.clone(), ptype.clone()) - }, - ); - let param_order_list = Rc::new({ - let mut __result = Vec::new(); - for p in params.clone().iter().cloned() { - __result.push(param_node_name_at( - p.clone(), - type_env.source_indices.clone(), - )); - } - __result - }); - let ctx = Rc::new(DescentContext { - fn_name: fn_name.clone(), - param_names: param_name_map.clone(), - param_order: param_order_list.clone(), - type_env: type_env.clone(), - sub_value_vars: v1_rt::rc_empty_map::>(), - size_aliases: v1_rt::rc_empty_map::>(), - scope_locals: scope_locals.clone(), - func_env: func_env.clone(), - per_field_vars: v1_rt::rc_empty_map::>>>( - ), - }); - annotate_descent(body.clone(), ctx.clone()) - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct InferPropertiesResult { - pub props: Rc>>, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct InferTransportResult { - pub transport: Option>, - pub diagnostics: Rc>>, -} - -pub fn infer_property_values( - props: Rc>>, - scope: Rc, -) -> Rc { - { - let results = Rc::new({ - let mut __result = Vec::new(); - for p in props.clone().iter().cloned() { - __result.push({ - let val = field_init_node_value(p.clone()); - let val_result = infer_expr(val.clone(), scope.clone(), None); - ( - Rc::new(Node { - name: p.name.clone(), - span: p.span.clone(), - ident_span: p.ident_span.clone(), - children: Rc::new(vec![val_result.typed.clone()]), - connective: p.connective.clone(), - params: p.params.clone(), - inferred: p.inferred.clone(), - return_cardinality: p.return_cardinality.clone(), - uses: p.uses.clone(), - body: p.body.clone(), - transport: p.transport.clone(), - properties: p.properties.clone(), - type_annotation: p.type_annotation.clone(), - is_self_recursive: p.is_self_recursive.clone(), - has_non_tail_self_call: p.has_non_tail_self_call.clone(), - match_pattern: p.match_pattern.clone(), - expr_data: p.expr_data.clone(), - ident: None, - }), - val_result.diagnostics.clone(), - ) - }); - } - __result - }); - Rc::new(InferPropertiesResult { - props: Rc::new({ - let mut __result = Vec::new(); - for r in results.clone().iter().cloned() { - __result.push(r.0.clone()); - } - __result - }), - diagnostics: Rc::new({ - let mut __result = Vec::new(); - for r in results.clone().iter().cloned() { - __result.extend((*r.1.clone()).iter().cloned()); - } - __result - }), - }) - } -} - -pub fn infer_auth_source_properties( - props: Rc>>, - scope: Rc, -) -> Rc { - { - let results = Rc::new({ - let mut __result = Vec::new(); - for p in props.clone().iter().cloned() { - __result.push( - if (field_init_node_name_at( - p.clone(), - scope.type_env.clone().source_indices.clone(), - ) == "svc_auth_source".to_string()) - { - { - let val = field_init_node_value(p.clone()); - let val_result = infer_expr(val.clone(), scope.clone(), None); - ( - Rc::new(Node { - name: p.name.clone(), - span: p.span.clone(), - ident_span: p.ident_span.clone(), - children: Rc::new(vec![val_result.typed.clone()]), - connective: p.connective.clone(), - params: p.params.clone(), - inferred: p.inferred.clone(), - return_cardinality: p.return_cardinality.clone(), - uses: p.uses.clone(), - body: p.body.clone(), - transport: p.transport.clone(), - properties: p.properties.clone(), - type_annotation: p.type_annotation.clone(), - is_self_recursive: p.is_self_recursive.clone(), - has_non_tail_self_call: p.has_non_tail_self_call.clone(), - match_pattern: p.match_pattern.clone(), - expr_data: p.expr_data.clone(), - ident: None, - }), - val_result.diagnostics.clone(), - ) - } - } else { - (p.clone(), Rc::new(vec![])) - }, - ); - } - __result - }); - Rc::new(InferPropertiesResult { - props: Rc::new({ - let mut __result = Vec::new(); - for r in results.clone().iter().cloned() { - __result.push(r.0.clone()); - } - __result - }), - diagnostics: Rc::new({ - let mut __result = Vec::new(); - for r in results.clone().iter().cloned() { - __result.extend((*r.1.clone()).iter().cloned()); - } - __result - }), - }) - } -} - -pub fn infer_transport_node( - transport: Option>, - scope: Rc, -) -> Rc { - match transport.clone() { - None => Rc::new(InferTransportResult { - transport: None, - diagnostics: Rc::new(vec![]), - }), - Some(t) => { - let prop_result = infer_property_values(t.properties.clone(), scope.clone()); - Rc::new(InferTransportResult { - transport: Some(Rc::new(Node { - name: t.name.clone(), - span: t.span.clone(), - ident_span: t.ident_span.clone(), - children: t.children.clone(), - connective: t.connective.clone(), - params: t.params.clone(), - inferred: t.inferred.clone(), - return_cardinality: t.return_cardinality.clone(), - uses: t.uses.clone(), - body: t.body.clone(), - transport: t.transport.clone(), - properties: prop_result.props.clone(), - type_annotation: t.type_annotation.clone(), - is_self_recursive: t.is_self_recursive.clone(), - has_non_tail_self_call: t.has_non_tail_self_call.clone(), - match_pattern: t.match_pattern.clone(), - expr_data: t.expr_data.clone(), - ident: None, - })), - diagnostics: prop_result.diagnostics.clone(), - }) - } - } -} - -pub fn infer_item(item: Rc, scope: Rc) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - let typed_anno = item.type_annotation.clone(); - let transport_scope = if ((item.params.clone().len() as i64) > 0) { - build_params_scope(scope.clone(), item.params.clone()) - } else { - scope.clone() - }; - let transport_result = - infer_transport_node(item.transport.clone(), transport_scope.clone()); - let typed_transport = transport_result.transport.clone(); - let transport_diags = transport_result.diagnostics.clone(); - let props_result = infer_auth_source_properties(item.properties.clone(), scope.clone()); - let typed_properties = props_result.props.clone(); - let props_diags = props_result.diagnostics.clone(); - if ((item.connective.clone() != Connective::NoConnective) - && (item.transport.clone() == None)) - { - Rc::new(TypedItemResult { - item: Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new({ - let mut __result = Vec::new(); - for c in item.children.clone().iter().cloned() { - __result.push(infer_item(c.clone(), scope.clone()).item.clone()); - } - __result - }), - params: item.params.clone(), - inferred: Some(Rc::new(InferredNode::Resolved { node: unit_type() })), - return_cardinality: item.return_cardinality.clone(), - uses: item.uses.clone(), - body: None, - connective: item.connective.clone(), - transport: typed_transport.clone(), - properties: typed_properties.clone(), - type_annotation: typed_anno.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - diagnostics: v1_rt::concat(transport_diags.clone(), props_diags.clone()), - }) - } else { - if ((item.body.clone() != None) && ((item.params.clone().len() as i64) > 0)) { - { - let fn_scope = build_params_scope(scope.clone(), item.params.clone()); - let fn_scope = item.uses.clone().iter().cloned().fold( - fn_scope.clone(), - |s: Rc, u: Rc| { - extend_scope( - s, - resource_use_name_at( - u.clone(), - scope.type_env.clone().source_indices.clone(), - ), - resource_use_resource(u.clone()), - Rc::new(SubValueRelation::SubValueUnknown), - ) - }, - ); - let fn_decl_name = authored_name_at( - scope.type_env.clone().source_indices.clone(), - item.clone(), - ); - let fn_scope = Rc::new(InferScope { - type_env: fn_scope.type_env.clone(), - func_env: fn_scope.func_env.clone(), - locals: fn_scope.locals.clone(), - body_locals: fn_scope.body_locals.clone(), - match_bound_names: fn_scope.match_bound_names.clone(), - module_name: fn_scope.module_name.clone(), - service_registry: fn_scope.service_registry.clone(), - item_registry: fn_scope.item_registry.clone(), - caller_decl_name: fn_decl_name.clone(), - lambda_param_provenance: fn_scope.lambda_param_provenance.clone(), - }); - let fn_return_expected = if (item.inferred.clone() != None) { - Some(resolved_type(item.clone())) - } else { - None - }; - let body_result = infer_expr( - item.body.clone().clone().unwrap(), - fn_scope.clone(), - fn_return_expected.clone(), - ); - let body_typed = body_result.typed.clone(); - let body_diags = body_result.diagnostics.clone(); - let inferred_ret = if (item.inferred.clone() != None) { - item.inferred.clone() - } else { - body_typed.inferred.clone() - }; - let return_conformance_diags = if (item.inferred.clone() != None) { - v1_rt::concat( - declared_type_conformance_diags( - declared_return_type_node(item.clone()), - resolved_type(body_typed.clone()), - item.body.clone().clone().unwrap().span.clone(), - scope.clone(), - ), - explicit_return_conformance_diags( - declared_return_type_node(item.clone()), - body_typed.clone(), - scope.clone(), - ), - ) - } else { - Rc::new(vec![]) - }; - let is_recursive = expr_has_self_call( - body_typed.clone(), - authored_name_at( - scope.type_env.clone().source_indices.clone(), - item.clone(), - ), - scope.type_env.clone().source_indices.clone(), - ); - let annotated_body = if is_recursive.clone() { - annotate_descent_evidence( - body_typed.clone(), - authored_name_at( - scope.type_env.clone().source_indices.clone(), - item.clone(), - ), - item.params.clone(), - scope.type_env.clone(), - fn_scope.locals.clone(), - scope.func_env.clone(), - ) - } else { - body_typed.clone() - }; - Rc::new(TypedItemResult { - item: Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new({ - let mut __result = Vec::new(); - for c in item.children.clone().iter().cloned() { - __result - .push(infer_item(c.clone(), scope.clone()).item.clone()); - } - __result - }), - params: item.params.clone(), - inferred: inferred_ret.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: item.uses.clone(), - body: Some(annotated_body.clone()), - connective: Connective::NoConnective, - transport: typed_transport.clone(), - properties: typed_properties.clone(), - type_annotation: typed_anno.clone(), - is_self_recursive: is_recursive.clone(), - has_non_tail_self_call: expr_has_non_tail_self_call( - body_typed.clone(), - authored_name_at( - scope.type_env.clone().source_indices.clone(), - item.clone(), - ), - true, - scope.type_env.clone().source_indices.clone(), - ), - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - diagnostics: v1_rt::concat( - v1_rt::concat(transport_diags.clone(), props_diags.clone()), - v1_rt::concat(body_diags.clone(), return_conformance_diags.clone()), - ), - }) - } - } else { - if (((item.body.clone() != None) && ((item.params.clone().len() as i64) == 0)) - && (item.inferred.clone() != None)) - { - { - let fn_decl_name = authored_name_at( - scope.type_env.clone().source_indices.clone(), - item.clone(), - ); - let fn_scope = Rc::new(InferScope { - type_env: scope.type_env.clone(), - func_env: scope.func_env.clone(), - locals: scope.locals.clone(), - body_locals: scope.body_locals.clone(), - match_bound_names: scope.match_bound_names.clone(), - module_name: scope.module_name.clone(), - service_registry: scope.service_registry.clone(), - item_registry: scope.item_registry.clone(), - caller_decl_name: fn_decl_name.clone(), - lambda_param_provenance: scope.lambda_param_provenance.clone(), - }); - let body_result = infer_expr( - item.body.clone().clone().unwrap(), - fn_scope.clone(), - Some(resolved_type(item.clone())), - ); - let body_typed = body_result.typed.clone(); - let body_diags = v1_rt::concat( - body_result.diagnostics.clone(), - v1_rt::concat( - declared_type_conformance_diags( - declared_return_type_node(item.clone()), - resolved_type(body_typed.clone()), - item.body.clone().clone().unwrap().span.clone(), - scope.clone(), - ), - explicit_return_conformance_diags( - declared_return_type_node(item.clone()), - body_typed.clone(), - scope.clone(), - ), - ), - ); - Rc::new(TypedItemResult { - item: Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new(vec![]), - params: Rc::new(vec![]), - inferred: item.inferred.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: Some(body_typed.clone()), - connective: Connective::NoConnective, - transport: typed_transport.clone(), - properties: typed_properties.clone(), - type_annotation: typed_anno.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - diagnostics: v1_rt::concat( - v1_rt::concat(transport_diags.clone(), props_diags.clone()), - body_diags.clone(), - ), - }) - } - } else { - if ((item.body.clone() != None) && ((item.params.clone().len() as i64) == 0)) { - { - let data_expected = if (item.type_annotation.clone() != None) { - Some(item.type_annotation.clone().clone().unwrap()) - } else { - None - }; - let val_result = infer_expr( - item.body.clone().clone().unwrap(), - scope.clone(), - data_expected.clone(), - ); - let val_typed = val_result.typed.clone(); - let val_diags = if (item.type_annotation.clone() != None) { - v1_rt::concat( - val_result.diagnostics.clone(), - declared_type_conformance_diags( - item.type_annotation.clone().clone().unwrap(), - resolved_type(val_typed.clone()), - item.body.clone().clone().unwrap().span.clone(), - scope.clone(), - ), - ) - } else { - val_result.diagnostics.clone() - }; - let inferred_ret = if (item.type_annotation.clone() != None) { - Some(Rc::new(InferredNode::Resolved { - node: item.type_annotation.clone().clone().unwrap(), - })) - } else { - val_typed.inferred.clone() - }; - Rc::new(TypedItemResult { - item: Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new(vec![]), - params: Rc::new(vec![]), - inferred: inferred_ret.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: Some(val_typed.clone()), - connective: Connective::NoConnective, - transport: typed_transport.clone(), - properties: typed_properties.clone(), - type_annotation: typed_anno.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - diagnostics: v1_rt::concat( - v1_rt::concat(transport_diags.clone(), props_diags.clone()), - val_diags.clone(), - ), - }) - } - } else { - if (((item.params.clone().len() as i64) > 0) && (item.body.clone() == None)) - { - Rc::new(TypedItemResult { - item: Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new({ - let mut __result = Vec::new(); - for c in item.children.clone().iter().cloned() { - __result.push( - infer_item(c.clone(), scope.clone()).item.clone(), - ); - } - __result - }), - params: item.params.clone(), - inferred: if (item.inferred.clone() != None) { - item.inferred.clone() - } else { - Some(Rc::new(InferredNode::Resolved { node: unit_type() })) - }, - return_cardinality: item.return_cardinality.clone(), - uses: item.uses.clone(), - body: None, - connective: Connective::NoConnective, - transport: typed_transport.clone(), - properties: typed_properties.clone(), - type_annotation: typed_anno.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - diagnostics: v1_rt::concat( - transport_diags.clone(), - props_diags.clone(), - ), - }) - } else { - Rc::new(TypedItemResult { - item: Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new({ - let mut __result = Vec::new(); - for c in item.children.clone().iter().cloned() { - __result.push( - infer_item(c.clone(), scope.clone()).item.clone(), - ); - } - __result - }), - params: item.params.clone(), - inferred: if (item.inferred.clone() != None) { - item.inferred.clone() - } else { - Some(Rc::new(InferredNode::Resolved { node: unit_type() })) - }, - return_cardinality: item.return_cardinality.clone(), - uses: item.uses.clone(), - body: None, - connective: item.connective.clone(), - transport: typed_transport.clone(), - properties: typed_properties.clone(), - type_annotation: typed_anno.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - diagnostics: v1_rt::concat( - transport_diags.clone(), - props_diags.clone(), - ), - }) - } - } - } - } - } - }) -} - -pub fn infer_items( - items: Rc>>, - scope: Rc, -) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for item in items.clone().iter().cloned() { - __result.push(infer_item(item.clone(), scope.clone())); - } - __result - }) -} - -pub fn is_type_variable_name(name: String) -> bool { - (((((name.clone() == "T".to_string()) || (name.clone() == "K".to_string())) - || (name.clone() == "V".to_string())) - || (name.clone() == "MappedElement".to_string())) - || (name.clone() == "FoldAccumulator".to_string())) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ArgGenericFoldState { - pub results: Rc>>, - pub subst: Rc>>, -} - -pub fn type_node_label( - n: Rc, - source_indices: Rc>>, -) -> String { - { - let authored = authored_name_at(source_indices.clone(), n.clone()); - if (authored.clone() != "".to_string()) { - authored.clone() - } else { - match n.inferred.clone().as_deref().cloned() { - Some(InferredNode::TypeVariable { id: tv_id, .. }) => tv_id.clone(), - _ => n.name.clone(), - } - } - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct SigParamSplit { - pub value_params: Rc>>, - pub generic_names: Rc>, -} - -pub fn body_shadow_aware_func_sig(scope: Rc, func_name: String) -> Rc { - match v1_rt::map_get(&scope.body_locals.clone(), func_name.clone()) { - Some(_) => Rc::new(FuncSigLookup::FuncSigUnresolved), - None => lookup_func_sig( - scope.func_env.clone(), - scope.type_env.clone(), - func_name.clone(), - ), - } -} - -pub fn split_sig_params( - params: Rc>>, - source_indices: Rc>>, -) -> Rc { - Rc::new(SigParamSplit { - value_params: Rc::new({ - let mut __result = Vec::new(); - for p in params.clone().iter().cloned() { - if !param_is_generic_decl(p.clone(), source_indices.clone()) { - __result.push(p); - } - } - __result - }), - generic_names: Rc::new({ - let mut __result = Vec::new(); - for p in Rc::new({ - let mut __result = Vec::new(); - for p in params.clone().iter().cloned() { - if param_is_generic_decl(p.clone(), source_indices.clone()) { - __result.push(p); - } - } - __result - }) - .iter() - .cloned() - { - __result.push(param_node_name_at(p.clone(), source_indices.clone())); - } - __result - }), - }) -} - -pub fn param_is_generic_decl( - p: Rc, - source_indices: Rc>>, -) -> bool { - { - let pt = param_node_type_expr(p.clone()); - let pname = param_node_name_at(p.clone(), source_indices.clone()); - let tname = type_node_label(pt.clone(), source_indices.clone()); - let type_expr_is_var = match pt.inferred.clone() { - Some(inf) => is_type_variable(inf.clone()), - None => false, - }; - (((((pt.children.clone().len() as i64) == 0) - && (pt.connective.clone() == Connective::NoConnective)) - && (pname.clone() != "".to_string())) - && ((pname.clone() == tname.clone()) - || (type_expr_is_var.clone() && (pname.clone() == pt.name.clone())))) - } -} - -pub fn unify_generics( - mut formal: Rc, - mut actual: Rc, - mut generic_names: Rc>, - mut source_indices: Rc>>, - mut acc: Rc>>, -) -> Rc>> { - loop { - let bind_name = type_node_label(formal.clone(), source_indices.clone()); - let f_bare = (((formal.children.clone().len() as i64) == 0) - && (formal.connective.clone() == Connective::NoConnective)); - if ((f_bare.clone() - || match formal.inferred.clone().as_deref().cloned() { - Some(InferredNode::TypeVariable { id: _, .. }) => true, - _ => false, - }) - && { - let mut __found = false; - for g in generic_names.clone().iter().cloned() { - if (g.clone() == bind_name.clone()) { - __found = true; - break; - } - } - __found - }) - { - match v1_rt::map_get(&acc, bind_name.clone()) { - None => { - break v1_rt::rc_map_insert(acc.clone(), bind_name.clone(), actual.clone()); - } - Some(_) => { - break acc.clone(); - } - } - } else { - if (((formal.children.clone().len() as i64) == 1) - && ((actual.children.clone().len() as i64) == 1)) - { - match formal.children.clone().first().cloned() { - Some(fc) => match actual.children.clone().first().cloned() { - Some(ac) => { - let __tco_0 = fc.clone(); - let __tco_1 = ac.clone(); - formal = __tco_0; - actual = __tco_1; - continue; - } - None => { - break acc.clone(); - } - }, - None => { - break acc.clone(); - } - } - } else { - break acc.clone(); - } - } - } -} - -pub fn should_unify_record_lit_generics( - formal: Rc, - arg_expr: Rc, - generic_names: Rc>, - source_indices: Rc>>, -) -> bool { - match record_lit_expr_optional(arg_expr.clone()) { - None => false, - Some(record_expr) => { - if ((generic_names.clone().len() as i64) == 0) { - false - } else { - if ((formal.children.clone().len() as i64) > 0) { - true - } else { - { - let formal_name = type_node_label(formal.clone(), source_indices.clone()); - let record_name = - type_node_label(record_expr.clone(), source_indices.clone()); - (((formal_name.clone() != "".to_string()) - && (record_name.clone() != "".to_string())) - && (formal_name.clone() == record_name.clone())) - } - } - } - } - } -} - -pub fn unify_record_lit_field_walk( - struct_fields: Rc>>, - record: Rc, - generic_names: Rc>, - scope: Rc, - acc: Rc>>, -) -> Rc>> { - struct_fields.clone().iter().cloned().fold( - acc.clone(), - |st: Rc>>, sf: Rc| { - let field_name = - authored_name_at(scope.type_env.clone().source_indices.clone(), sf.clone()); - match Rc::new({ - let mut __result = Vec::new(); - for fi in record.children.clone().iter().cloned() { - if (field_init_node_name_at( - fi.clone(), - scope.type_env.clone().source_indices.clone(), - ) == field_name.clone()) - { - __result.push(fi); - } - } - __result - }) - .first() - .cloned() - { - Some(fi) => { - let actual_value = field_init_node_value(fi.clone()); - let field_formal = match sf.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => rt.clone(), - _ => field_node_type_expr(sf.clone()), - }; - match record_lit_expr_optional(actual_value.clone()) { - Some(nested_record) => unify_record_lit_generics( - field_formal.clone(), - nested_record.clone(), - generic_names.clone(), - scope.clone(), - st.clone(), - ), - None => unify_generics( - field_formal.clone(), - resolved_type(actual_value.clone()), - generic_names.clone(), - scope.type_env.clone().source_indices.clone(), - st.clone(), - ), - } - } - None => st.clone(), - } - }, - ) -} - -pub fn unify_record_lit_generics( - formal: Rc, - record: Rc, - generic_names: Rc>, - scope: Rc, - acc: Rc>>, -) -> Rc>> { - if ((formal.children.clone().len() as i64) == 0) { - { - let formal_name = type_node_label( - formal.clone(), - scope.type_env.clone().source_indices.clone(), - ); - let is_generic_slot = { - let mut __found = false; - for g in generic_names.clone().iter().cloned() { - if (g.clone() == formal_name.clone()) { - __found = true; - break; - } - } - __found - }; - if is_generic_slot.clone() { - unify_generics( - formal.clone(), - resolved_type(record.clone()), - generic_names.clone(), - scope.type_env.clone().source_indices.clone(), - acc.clone(), - ) - } else { - match record_lit_expr_optional(record.clone()) { - Some(record_lit) => { - let record_type_name = type_node_label( - record_lit.clone(), - scope.type_env.clone().source_indices.clone(), - ); - if ((record_type_name.clone() != "".to_string()) - && (formal_name.clone() == record_type_name.clone())) - { - unify_record_lit_field_walk( - record_lit_expected_fields( - Some(record_type_name.clone()), - scope.clone(), - ), - record_lit.clone(), - generic_names.clone(), - scope.clone(), - acc.clone(), - ) - } else { - unify_generics( - formal.clone(), - resolved_type(record.clone()), - generic_names.clone(), - scope.type_env.clone().source_indices.clone(), - acc.clone(), - ) - } - } - None => unify_generics( - formal.clone(), - resolved_type(record.clone()), - generic_names.clone(), - scope.type_env.clone().source_indices.clone(), - acc.clone(), - ), - } - } - } - } else { - { - let type_name = type_node_label( - formal.clone(), - scope.type_env.clone().source_indices.clone(), - ); - unify_record_lit_field_walk( - record_lit_expected_fields(Some(type_name.clone()), scope.clone()), - record.clone(), - generic_names.clone(), - scope.clone(), - acc.clone(), - ) - } - } -} - -pub fn substitute_generics( - n: Rc, - subst: Rc>>, - source_indices: Rc>>, -) -> Rc { - if v1_rt::map_is_empty(&subst) { - n - } else { - substitute_generics_apply(n, subst.clone(), source_indices.clone()) - } -} - -pub fn substitute_generics_apply( - n: Rc, - subst: Rc>>, - source_indices: Rc>>, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match n.inferred.clone().as_deref().cloned() { - Some(InferredNode::TypeVariable { id: tv_id, .. }) => { - match v1_rt::map_get(&subst, tv_id.clone()) { - Some(c) => c.clone(), - None => n.clone(), - } - } - _ => { - let nm = type_node_label(n.clone(), source_indices.clone()); - let is_bare = ((((n.children.clone().len() as i64) == 0) - && (n.connective.clone() == Connective::NoConnective)) - && ((n.params.clone().len() as i64) == 0)); - if is_bare.clone() { - match v1_rt::map_get(&subst, nm.clone()) { - Some(c) => c.clone(), - None => n.clone(), - } - } else { - { - let new_children = Rc::new({ - let mut __result = Vec::new(); - for c in n.children.clone().iter().cloned() { - __result.push(substitute_generics_apply( - c.clone(), - subst.clone(), - source_indices.clone(), - )); - } - __result - }); - let new_params = Rc::new({ - let mut __result = Vec::new(); - for p in n.params.clone().iter().cloned() { - __result.push(substitute_generics_apply( - p.clone(), - subst.clone(), - source_indices.clone(), - )); - } - __result - }); - let new_inferred = match n.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => { - let new_rt = substitute_generics_apply( - rt.clone(), - subst.clone(), - source_indices.clone(), - ); - if v1_rt::rc_ptr_eq(new_rt.clone(), rt.clone()) { - n.inferred.clone() - } else { - Some(Rc::new(InferredNode::Resolved { - node: new_rt.clone(), - })) - } - } - _ => n.inferred.clone(), - }; - if ((v1_rt::rc_vec_ptr_eq(new_children.clone(), n.children.clone()) - && v1_rt::rc_vec_ptr_eq(new_params.clone(), n.params.clone())) - && (new_inferred.clone() == n.inferred.clone())) - { - n.clone() - } else { - Rc::new(Node { - name: n.name.clone(), - span: n.span.clone(), - ident_span: n.ident_span.clone(), - children: new_children.clone(), - connective: n.connective.clone(), - params: new_params.clone(), - inferred: new_inferred.clone(), - return_cardinality: n.return_cardinality.clone(), - uses: n.uses.clone(), - body: n.body.clone(), - transport: n.transport.clone(), - properties: n.properties.clone(), - type_annotation: n.type_annotation.clone(), - is_self_recursive: n.is_self_recursive.clone(), - has_non_tail_self_call: n.has_non_tail_self_call.clone(), - match_pattern: n.match_pattern.clone(), - expr_data: n.expr_data.clone(), - ident: None, - }) - } - } - } - } - } - }) -} - -pub fn kernel_span(name: String) -> Rc { - Rc::new(SourceSpan { - file: v1_rt::concat( - v1_rt::concat("".to_string(), - ), - start: 0, - end: v1_rt::string_length(&name), - }) -} - -pub fn deps_excluding_leaf_self( - b: Rc, - source_indices: Rc>>, -) -> Rc> { - { - let deps0 = node_type_deps(b.resolved.clone(), source_indices.clone()); - let is_bare_self = ((((b.resolved.clone().connective.clone() - == Connective::NoConnective) - && ((b.resolved.clone().children.clone().len() as i64) == 0)) - && ((deps0.clone().len() as i64) == 1)) - && { - let mut __found = false; - for d in deps0.clone().iter().cloned() { - if (d.clone() == b.name.clone()) { - __found = true; - break; - } - } - __found - }); - if is_bare_self.clone() { - Rc::new(vec![]) - } else { - deps0.clone() - } - } -} - -pub fn compiler_recursive_name_set() -> Rc> { - Rc::new(v1_rt::map_keys(&compiler_recursive_types())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert(acc, name.clone(), true) - }, - ) -} - -pub fn type_env_cache_from_bindings( - bindings: Rc>>, - source_indices: Rc>>, - cycle_set_str: Rc>, -) -> Rc { - { - let str_bindings = Rc::new(v1_rt::map_values(&bindings)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, b: Rc| { - v1_rt::rc_map_insert(acc, b.name.clone(), b.clone()) - }, - ); - let deps_map = Rc::new(v1_rt::map_values(&bindings)).iter().cloned().fold( - v1_rt::rc_empty_map::>>(), - |acc: Rc>>>, b: Rc| { - v1_rt::rc_map_insert( - acc, - b.name.clone(), - deps_excluding_leaf_self(b.clone(), source_indices.clone()), - ) - }, - ); - Rc::new(TypeEnvCache { - deps_map: deps_map.clone(), - str_bindings: str_bindings.clone(), - cycle_set_str: cycle_set_str.clone(), - variant_locals: v1_rt::rc_empty_map::>(), - }) - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ParentCacheRow { - pub import_path: String, - pub cache: Rc, -} - -pub fn union_parent_type_env_caches( - resolved_imports: Rc>>, - parent_index: Rc>>, -) -> Rc { - { - let parent_caches = Rc::new({ - let mut __result = Vec::new(); - for imp in resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(parent) => Rc::new(vec![Rc::new(ParentCacheRow { - import_path: imp.module_path.clone(), - cache: parent.interface.clone().cache.clone(), - })]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - match parent_caches.clone().first().cloned() { - None => Rc::new(GuardedTypeEnvCacheMerge { - cache: empty_type_env_cache(), - conflicts: Rc::new(vec![]), - }), - Some(head) => Rc::new( - parent_caches - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - Rc::new(GuardedTypeEnvCacheMerge { - cache: head.cache.clone(), - conflicts: Rc::new(vec![]), - }), - |acc: Rc, row: Rc| { - merge_type_env_cache_guarded( - acc.cache.clone(), - row.cache.clone(), - row.import_path.clone(), - acc.conflicts.clone(), - ) - }, - ), - } - } -} - -pub fn kernel_coproduct_variant_locals(env: Rc) -> Rc>> { - match env.parents.clone().last().cloned() { - Some(kernel) => Rc::new({ - let mut __sorted: Vec<_> = Rc::new(v1_rt::map_values(&kernel.bindings.clone())) - .iter() - .cloned() - .collect(); - __sorted.sort_by(|a: &Rc, b: &Rc| { - let __ka = (|b: Rc| b.name.clone())(a.clone()); - let __kb = (|b: Rc| b.name.clone())(b.clone()); - __ka.partial_cmp(&__kb).unwrap_or(std::cmp::Ordering::Equal) - }); - __sorted - }) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, binding: Rc| { - let is_coproduct = - (binding.resolved.clone().connective.clone() == Connective::Disj); - if is_coproduct.clone() { - binding - .resolved - .clone() - .children - .clone() - .iter() - .cloned() - .fold( - acc.clone(), - |vacc: Rc>>, child: Rc| { - let child_name = - authored_name_at(env.source_indices.clone(), child.clone()); - match v1_rt::map_get(&vacc, child_name.clone()) { - Some(_prev) => vacc.clone(), - None => v1_rt::rc_map_insert( - vacc.clone(), - child_name.clone(), - Rc::new(TypeBinding { - name: child_name.clone(), - resolved: binding.resolved.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ), - } - }, - ) - } else { - acc.clone() - } - }, - ), - None => v1_rt::rc_empty_map::>(), - } -} - -pub fn merge_kernel_variant_locals_low_priority( - env: Rc, - locals: Rc>>, -) -> Rc>> { - { - let kernel_locals = kernel_coproduct_variant_locals(env.clone()); - Rc::new(v1_rt::map_keys(&kernel_locals)) - .iter() - .cloned() - .fold( - locals.clone(), - |acc: Rc>>, variant_name: String| { - match v1_rt::map_get(&acc, variant_name.clone()) { - Some(_) => acc.clone(), - None => match v1_rt::map_get(&kernel_locals, variant_name.clone()) { - Some(binding) => v1_rt::rc_map_insert( - acc.clone(), - variant_name.clone(), - binding.clone(), - ), - None => acc.clone(), - }, - } - }, - ) - } -} - -pub fn type_env_for_import(module_path: String, parent_env: Rc) -> Rc { - if (module_path.clone() == "std.types".to_string()) { - { - let filtered = Rc::new(v1_rt::map_keys(&parent_env.bindings.clone())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, ident: i64| { - let name = intern_str(parent_env.intern_table.clone(), ident.clone()); - if is_type_variable_name(name.clone()) { - acc.clone() - } else { - match v1_rt::map_get(&parent_env.bindings.clone(), ident.clone()) { - Some(binding) => v1_rt::rc_map_insert( - acc.clone(), - ident.clone(), - binding.clone(), - ), - None => acc.clone(), - } - } - }, - ); - let filtered_str = Rc::new(v1_rt::map_keys(&parent_env.str_bindings.clone())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| { - if is_type_variable_name(name.clone()) { - acc.clone() - } else { - match v1_rt::map_get(&parent_env.str_bindings.clone(), name.clone()) { - Some(binding) => { - v1_rt::rc_map_insert(acc.clone(), name.clone(), binding.clone()) - } - None => acc.clone(), - } - } - }, - ); - let filtered_ancestry = - Rc::new(v1_rt::map_keys(&parent_env.ancestry_str_bindings.clone())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| { - if is_type_variable_name(name.clone()) { - acc.clone() - } else { - match v1_rt::map_get( - &parent_env.ancestry_str_bindings.clone(), - name.clone(), - ) { - Some(binding) => v1_rt::rc_map_insert( - acc.clone(), - name.clone(), - binding.clone(), - ), - None => acc.clone(), - } - } - }, - ); - Rc::new(TypeEnv { - module_path: module_path.clone(), - bindings: filtered.clone(), - str_bindings: filtered_str.clone(), - ancestry_str_bindings: filtered_ancestry.clone(), - parents: parent_env.parents.clone(), - recursive_types: parent_env.recursive_types.clone(), - recursive_type_set: parent_env.recursive_type_set.clone(), - inductive_fields: parent_env.inductive_fields.clone(), - source_indices: parent_env.source_indices.clone(), - intern_table: parent_env.intern_table.clone(), - source_visible_names: parent_env.source_visible_names.clone(), - symbol_index: parent_env.symbol_index.clone(), - }) - } - } else { - parent_env.clone() - } -} - -pub fn interface_env_for_import_note() -> String { - thread_local! { - static CACHED: String = { - "Interface-grain scope parent (S2a move 2 increment B, resolver-graph-major-design.md 7): a dependent's typecheck may read exactly its direct import's exported surface - str_bindings, the flattened ancestry maps, the MERGED inductive_fields/recursive sets (each inductively carries the parent's own ancestry, so one level suffices) - and never the parent's parent-chain env OBJECTS. parents: [] cuts the whole-ancestry retention (the measured ~16.3MiB/module residency class) while every chain consumer stays satisfied: phantom-variant and paramless-generic retries read direct parents' str_bindings (carried), inductive_fields_for reads the merged fields (carried), and the kernel stays the dependent's own last scope parent. Discriminating receipt: transitive_interface_binding_test (green arm = a C-declared record projected through B's exported signature still typechecks in A; red control = a bogus field on the same transitive record still errors).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn interface_env_for_import(module_path: String, parent_env: Rc) -> Rc { - { - let filtered = type_env_for_import(module_path.clone(), parent_env.clone()); - Rc::new(TypeEnv { - module_path: module_path.clone(), - bindings: filtered.bindings.clone(), - str_bindings: filtered.str_bindings.clone(), - ancestry_str_bindings: filtered.ancestry_str_bindings.clone(), - parents: Rc::new(vec![]), - recursive_types: filtered.recursive_types.clone(), - recursive_type_set: filtered.recursive_type_set.clone(), - inductive_fields: filtered.inductive_fields.clone(), - source_indices: filtered.source_indices.clone(), - intern_table: filtered.intern_table.clone(), - source_visible_names: filtered.source_visible_names.clone(), - symbol_index: filtered.symbol_index.clone(), - }) - } -} - -pub fn interface_summary_consumer_note() -> String { - thread_local! { - static CACHED: String = { - "S2a move 2 increment B (resolver-graph-major-design.md §7): build_type_env reads a direct import's ModuleInterface (std.interface_summary carrier + interface-grain env/cache realization) — never the parent's full TypeEnv+TypeEnvCache chains. interface.env is the export surface with parents: [] (ancestry-complete via flattened str_bindings/ancestry maps and merged inductive/recursive sets); interface.cache is the flattened import-union grain (variant_locals stripped — interpretation-local). Consumption still runs interface_env_for_import for importer-specific std.types filtering. Discriminating receipt: transitive_interface_binding_test.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn interface_signature_fingerprint_v0_note() -> String { - thread_local! { - static CACHED: String = { - "Interim v0 export signature fingerprint (export_entry_from_item): name-grain, NOT yet structural type shape. Type/data/service exports fingerprint name + authored_name_at(binding.resolved) under tag v1-interface-sig-v0; fn/func exports fingerprint name + param resolved-type names + return-type authored name under tag v1-interface-fn-sig-v0 (the fn arm landed with the typed-module content key, PR-alpha — before it, fn exports produced NO entry, so a fn-only module's interface_hash was the constant empty rollup and the content key's import term was vacuous; the key's import-term RED control is the discriminating receipt). Two exports whose names and resolved authored-name strings all match still collide even if type STRUCTURE differs; increment-B receipt is binding transitivity (transitive_interface_binding_test), not hash-discriminated deep structure. Structural fingerprint authority: std.interface_summary.interface_summary_v0_dissolution_trigger → export_entry_fingerprint when type-structure hashing lands.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn interface_env_surface(env: Rc) -> Rc { - Rc::new(TypeEnv { - module_path: env.module_path.clone(), - bindings: env.bindings.clone(), - str_bindings: env.str_bindings.clone(), - ancestry_str_bindings: env.ancestry_str_bindings.clone(), - parents: Rc::new(vec![]), - recursive_types: env.recursive_types.clone(), - recursive_type_set: env.recursive_type_set.clone(), - inductive_fields: env.inductive_fields.clone(), - source_indices: env.source_indices.clone(), - intern_table: env.intern_table.clone(), - source_visible_names: env.source_visible_names.clone(), - symbol_index: env.symbol_index.clone(), - }) -} - -pub fn interface_cache_from_module(cache: Rc) -> Rc { - Rc::new(TypeEnvCache { - deps_map: cache.deps_map.clone(), - str_bindings: cache.str_bindings.clone(), - cycle_set_str: cache.cycle_set_str.clone(), - variant_locals: v1_rt::rc_empty_map::>(), - }) -} - -pub fn export_kind_of_item_kind(kind: ItemKind) -> Option { - match kind.clone() { - ItemKind::FnItem => Some(ExportKind::ExportFn), - ItemKind::FuncItem => Some(ExportKind::ExportFn), - ItemKind::TypeItem => Some(ExportKind::ExportType), - ItemKind::DataItem => Some(ExportKind::ExportData), - ItemKind::ServiceItem => Some(ExportKind::ExportService), - ItemKind::OtherItem => None, - } -} - -pub fn fn_signature_fingerprint( - item: Rc, - source_indices: Rc>>, -) -> Rc { - { - let params_acc = item.params.clone().iter().cloned().fold( - content_hash_atom("v1-interface-fn-sig-v0".to_string()), - |acc: Rc, p: Rc| { - content_hash_combine_structural( - acc, - content_hash_atom(resolved_type_name(p.clone(), source_indices.clone())), - ) - }, - ); - match item.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => content_hash_combine_structural( - params_acc.clone(), - content_hash_atom(authored_name_at(source_indices.clone(), rt.clone())), - ), - _ => params_acc.clone(), - } - } -} - -pub fn export_entry_from_item( - item: Rc, - env: Rc, - source_indices: Rc>>, -) -> Option> { - { - let name = authored_name_at(source_indices.clone(), item.clone()); - match export_kind_of_item_kind(item_kind(item.clone())) { - None => None, - Some(kind) => match kind.clone() { - ExportKind::ExportFn => Some(Rc::new(ExportEntry { - name: name.clone(), - kind: kind.clone(), - contract: signature_contract(content_hash_tagged_structural( - "v1-interface-fn-sig-v0".to_string(), - content_hash_combine_structural( - content_hash_atom(name.clone()), - fn_signature_fingerprint(item.clone(), source_indices.clone()), - ), - )), - })), - _ => match v1_rt::map_get(&env.str_bindings.clone(), name.clone()) { - Some(binding) => Some(Rc::new(ExportEntry { - name: name.clone(), - kind: kind.clone(), - contract: signature_contract(content_hash_tagged_structural( - "v1-interface-sig-v0".to_string(), - content_hash_combine_structural( - content_hash_atom(binding.name.clone()), - content_hash_atom(authored_name_at( - source_indices.clone(), - binding.resolved.clone(), - )), - ), - )), - })), - None => None, - }, - }, - } - } -} - -pub fn export_entries_from_module( - module: Rc, - env: Rc, - source_indices: Rc>>, -) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for item in module_items(module.clone()).iter().cloned() { - __result.extend( - (*match export_entry_from_item(item.clone(), env.clone(), source_indices.clone()) { - Some(entry) => Rc::new(vec![entry.clone()]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }) -} - -pub fn build_module_interface( - module_path: String, - module: Rc, - env: Rc, - cache: Rc, - source_indices: Rc>>, -) -> Rc { - { - let exports = - export_entries_from_module(module.clone(), env.clone(), source_indices.clone()); - Rc::new(ModuleInterface { - summary: Rc::new(InterfaceSummary { - module_path: module_path.clone(), - exports: exports.clone(), - interface_hash: interface_summary_rollup(exports.clone()), - }), - env: interface_env_surface(env.clone()), - cache: interface_cache_from_module(cache.clone()), - }) - } -} - -pub fn local_binding_for_item( - item: Rc, - source_indices: Rc>>, -) -> Option> { - if is_namespace_alias_item(item.clone(), source_indices.clone()) { - None - } else { - { - let has_structure = (item.connective.clone() != Connective::NoConnective); - if has_structure.clone() { - { - let type_node = Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: item.children.clone(), - connective: item.connective.clone(), - params: item.params.clone(), - inferred: None, - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: item.properties.clone(), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - Some(Rc::new(TypeBinding { - name: authored_name_at(source_indices.clone(), item.clone()), - resolved: type_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - })) - } - } else { - if ((item.body.clone() != None) && (item.transport.clone() == None)) { - { - let fn_node = Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: item.params.clone(), - inferred: item.inferred.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: item.properties.clone(), - type_annotation: item.type_annotation.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - Some(Rc::new(TypeBinding { - name: authored_name_at(source_indices.clone(), item.clone()), - resolved: fn_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - })) - } - } else { - if (((item.inferred.clone() != None) - && ((item.params.clone().len() as i64) == 0)) - && (item.body.clone() == None)) - { - { - let alias_node = Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: item.inferred.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - Some(Rc::new(TypeBinding { - name: authored_name_at(source_indices.clone(), item.clone()), - resolved: alias_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - })) - } - } else { - if ((item.transport.clone() == None) - && ((item.children.clone().len() as i64) > 0)) - { - { - let ref_node = nominal_ref_node( - authored_name_at(source_indices.clone(), item.clone()), - item.span.clone(), - item.ident_span.clone(), - ); - Some(Rc::new(TypeBinding { - name: authored_name_at(source_indices.clone(), item.clone()), - resolved: ref_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - })) - } - } else { - if (((((item.params.clone().len() as i64) > 0) - && (item.connective.clone() == Connective::NoConnective)) - && (item.body.clone() == None)) - && (item.transport.clone() == None)) - { - { - let bare_node = Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: item.params.clone(), - inferred: item.inferred.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - Some(Rc::new(TypeBinding { - name: authored_name_at( - source_indices.clone(), - item.clone(), - ), - resolved: bare_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - })) - } - } else { - if ((((((item.properties.clone().len() as i64) > 0) - && (item.connective.clone() == Connective::NoConnective)) - && (item.transport.clone() == None)) - && (item.inferred.clone() == None)) - && ((item.params.clone().len() as i64) == 0)) - { - Some(nominal_type_binding(authored_name_at( - source_indices.clone(), - item.clone(), - ))) - } else { - None - } - } - } - } - } - } - } - } -} - -pub fn symbol_index_insert_item( - index: Rc, - module_path: String, - item: Rc, - source_indices: Rc>>, -) -> Rc { - { - let with_decl = if is_namespace_alias_item(item.clone(), source_indices.clone()) { - match namespace_alias_target_path(item.clone(), source_indices.clone()) { - None => index.clone(), - Some(target_path) => { - match symbol_index_lookup(index.clone(), target_path.clone()) { - None => index.clone(), - Some(target_node) => symbol_index_insert_decl( - index.clone(), - module_path.clone(), - namespace_alias_binding_for_target( - item.clone(), - target_node.clone(), - source_indices.clone(), - ), - ), - } - } - } - } else { - match local_binding_for_item(item.clone(), source_indices.clone()) { - None => index.clone(), - Some(binding) => { - symbol_index_insert_decl(index.clone(), module_path.clone(), binding.clone()) - } - } - }; - if ((item.transport.clone() != None) && ((item.children.clone().len() as i64) > 0)) { - symbol_index_insert_service( - with_decl.clone(), - authored_name_at(source_indices.clone(), item.clone()), - module_path.clone(), - item.clone(), - ) - } else { - with_decl.clone() - } - } -} - -pub fn disj_variant_name_count_inc( - counts: Rc>, - name: String, -) -> Rc> { - match v1_rt::map_get(&counts, name.clone()) { - Some(n) => v1_rt::rc_map_insert(counts.clone(), name.clone(), (n.clone() + 1)), - None => v1_rt::rc_map_insert(counts.clone(), name.clone(), 1), - } -} - -pub fn disj_variant_name_counts( - items: Rc>>, - source_indices: Rc>>, -) -> Rc> { - items.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |counts: Rc>, item: Rc| match item.connective.clone() { - Connective::Disj => item.children.clone().iter().cloned().fold( - counts.clone(), - |c: Rc>, child: Rc| { - disj_variant_name_count_inc( - c, - authored_name_at(source_indices.clone(), child.clone()), - ) - }, - ), - _ => counts.clone(), - }, - ) -} - -pub fn census_node_base_note() -> String { - thread_local! { - static CACHED: String = { - "The census reads only the module NODE, so the node list is its true input: one census over two front ends (resolved closures and parse-grade pool fills). ResolvedModule entry points delegate through census_module_nodes.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn census_module_nodes(modules: Rc>>) -> Rc>> { - Rc::new({ - let mut __result = Vec::new(); - for rm in modules.clone().iter().cloned() { - __result.push(rm.module.clone()); - } - __result - }) -} - -pub fn corpus_disj_variant_name_counts_nodes( - module_nodes: Rc>>, - source_indices: Rc>>, -) -> Rc> { - module_nodes.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |counts: Rc>, module_node: Rc| { - module_items(module_node.clone()).iter().cloned().fold( - counts, - |c: Rc>, item: Rc| match item.connective.clone() { - Connective::Disj => item.children.clone().iter().cloned().fold( - c.clone(), - |c2: Rc>, child: Rc| { - disj_variant_name_count_inc( - c2, - authored_name_at(source_indices.clone(), child.clone()), - ) - }, - ), - _ => c.clone(), - }, - ) - }, - ) -} - -pub fn corpus_disj_variant_name_counts( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc> { - corpus_disj_variant_name_counts_nodes( - census_module_nodes(modules.clone()), - source_indices.clone(), - ) -} - -pub fn corpus_item_name_counts_nodes( - module_nodes: Rc>>, - source_indices: Rc>>, -) -> Rc> { - module_nodes.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |counts: Rc>, module_node: Rc| { - module_items(module_node.clone()).iter().cloned().fold( - counts, - |c: Rc>, item: Rc| { - disj_variant_name_count_inc( - c, - authored_name_at(source_indices.clone(), item.clone()), - ) - }, - ) - }, - ) -} - -pub fn corpus_item_name_counts( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc> { - corpus_item_name_counts_nodes(census_module_nodes(modules.clone()), source_indices.clone()) -} - -pub fn symbol_index_insert_unique_disj_variant_aliases( - index: Rc, - module_path: String, - items: Rc>>, - source_indices: Rc>>, - corpus_variant_counts: Rc>, - corpus_item_counts: Rc>, -) -> Rc { - { - let counts = disj_variant_name_counts(items.clone(), source_indices.clone()); - items - .clone() - .iter() - .cloned() - .fold( - index.clone(), - |acc: Rc, item: Rc| match item.connective.clone() { - Connective::Disj => { - let tname = authored_name_at(source_indices.clone(), item.clone()); - item.children.clone().iter().cloned().fold( - acc.clone(), - |a2: Rc, child: Rc| { - let vname = authored_name_at(source_indices.clone(), child.clone()); - let a2_qualified = symbol_index_insert( - a2, - v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat(module_path.clone(), ".".to_string()), - tname.clone(), - ), - ".".to_string(), - ), - vname.clone(), - ), - item.clone(), - ); - match v1_rt::map_get(&counts, vname.clone()) { - Some(1) => { - match v1_rt::map_get(&corpus_variant_counts, vname.clone()) - { - Some(1) => { - if ((v1_rt::map_get( - &corpus_item_counts, - vname.clone(), - ) != None) - || overlay_skips_kernel_name(vname.clone())) - { - symbol_index_insert( - a2_qualified.clone(), - v1_rt::concat( - v1_rt::concat( - module_path.clone(), - ".".to_string(), - ), - vname.clone(), - ), - item.clone(), - ) - } else { - symbol_index_insert_decl( - a2_qualified.clone(), - module_path.clone(), - Rc::new(TypeBinding { - name: vname.clone(), - resolved: item.clone(), - provenance: Rc::new( - SubValueRelation::SubValueUnknown, - ), - }), - ) - } - } - _ => symbol_index_insert( - a2_qualified.clone(), - v1_rt::concat( - v1_rt::concat( - module_path.clone(), - ".".to_string(), - ), - vname.clone(), - ), - item.clone(), - ), - } - } - _ => a2_qualified.clone(), - } - }, - ) - } - _ => acc.clone(), - }, - ) - } -} - -pub fn build_symbol_index_census_raw_nodes( - module_nodes: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let corpus_variant_counts = - corpus_disj_variant_name_counts_nodes(module_nodes.clone(), source_indices.clone()); - let corpus_item_counts = - corpus_item_name_counts_nodes(module_nodes.clone(), source_indices.clone()); - module_nodes.clone().iter().cloned().fold( - empty_symbol_index(), - |index: Rc, module_node: Rc| { - let module_path = authored_name_at(source_indices.clone(), module_node.clone()); - let items = module_items(module_node.clone()); - let with_items = items.clone().iter().cloned().fold( - index, - |acc: Rc, item: Rc| { - symbol_index_insert_item( - acc, - module_path.clone(), - item.clone(), - source_indices.clone(), - ) - }, - ); - symbol_index_insert_unique_disj_variant_aliases( - with_items.clone(), - module_path.clone(), - items.clone(), - source_indices.clone(), - corpus_variant_counts.clone(), - corpus_item_counts.clone(), - ) - }, - ) - } -} - -pub fn build_symbol_index_census_raw( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc { - build_symbol_index_census_raw_nodes( - census_module_nodes(modules.clone()), - source_indices.clone(), - ) -} - -pub fn census_borrowed_sig_resolution_note() -> String { - thread_local! { - static CACHED: String = { - "Borrowed-sig hoist (namespace lane): the census stores raw pre-typecheck fn nodes, so a borrowed generic fn's return leaked bare type-param leaves (T/V/E) and owner-local names into consumers — the local/borrowed asymmetry (locals resolve once per module in resolve_item_types with type params bound as TypeVariables; borrows got the raw node per lookup). Pass 2 resolves each borrowable GENERIC fn signature's return ONCE at census build, in a synthetic env at the OWNER's containment position (module_path = the candidate's declaring module; symbol_index = the completed pass-1 census; type params bound via env_with_type_variable_bindings) — order-independent (resolution reads only the completed raw census, never a partial one), once per decl (never per lookup — the per-lookup variant re-resolved recursive carriers to the depth bound on every call), and staged fail-closed: ANY resolution diagnostic keeps the raw binding, so the consumer-side refusal surface is unchanged (upgraded | raw is a typed frontier, not a widen). Scope: fn sigs with value params (params non-empty; type params may be zero — a NON-generic fn's return can still USE a generic type, e.g. Outcome>, and needs the same owner-position expansion for variant-payload substitution); 0-arg fns and aliases share a census shape (body stripped) and stay raw pending a discriminator.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn census_fn_sig_env( - census: Rc, - module_path: String, - tp_names: Rc>, - source_indices: Rc>>, -) -> Rc { - { - let base = Rc::new(TypeEnv { - module_path: module_path.clone(), - bindings: v1_rt::rc_empty_map::>(), - str_bindings: v1_rt::rc_empty_map::>(), - ancestry_str_bindings: v1_rt::rc_empty_map::>(), - parents: Rc::new(vec![]), - recursive_types: Rc::new(vec![]), - recursive_type_set: v1_rt::rc_empty_map::(), - inductive_fields: v1_rt::rc_empty_map::>>>(), - source_indices: source_indices.clone(), - intern_table: empty_intern_table(), - source_visible_names: v1_rt::rc_empty_map::(), - symbol_index: census.clone(), - }); - env_with_type_variable_bindings(base.clone(), tp_names.clone()) - } -} - -pub fn census_binding_is_borrowable_fn_sig( - binding: Rc, - source_indices: Rc>>, -) -> bool { - { - let node = binding.resolved.clone(); - ((((((node.connective.clone() == Connective::NoConnective) - && ((node.children.clone().len() as i64) == 0)) - && (node.body.clone() == None)) - && (node.transport.clone() == None)) - && (node.inferred.clone() != None)) - && ((node.params.clone().len() as i64) > 0)) - } -} - -pub fn census_qualify_sig_return_binding( - binding: Rc, - module_path: String, - census: Rc, - source_indices: Rc>>, -) -> Rc { - { - let node = binding.resolved.clone(); - let env = census_fn_sig_env( - census.clone(), - module_path.clone(), - Rc::new(vec![]), - source_indices.clone(), - ); - Rc::new(TypeBinding { - name: binding.name.clone(), - resolved: node_with_inferred( - node.clone(), - qualify_borrowed_inferred( - node.inferred.clone(), - module_path.clone(), - env.clone(), - v1_rt::rc_empty_map::(), - ), - ), - provenance: binding.provenance.clone(), - }) - } -} - -pub fn census_upgrade_sig_binding( - binding: Rc, - module_path: String, - census: Rc, - source_indices: Rc>>, - tp_names: Rc>, -) -> Rc { - if ((tp_names.clone().len() as i64) > 0) { - { - let node = binding.resolved.clone(); - match node.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: raw_ret, .. }) => { - let env = census_fn_sig_env( - census.clone(), - module_path.clone(), - tp_names.clone(), - source_indices.clone(), - ); - let ret_result = - resolve_node(raw_ret.clone(), env.clone(), module_path.clone()); - if ((ret_result.diagnostics.clone().len() as i64) == 0) { - { - let preserved = preserve_nominal_brand_on_resolve( - raw_ret.clone(), - ret_result.resolved.clone(), - authored_name_at(source_indices.clone(), raw_ret.clone()), - source_indices.clone(), - ); - Rc::new(TypeBinding { - name: binding.name.clone(), - resolved: node_with_inferred( - node.clone(), - Some(Rc::new(InferredNode::Resolved { - node: preserved.clone(), - })), - ), - provenance: binding.provenance.clone(), - }) - } - } else { - binding.clone() - } - } - _ => binding.clone(), - } - } - } else { - binding.clone() - } -} - -pub fn stamp_field_type_from_decl_params( - field_type: Rc, - serving_decl: Rc, - source_indices: Rc>>, -) -> Rc { - if (((serving_decl.params.clone().len() as i64) == 0) || (field_type.inferred.clone() != None)) - { - field_type.clone() - } else { - { - let is_bare = ((((field_type.children.clone().len() as i64) == 0) - && (field_type.connective.clone() == Connective::NoConnective)) - && ((field_type.params.clone().len() as i64) == 0)); - if is_bare.clone() { - { - let nm = type_node_label(field_type.clone(), source_indices.clone()); - let is_param = Rc::new({ - let mut __result = Vec::new(); - for p in serving_decl.params.clone().iter().cloned() { - __result.push(generic_param_name_at(p.clone(), source_indices.clone())); - } - __result - }) - .iter() - .cloned() - .fold(false, |acc: bool, pn: String| { - (acc || (pn.clone() == nm.clone())) - }); - if is_param.clone() { - node_with_inferred( - field_type.clone(), - Some(Rc::new(InferredNode::TypeVariable { id: nm.clone() })), - ) - } else { - field_type.clone() - } - } - } else { - field_type.clone() - } - } - } -} - -pub fn stamp_type_param_occurrences( - n: Rc, - param_names: Rc>, - source_indices: Rc>>, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - let is_bare = ((((n.children.clone().len() as i64) == 0) - && (n.connective.clone() == Connective::NoConnective)) - && ((n.params.clone().len() as i64) == 0)); - if is_bare.clone() { - if (n.inferred.clone() == None) { - { - let nm = type_node_label(n.clone(), source_indices.clone()); - match v1_rt::map_get(¶m_names, nm.clone()) { - Some(_) => node_with_inferred( - n.clone(), - Some(Rc::new(InferredNode::TypeVariable { id: nm.clone() })), - ), - _ => n.clone(), - } - } - } else { - n.clone() - } - } else { - node_with_children( - n.clone(), - Rc::new({ - let mut __result = Vec::new(); - for c in n.children.clone().iter().cloned() { - __result.push(stamp_type_param_occurrences( - c.clone(), - param_names.clone(), - source_indices.clone(), - )); - } - __result - }), - ) - } - }) -} - -pub fn census_upgrade_type_decl_binding( - binding: Rc, - module_path: String, - census: Rc, - source_indices: Rc>>, -) -> Rc { - { - let node = binding.resolved.clone(); - let param_names = Rc::new({ - let mut __result = Vec::new(); - for p in node.params.clone().iter().cloned() { - __result.push(generic_param_name_at(p.clone(), source_indices.clone())); - } - __result - }); - let excluded = param_names.clone().iter().cloned().fold( - v1_rt::rc_map_insert( - v1_rt::rc_empty_map::(), - binding.name.clone(), - true, - ), - |acc: Rc>, nm: String| { - v1_rt::rc_map_insert(acc, nm.clone(), true) - }, - ); - let env = census_fn_sig_env( - census.clone(), - module_path.clone(), - param_names.clone(), - source_indices.clone(), - ); - Rc::new(TypeBinding { - name: binding.name.clone(), - resolved: qualify_decl_reference_positions( - node.clone(), - module_path.clone(), - env.clone(), - excluded.clone(), - ), - provenance: binding.provenance.clone(), - }) - } -} - -pub fn census_qualify_leaf_binding( - binding: Rc, - module_path: String, - census: Rc, - source_indices: Rc>>, -) -> Rc { - { - let node = binding.resolved.clone(); - let excluded = Rc::new({ - let mut __result = Vec::new(); - for p in node.params.clone().iter().cloned() { - __result.push(generic_param_name_at(p.clone(), source_indices.clone())); - } - __result - }) - .iter() - .cloned() - .fold( - v1_rt::rc_map_insert( - v1_rt::rc_empty_map::(), - binding.name.clone(), - true, - ), - |acc: Rc>, nm: String| { - v1_rt::rc_map_insert(acc, nm.clone(), true) - }, - ); - let env = census_fn_sig_env( - census.clone(), - module_path.clone(), - Rc::new(vec![]), - source_indices.clone(), - ); - Rc::new(TypeBinding { - name: binding.name.clone(), - resolved: node_with_inferred( - node.clone(), - qualify_borrowed_inferred( - node.inferred.clone(), - module_path.clone(), - env.clone(), - excluded.clone(), - ), - ), - provenance: binding.provenance.clone(), - }) - } -} - -pub fn census_upgrade_binding( - binding: Rc, - module_path: String, - census: Rc, - source_indices: Rc>>, -) -> Rc { - if census_binding_is_borrowable_fn_sig(binding.clone(), source_indices.clone()) { - { - let tp_names = fn_type_param_names(binding.resolved.clone(), source_indices.clone()); - if ((tp_names.clone().len() as i64) > 0) { - census_upgrade_sig_binding( - binding.clone(), - module_path.clone(), - census.clone(), - source_indices.clone(), - tp_names.clone(), - ) - } else { - census_qualify_sig_return_binding( - binding.clone(), - module_path.clone(), - census.clone(), - source_indices.clone(), - ) - } - } - } else { - if (binding.resolved.clone().connective.clone() != Connective::NoConnective) { - census_upgrade_type_decl_binding( - binding.clone(), - module_path.clone(), - census.clone(), - source_indices.clone(), - ) - } else { - if (binding.resolved.clone().inferred.clone() != None) { - census_qualify_leaf_binding( - binding.clone(), - module_path.clone(), - census.clone(), - source_indices.clone(), - ) - } else { - binding.clone() - } - } - } -} - -pub fn census_upgrade_type_expr( - raw: Rc, - env: Rc, - module_path: String, - source_indices: Rc>>, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - if ((raw.connective.clone() != Connective::NoConnective) - && ((raw.children.clone().len() as i64) > 0)) - { - { - let fields2 = Rc::new({ - let mut __result = Vec::new(); - for f in raw.children.clone().iter().cloned() { - __result.push(match f.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: ft, .. }) => node_with_inferred( - f.clone(), - Some(Rc::new(InferredNode::Resolved { - node: census_upgrade_type_expr( - ft.clone(), - env.clone(), - module_path.clone(), - source_indices.clone(), - ), - })), - ), - _ => f.clone(), - }); - } - __result - }); - node_with_children(raw.clone(), fields2.clone()) - } - } else { - { - let r = resolve_node(raw.clone(), env.clone(), module_path.clone()); - if ((r.diagnostics.clone().len() as i64) == 0) { - preserve_nominal_brand_on_resolve( - raw.clone(), - r.resolved.clone(), - authored_name_at(source_indices.clone(), raw.clone()), - source_indices.clone(), - ) - } else { - raw.clone() - } - } - } - }) -} - -pub fn census_upgrade_service_item( - item: Rc, - module_path: String, - census: Rc, - source_indices: Rc>>, -) -> Rc { - { - let env = census_fn_sig_env( - census.clone(), - module_path.clone(), - Rc::new(vec![]), - source_indices.clone(), - ); - let ops2 = Rc::new({ - let mut __result = Vec::new(); - for c in item.children.clone().iter().cloned() { - __result.push(match c.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: raw_out, .. }) => node_with_inferred( - c.clone(), - Some(Rc::new(InferredNode::Resolved { - node: census_upgrade_type_expr( - raw_out.clone(), - env.clone(), - module_path.clone(), - source_indices.clone(), - ), - })), - ), - _ => c.clone(), - }); - } - __result - }); - node_with_children(item.clone(), ops2.clone()) - } -} - -pub fn census_with_resolved_fn_sigs( - index: Rc, - source_indices: Rc>>, -) -> Rc { - { - let entry_keys = Rc::new(v1_rt::sorted_map_keys(&index.entries.clone())); - let entries2 = entry_keys.clone().iter().cloned().fold( - index.entries.clone(), - |acc: Rc>>, k: String| match v1_rt::map_get( - &index.entries.clone(), - k.clone(), - ) { - Some(node) => { - let upgraded = census_upgrade_binding( - Rc::new(TypeBinding { - name: qualified_last_segment(k.clone()), - resolved: node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - qualified_all_but_last(k.clone()), - index.clone(), - source_indices.clone(), - ); - if (upgraded.resolved.clone() == node.clone()) { - acc.clone() - } else { - v1_rt::rc_map_insert(acc.clone(), k.clone(), upgraded.resolved.clone()) - } - } - None => acc.clone(), - }, - ); - let bare_keys = Rc::new(v1_rt::sorted_map_keys(&index.global_bare.clone())); - let global2 = bare_keys.clone().iter().cloned().fold( - index.global_bare.clone(), - |acc: Rc>>, k: String| match v1_rt::map_get( - &index.global_bare.clone(), - k.clone(), - ) - .as_deref() - .cloned() - { - Some(GlobalBareLookupState::GlobalBareUniqueBinding { - module_path: mp, - binding: b, - .. - }) => { - let b2 = census_upgrade_binding( - b.clone(), - mp.clone(), - index.clone(), - source_indices.clone(), - ); - if (b2.resolved.clone() == b.resolved.clone()) { - acc.clone() - } else { - v1_rt::rc_map_insert( - acc.clone(), - k.clone(), - Rc::new(GlobalBareLookupState::GlobalBareUniqueBinding { - module_path: mp.clone(), - binding: b2.clone(), - }), - ) - } - } - Some(GlobalBareLookupState::GlobalBareAmbiguousBinding { - candidates: cands, - .. - }) => { - let cands2 = Rc::new({ - let mut __result = Vec::new(); - for c in cands.clone().iter().cloned() { - __result.push(Rc::new(GlobalBareCandidate { - module_path: c.module_path.clone(), - binding: census_upgrade_binding( - c.binding.clone(), - c.module_path.clone(), - index.clone(), - source_indices.clone(), - ), - })); - } - __result - }); - v1_rt::rc_map_insert( - acc.clone(), - k.clone(), - Rc::new(GlobalBareLookupState::GlobalBareAmbiguousBinding { - candidates: cands2.clone(), - }), - ) - } - None => acc.clone(), - }, - ); - let service_keys = Rc::new(v1_rt::sorted_map_keys(&index.services.clone())); - let services2 = service_keys.clone().iter().cloned().fold( - index.services.clone(), - |acc: Rc>>, k: String| match v1_rt::map_get( - &index.services.clone(), - k.clone(), - ) { - Some(sentry) => { - let upgraded = census_upgrade_service_item( - sentry.item.clone(), - sentry.module_path.clone(), - index.clone(), - source_indices.clone(), - ); - if (upgraded.clone() == sentry.item.clone()) { - acc.clone() - } else { - v1_rt::rc_map_insert( - acc.clone(), - k.clone(), - Rc::new(ServiceCensusEntry { - module_path: sentry.module_path.clone(), - item: upgraded.clone(), - }), - ) - } - } - None => acc.clone(), - }, - ); - Rc::new(SymbolIndex { - entries: entries2.clone(), - global_bare: global2.clone(), - services: services2.clone(), - }) - } -} - -pub fn build_symbol_index_census( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let raw = build_symbol_index_census_raw(modules.clone(), source_indices.clone()); - census_with_resolved_fn_sigs(raw.clone(), source_indices.clone()) - } -} - -pub fn census_layering_note() -> String { - thread_local! { - static CACHED: String = { - "Layered census (namespace-resolution-design.md 7.5: fill = whole tree; policy gates lookup, never fill). The closure census is byte-identical to the no-fill build — bare visibility, variant-alias corpus gating, and services stay closure-scoped, so a pool homonym cannot shift what a compiled module's bare names mean (measured on the whole-tree gate: a single whole-pool census vanished bare GET/Persistent/JsonValue across 28 witness rows via the corpus-count gate and unique-to-ambiguous flips). Census-only fill modules are PARSE-GRADE (tokenize + parse, never resolve: fill imports point into the compile closure or another tree view, and resolving fill against a fill-only pool fabricated 797 unresolved-import diagnostics about the view, not the modules) and enter a QUALIFIED-ONLY entries underlay — no bare reach INTO fill is needed because cross-tree references are qualified, the migration direction. The cli_run reconcile additionally underlays each typechecked module's OWN tree-closure bare census (root modules plus import-reached pool modules — gate parity by construction: e.g. dag witnesses' bare LiveTreeDisposition is declared only in v2.std.live_tree but import-reached from the dag tree).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn build_symbol_index_census_nodes( - module_nodes: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let raw = build_symbol_index_census_raw_nodes(module_nodes.clone(), source_indices.clone()); - census_with_resolved_fn_sigs(raw.clone(), source_indices.clone()) - } -} - -pub fn underlay_fill_direction_note() -> String { - thread_local! { - static CACHED: String = { - "Fill composition overlays the CLOSURE onto the shared underlay, never the reverse. Both directions denote the same map (union of key sets, closure wins the intersection); only the cost grain differs — the underlay is a per-index memo, so walking its keys charges every entry O(|whole pool|) for an index that differs by its own closure. Receipt: docs/plans/fill-composition-overlay-direction-receipt.md. Witness: symbol_index_fill_overlay_direction_test.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn symbol_index_with_bare_fill( - closure: Rc, - tree: Rc, -) -> Rc { - { - let global2 = v1_rt::rc_map_merge(tree.global_bare.clone(), closure.global_bare.clone()); - let services2 = v1_rt::rc_map_merge(tree.services.clone(), closure.services.clone()); - Rc::new(SymbolIndex { - entries: closure.entries.clone(), - global_bare: global2.clone(), - services: services2.clone(), - }) - } -} - -pub fn build_symbol_index_qualified_fill( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let raw = modules.clone().iter().cloned().fold( - empty_symbol_index(), - |index: Rc, module_node: Rc| { - let module_path = authored_name_at(source_indices.clone(), module_node.clone()); - let items = module_items(module_node.clone()); - let with_items = items.clone().iter().cloned().fold( - index, - |acc: Rc, item: Rc| match local_binding_for_item( - item.clone(), - source_indices.clone(), - ) { - None => acc.clone(), - Some(binding) => symbol_index_insert( - acc.clone(), - v1_rt::concat( - v1_rt::concat(module_path.clone(), ".".to_string()), - binding.name.clone(), - ), - binding.resolved.clone(), - ), - }, - ); - let counts = disj_variant_name_counts(items.clone(), source_indices.clone()); - items.clone().iter().cloned().fold( - with_items.clone(), - |acc: Rc, item: Rc| match item.connective.clone() { - Connective::Disj => item.children.clone().iter().cloned().fold( - acc.clone(), - |a2: Rc, child: Rc| { - let vname = authored_name_at(source_indices.clone(), child.clone()); - match v1_rt::map_get(&counts, vname.clone()) { - Some(1) => symbol_index_insert( - a2.clone(), - v1_rt::concat( - v1_rt::concat(module_path.clone(), ".".to_string()), - vname.clone(), - ), - item.clone(), - ), - _ => a2.clone(), - } - }, - ), - _ => acc.clone(), - }, - ) - }, - ); - census_with_resolved_fn_sigs(raw.clone(), source_indices.clone()) - } -} - -pub fn symbol_index_with_qualified_fill( - closure: Rc, - fill: Rc, -) -> Rc { - { - let entries2 = v1_rt::rc_map_merge(fill.entries.clone(), closure.entries.clone()); - Rc::new(SymbolIndex { - entries: entries2.clone(), - global_bare: closure.global_bare.clone(), - services: closure.services.clone(), - }) - } -} - -pub fn direct_import_export_precedence_note() -> String { - thread_local! { - static CACHED: String = { - "Direct-selected exports beat transitive leaks (2026-07-16, the #6663 x #6686 main-red). The ancestry union folds each direct import's WHOLE flattened cache (its own exports AND everything it inherited), so a later import's transitively-leaked homonym could overlay an earlier import's OWN export that this module's import statement explicitly selects - import v2.std.algebra { Monoid } lost 'Monoid' to dag-root std.algebra riding v2.std.node's ancestry via std.types, and #6663's field-presence wall read the wrong shape at 28 sites. This overlay re-applies, in import order, each direct import's OWN export surface (interface.env.str_bindings - locals only, never its ancestry) restricted to the names the import statement makes visible (specific_names; is_all = the parent's whole local surface, type-variable names filtered per the std.types precedent). Winner semantics: direct-selected vs transitive leak = direct wins (lexical nearest-wins, the containment ruling one hop out - the sanctioned 1c universe is own declarations UNION direct import lists); direct vs direct = unchanged import-order overlay-wins (the ledgered peer-fork ruling, 2026-07-11: later import wins, conflict stays LEDGERED on binding_forks); leak vs leak = unchanged union winner; KERNEL names are never overridden (overlay_skips_kernel_name: kernel_type_set, the container_type_arity names List/Set/Map/Witness, plus Unit/Optional/Present/Absent) - the kernel scope layer stays positionally above imports per the same ruling, because builtin typing (first, skip, string ops) grounds on kernel identities and the v2 substrate models of those concepts (v2.std.collection List=FreeMonoid, Optional; v2.std.text String) are the known dual-representation debt, resolved corpus-wide by kernel-wins today. Full precedence, nearest first: locals > kernel > direct-selected > transitive union. The fork LEDGER is untouched - rows still record every union conflict; this layer only corrects which binding serves lookups. DISSOLVES WHEN namespace Rule-1 lands (containment tree is the naming authority; imports become parse errors) - the union leak itself disappears and this overlay with it. Receipt: direct_import_precedence_over_transitive_leak_test (green arm = selected name resolves the selected module's shape regardless of import order; red control = the field wall still refuses the true shape's missing fields, with that arm's modules placed so the homonym is census-UNAMBIGUOUS by containment (realleaf under the consumer's own parent, leakleaf under a sibling parent) - a census-ambiguous name stands the wall down BY DESIGN (presence_check_census_gate_note), so without that placement the control asserts a diagnostic the gate exists to suppress and silently measures the gate instead of the overlay; ledger arm = the fork row is still recorded).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn overlay_skips_kernel_name(name: String) -> bool { - (((((is_kernel_type(name.clone()) || is_container_type(name.clone())) - || (name.clone() == "Unit".to_string())) - || (name.clone() == "Optional".to_string())) - || (name.clone() == "Present".to_string())) - || (name.clone() == "Absent".to_string())) -} - -pub fn overlay_direct_import_exports( - ancestry_str_bindings: Rc>>, - resolved_imports: Rc>>, - parent_index: Rc>>, -) -> Rc>> { - resolved_imports.clone().iter().cloned().fold( - ancestry_str_bindings.clone(), - |acc: Rc>>, imp: Rc| match v1_rt::map_get( - &parent_index, - imp.module_path.clone(), - ) { - Some(typed_parent) => { - let export_surface = interface_env_for_import( - imp.module_path.clone(), - typed_parent.interface.clone().env.clone(), - ); - let selected = if imp.is_all.clone() { - Rc::new({ - let mut __result = Vec::new(); - for name in Rc::new(v1_rt::map_keys(&export_surface.str_bindings.clone())) - .iter() - .cloned() - { - if (is_type_variable_name(name.clone()) == false) { - __result.push(name); - } - } - __result - }) - } else { - imp.specific_names.clone() - }; - selected.clone().iter().cloned().fold( - acc.clone(), - |bacc: Rc>>, name: String| { - if overlay_skips_kernel_name(name.clone()) { - bacc.clone() - } else { - match v1_rt::map_get(&export_surface.str_bindings.clone(), name.clone()) - { - Some(binding) => v1_rt::rc_map_insert( - bacc.clone(), - name.clone(), - binding.clone(), - ), - None => bacc.clone(), - } - } - }, - ) - } - None => acc.clone(), - }, - ) -} - -pub fn build_type_env( - module: Rc, - parent_index: Rc>>, - source_indices: Rc>>, - intern_table: Rc, - symbol_index: Rc, -) -> Rc { - { - let source_indices = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold( - source_indices.clone(), - |acc: Rc>>, name: String| { - v1_rt::rc_map_insert( - acc, - v1_rt::concat( - v1_rt::concat("".to_string(), - ), - build_newline_index( - v1_rt::concat( - v1_rt::concat("".to_string(), - ), - name.clone(), - ), - ) - }, - ); - let source_indices = Rc::new(vec![ - "Optional".to_string(), - "Present".to_string(), - "Absent".to_string(), - "value".to_string(), - "none".to_string(), - ]) - .iter() - .cloned() - .fold( - source_indices.clone(), - |acc: Rc>>, name: String| { - v1_rt::rc_map_insert( - acc, - v1_rt::concat( - v1_rt::concat("".to_string(), - ), - build_newline_index( - v1_rt::concat( - v1_rt::concat("".to_string(), - ), - name.clone(), - ), - ) - }, - ); - let intern_table = seed_kernel_intern_table(intern_table.clone()); - let kernel_bindings_base = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - Rc::new(TypeBinding { - name: name.clone(), - resolved: Rc::new(Node { - name: name.clone(), - span: kernel_span(name.clone()), - ident_span: Some(kernel_span(name.clone())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - }, - ); - let unit_span = kernel_span("Unit".to_string()); - let kernel_bindings = v1_rt::rc_map_insert( - kernel_bindings_base.clone(), - intern(intern_table.clone(), "Unit".to_string()).id.clone(), - Rc::new(TypeBinding { - name: "Unit".to_string(), - resolved: Rc::new(Node { - name: "Unit".to_string(), - span: unit_span.clone(), - ident_span: Some(unit_span.clone()), - children: Rc::new(vec![]), - connective: Connective::Conj, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ); - let present_value_field = Rc::new(Node { - name: "value".to_string(), - span: kernel_span("value".to_string()), - ident_span: Some(kernel_span("value".to_string())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: Some(Rc::new(InferredNode::TypeVariable { - id: "present_value".to_string(), - })), - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let present_variant = Rc::new(Node { - name: "Present".to_string(), - span: kernel_span("Present".to_string()), - ident_span: Some(kernel_span("Present".to_string())), - children: Rc::new(vec![present_value_field.clone()]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let absent_variant = Rc::new(Node { - name: "Absent".to_string(), - span: kernel_span("Absent".to_string()), - ident_span: Some(kernel_span("Absent".to_string())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let kernel_optional = Rc::new(Node { - name: "Optional".to_string(), - span: kernel_span("Optional".to_string()), - ident_span: Some(kernel_span("Optional".to_string())), - children: Rc::new(vec![present_variant.clone(), absent_variant.clone()]), - connective: Connective::Disj, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let kernel_bindings = v1_rt::rc_map_insert( - kernel_bindings.clone(), - intern(intern_table.clone(), "Optional".to_string()) - .id - .clone(), - Rc::new(TypeBinding { - name: "Optional".to_string(), - resolved: kernel_optional.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ); - let node_fields = inductive_fields_list_to_map(compiler_inductive_fields()); - let kernel_recursive_types = Rc::new({ - let mut __result = Vec::new(); - for name in Rc::new(v1_rt::map_keys(&compiler_recursive_types())) - .iter() - .cloned() - { - __result.push(intern(intern_table.clone(), name.clone()).id.clone()); - } - __result - }); - let kernel_recursive_type_set = Rc::new(v1_rt::map_keys(&compiler_recursive_types())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - true, - ) - }, - ); - let kernel = Rc::new(TypeEnv { - module_path: "".to_string(), - bindings: kernel_bindings.clone(), - str_bindings: str_bindings_from_bindings(kernel_bindings.clone()), - ancestry_str_bindings: v1_rt::rc_empty_map::>(), - parents: Rc::new(vec![]), - recursive_types: kernel_recursive_types.clone(), - recursive_type_set: kernel_recursive_type_set.clone(), - inductive_fields: node_fields.clone(), - source_indices: source_indices.clone(), - intern_table: intern_table.clone(), - source_visible_names: v1_rt::rc_empty_map::(), - symbol_index: empty_symbol_index(), - }); - let module_name_str = authored_name_at(source_indices.clone(), module.module.clone()); - let import_parents = Rc::new({ - let mut __result = Vec::new(); - for imp in module.resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(typed_parent) => Rc::new(vec![interface_env_for_import( - imp.module_path.clone(), - typed_parent.interface.clone().env.clone(), - )]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let scope_parents = v1_rt::concat(import_parents.clone(), Rc::new(vec![kernel.clone()])); - let import_diags = Rc::new({ - let mut __result = Vec::new(); - for imp in module.resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(_) => Rc::new(vec![]), - None => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::InternalError { - message: v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - "missing parent environment for imported module '" - .to_string(), - imp.module_path.clone(), - ), - "' while typechecking '".to_string(), - ), - module_name_str.clone(), - ), - "'".to_string(), - ), - span: imp.target_module.clone().clone().unwrap().span.clone(), - }), - module_name_str.clone(), - )]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let namespace_alias_diags = Rc::new({ - let mut __result = Vec::new(); - for item in module_items(module.module.clone()).iter().cloned() { - __result.extend( - (*if is_namespace_alias_item(item.clone(), source_indices.clone()) { - match namespace_alias_target_path(item.clone(), source_indices.clone()) { - None => Rc::new(vec![]), - Some(target_path) => { - match symbol_index_lookup(symbol_index.clone(), target_path.clone()) - { - Some(_) => Rc::new(vec![]), - None => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::UnresolvedType { - name: target_path.clone(), - span: item.span.clone(), - }), - module_name_str.clone(), - )]), - } - } - } - } else { - Rc::new(vec![]) - }) - .iter() - .cloned(), - ); - } - __result - }); - let local_bindings = module_items(module.module.clone()).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, item: Rc| { - if is_namespace_alias_item(item.clone(), source_indices.clone()) { - match namespace_alias_target_path(item.clone(), source_indices.clone()) { - None => acc.clone(), - Some(target_path) => { - match symbol_index_lookup(symbol_index.clone(), target_path.clone()) { - None => acc.clone(), - Some(target_node) => { - let binding = namespace_alias_binding_for_target( - item.clone(), - target_node.clone(), - source_indices.clone(), - ); - v1_rt::rc_map_insert( - acc.clone(), - intern(intern_table.clone(), binding.name.clone()) - .id - .clone(), - binding.clone(), - ) - } - } - } - } - } else { - match local_binding_for_item(item.clone(), source_indices.clone()) { - Some(binding) => v1_rt::rc_map_insert( - acc.clone(), - intern(intern_table.clone(), binding.name.clone()) - .id - .clone(), - binding.clone(), - ), - None => acc.clone(), - } - } - }, - ); - let param_bindings = module_items(module.module.clone()).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, item: Rc| { - let is_type_decl = match v1_rt::map_get( - &local_bindings, - intern( - intern_table.clone(), - authored_name_at(source_indices.clone(), item.clone()), - ) - .id - .clone(), - ) { - Some(_) => true, - None => false, - }; - if ((((item.params.clone().len() as i64) > 0) && is_type_decl.clone()) - && (item.body.clone() == None)) - { - { - let result = item.params.clone().iter().cloned().fold( - acc.clone(), - |pacc: Rc>>, p: Rc| { - v1_rt::rc_map_insert( - pacc, - intern( - intern_table.clone(), - authored_name_at(source_indices.clone(), p.clone()), - ) - .id - .clone(), - nominal_type_binding(authored_name_at( - source_indices.clone(), - p.clone(), - )), - ) - }, - ); - result.clone() - } - } else { - acc.clone() - } - }, - ); - let local_name_set = Rc::new(v1_rt::map_keys(&local_bindings)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, ident: i64| { - v1_rt::rc_map_insert(acc, ident.clone(), true) - }, - ); - let all_local_bindings = - v1_rt::rc_map_merge(local_bindings.clone(), param_bindings.clone()); - let kernel_cache = type_env_cache_from_bindings( - kernel_bindings.clone(), - source_indices.clone(), - compiler_recursive_name_set(), - ); - let import_union = - union_parent_type_env_caches(module.resolved_imports.clone(), parent_index.clone()); - let import_cache = import_union.cache.clone(); - let binding_forks = import_union.conflicts.clone(); - let ancestry_cache = if ((module.resolved_imports.clone().len() as i64) == 1) { - import_cache.clone() - } else { - merge_type_env_cache(import_cache.clone(), kernel_cache.clone()) - }; - let local_deps_map = Rc::new(v1_rt::map_values(&all_local_bindings)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>>(), - |acc: Rc>>>, b: Rc| { - v1_rt::rc_map_insert( - acc, - b.name.clone(), - deps_excluding_leaf_self(b.clone(), source_indices.clone()), - ) - }, - ); - let local_str_bindings = Rc::new(v1_rt::map_values(&all_local_bindings)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, b: Rc| { - v1_rt::rc_map_insert(acc, b.name.clone(), b.clone()) - }, - ); - let all_deps_map = - v1_rt::rc_map_merge(ancestry_cache.deps_map.clone(), local_deps_map.clone()); - let new_cycle_names = - detect_type_cycles_kahn(all_deps_map.clone(), local_str_bindings.clone()); - let new_cycle_set_str = new_cycle_names.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert(acc, name.clone(), true) - }, - ); - let cycle_set_str = v1_rt::rc_map_merge( - v1_rt::rc_map_merge( - ancestry_cache.cycle_set_str.clone(), - new_cycle_set_str.clone(), - ), - compiler_recursive_name_set(), - ); - let cycle_set = Rc::new({ - let mut __result = Vec::new(); - for name in Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) - .iter() - .cloned() - { - __result.push(intern(intern_table.clone(), name.clone()).id.clone()); - } - __result - }); - let cross_type_set = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - true, - ) - }, - ); - let cycle_set_for_inductive = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) - .iter() - .cloned() - .fold(v1_rt::rc_empty_set::<_>(), |acc: _, name: String| { - v1_rt::rc_set_insert(acc, name.clone()) - }); - let local_inductive_fields = build_item_inductive_fields( - module_items(module.module.clone()), - cycle_set_for_inductive.clone(), - source_indices.clone(), - ); - let parent_inductive_fields = match scope_parents.clone().first().cloned() { - Some(head_parent) => Rc::new( - scope_parents - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - head_parent.inductive_fields.clone(), - |acc: Rc>>>>, parent: Rc| { - merge_inductive_fields(acc, parent.inductive_fields.clone()) - }, - ), - None => v1_rt::rc_empty_map::>>>(), - }; - let merged_inductive_fields = merge_inductive_fields( - parent_inductive_fields.clone(), - local_inductive_fields.clone(), - ); - let ancestry_str_bindings = overlay_direct_import_exports( - ancestry_cache.str_bindings.clone(), - module.resolved_imports.clone(), - parent_index.clone(), - ); - let svn_local = Rc::new(v1_rt::map_keys(&local_str_bindings)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, n: String| { - v1_rt::rc_map_insert(acc, n.clone(), true) - }, - ); - let svn_kernel = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold( - svn_local.clone(), - |acc: Rc>, n: String| { - v1_rt::rc_map_insert(acc, n.clone(), true) - }, - ); - let source_visible_names = module.resolved_imports.clone().iter().cloned().fold( - svn_kernel.clone(), - |acc: Rc>, imp: Rc| { - if imp.is_all.clone() { - match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(parent_mod) => { - let a1 = Rc::new(v1_rt::map_keys( - &parent_mod - .interface - .clone() - .env - .clone() - .str_bindings - .clone(), - )) - .iter() - .cloned() - .fold( - acc.clone(), - |x: Rc>, n: String| { - v1_rt::rc_map_insert(x, n.clone(), true) - }, - ); - Rc::new(v1_rt::map_keys( - &parent_mod - .interface - .clone() - .env - .clone() - .ancestry_str_bindings - .clone(), - )) - .iter() - .cloned() - .fold( - a1.clone(), - |x: Rc>, n: String| { - v1_rt::rc_map_insert(x, n.clone(), true) - }, - ) - } - None => acc.clone(), - } - } else { - imp.specific_names.clone().iter().cloned().fold( - acc.clone(), - |x: Rc>, n: String| { - v1_rt::rc_map_insert(x, n.clone(), true) - }, - ) - } - }, - ); - let unresolved_env = Rc::new(TypeEnv { - module_path: module_name_str.clone(), - bindings: all_local_bindings.clone(), - str_bindings: local_str_bindings.clone(), - ancestry_str_bindings: ancestry_str_bindings.clone(), - parents: scope_parents.clone(), - recursive_types: cycle_set.clone(), - recursive_type_set: cross_type_set.clone(), - inductive_fields: merged_inductive_fields.clone(), - source_indices: source_indices.clone(), - intern_table: intern_table.clone(), - source_visible_names: source_visible_names.clone(), - symbol_index: symbol_index.clone(), - }); - let resolved = resolve_env_bindings( - unresolved_env.clone(), - module_name_str.clone(), - local_name_set.clone(), - all_deps_map.clone(), - ); - let resolved_env_out = resolved.env.clone(); - let resolved_diags = resolved.diagnostics.clone(); - let final_env = Rc::new(TypeEnv { - module_path: module_name_str.clone(), - bindings: resolved_env_out.bindings.clone(), - str_bindings: resolved_env_out.str_bindings.clone(), - ancestry_str_bindings: resolved_env_out.ancestry_str_bindings.clone(), - parents: scope_parents.clone(), - recursive_types: resolved_env_out.recursive_types.clone(), - recursive_type_set: resolved_env_out.recursive_type_set.clone(), - inductive_fields: resolved_env_out.inductive_fields.clone(), - source_indices: resolved_env_out.source_indices.clone(), - intern_table: intern_table.clone(), - source_visible_names: source_visible_names.clone(), - symbol_index: resolved_env_out.symbol_index.clone(), - }); - let cache_str_bindings = v1_rt::rc_map_merge( - final_env.ancestry_str_bindings.clone(), - final_env.str_bindings.clone(), - ); - let type_env_cache = Rc::new(TypeEnvCache { - deps_map: all_deps_map.clone(), - str_bindings: cache_str_bindings.clone(), - cycle_set_str: cycle_set_str.clone(), - variant_locals: v1_rt::rc_empty_map::>(), - }); - Rc::new(BuildTypeEnvResult { - env: final_env.clone(), - cache: type_env_cache.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat(import_diags.clone(), namespace_alias_diags.clone()), - resolved_diags.clone(), - ), - binding_forks: binding_forks.clone(), - }) - } -} - -pub fn build_type_env_unresolved( - module: Rc, - parent_index: Rc>>, - source_indices: Rc>>, - intern_table: Rc, -) -> Rc { - { - let intern_table = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold(intern_table.clone(), |t: Rc, name: String| { - intern(t, name.clone()).table.clone() - }); - let intern_table = Rc::new(vec!["Optional".to_string()]) - .iter() - .cloned() - .fold(intern_table.clone(), |t: Rc, name: String| { - intern(t, name.clone()).table.clone() - }); - let zero_span = no_span(); - let kernel_bindings = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - Rc::new(TypeBinding { - name: name.clone(), - resolved: Rc::new(Node { - name: name.clone(), - span: kernel_span(name.clone()), - ident_span: Some(kernel_span(name.clone())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - }, - ); - let present_value_field = Rc::new(Node { - name: "value".to_string(), - span: kernel_span("value".to_string()), - ident_span: Some(kernel_span("value".to_string())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: Some(Rc::new(InferredNode::TypeVariable { - id: "present_value".to_string(), - })), - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let present_variant = Rc::new(Node { - name: "Present".to_string(), - span: kernel_span("Present".to_string()), - ident_span: Some(kernel_span("Present".to_string())), - children: Rc::new(vec![present_value_field.clone()]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let absent_variant = Rc::new(Node { - name: "Absent".to_string(), - span: kernel_span("Absent".to_string()), - ident_span: Some(kernel_span("Absent".to_string())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let kernel_optional = Rc::new(Node { - name: "Optional".to_string(), - span: kernel_span("Optional".to_string()), - ident_span: Some(kernel_span("Optional".to_string())), - children: Rc::new(vec![present_variant.clone(), absent_variant.clone()]), - connective: Connective::Disj, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let kernel_bindings = v1_rt::rc_map_insert( - kernel_bindings.clone(), - intern(intern_table.clone(), "Optional".to_string()) - .id - .clone(), - Rc::new(TypeBinding { - name: "Optional".to_string(), - resolved: kernel_optional.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ); - let kernel = Rc::new(TypeEnv { - module_path: "".to_string(), - bindings: kernel_bindings.clone(), - str_bindings: str_bindings_from_bindings(kernel_bindings.clone()), - ancestry_str_bindings: v1_rt::rc_empty_map::>(), - parents: Rc::new(vec![]), - recursive_types: Rc::new(vec![]), - recursive_type_set: v1_rt::rc_empty_map::(), - inductive_fields: v1_rt::rc_empty_map::>>>(), - source_indices: source_indices.clone(), - intern_table: intern_table.clone(), - source_visible_names: v1_rt::rc_empty_map::(), - symbol_index: empty_symbol_index(), - }); - let module_name_str = authored_name_at(source_indices.clone(), module.module.clone()); - let import_parents = Rc::new({ - let mut __result = Vec::new(); - for imp in module.resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(typed_parent) => Rc::new(vec![interface_env_for_import( - imp.module_path.clone(), - typed_parent.interface.clone().env.clone(), - )]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let scope_parents = v1_rt::concat(import_parents.clone(), Rc::new(vec![kernel.clone()])); - let local_bindings = module_items(module.module.clone()).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, item: Rc| { - if is_namespace_alias_item(item.clone(), source_indices.clone()) { - acc.clone() - } else { - { - let item_ident = intern( - intern_table.clone(), - authored_name_at(source_indices.clone(), item.clone()), - ) - .id - .clone(); - let has_structure = (item.connective.clone() != Connective::NoConnective); - if has_structure.clone() { - { - let type_node = Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: item.children.clone(), - connective: item.connective.clone(), - params: Rc::new(vec![]), - inferred: None, - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - v1_rt::rc_map_insert( - acc.clone(), - item_ident.clone(), - Rc::new(TypeBinding { - name: authored_name_at( - source_indices.clone(), - item.clone(), - ), - resolved: type_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - } - } else { - if (((item.inferred.clone() != None) - && ((item.params.clone().len() as i64) == 0)) - && (item.body.clone() == None)) - { - { - let alias_node = Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: item.inferred.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - v1_rt::rc_map_insert( - acc.clone(), - item_ident.clone(), - Rc::new(TypeBinding { - name: authored_name_at( - source_indices.clone(), - item.clone(), - ), - resolved: alias_node.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - } - } else { - if ((item.transport.clone() == None) - && ((item.children.clone().len() as i64) > 0)) - { - { - let ref_node = nominal_ref_node( - authored_name_at(source_indices.clone(), item.clone()), - item.span.clone(), - item.ident_span.clone(), - ); - v1_rt::rc_map_insert( - acc.clone(), - item_ident.clone(), - Rc::new(TypeBinding { - name: authored_name_at( - source_indices.clone(), - item.clone(), - ), - resolved: ref_node.clone(), - provenance: Rc::new( - SubValueRelation::SubValueUnknown, - ), - }), - ) - } - } else { - if ((((((item.properties.clone().len() as i64) > 0) - && (item.connective.clone() == Connective::NoConnective)) - && (item.transport.clone() == None)) - && (item.inferred.clone() == None)) - && ((item.params.clone().len() as i64) == 0)) - { - v1_rt::rc_map_insert( - acc.clone(), - item_ident.clone(), - nominal_type_binding(authored_name_at( - source_indices.clone(), - item.clone(), - )), - ) - } else { - acc.clone() - } - } - } - } - } - } - }, - ); - let kernel_cache = type_env_cache_from_bindings( - kernel_bindings.clone(), - source_indices.clone(), - compiler_recursive_name_set(), - ); - let import_cache = - union_parent_type_env_caches(module.resolved_imports.clone(), parent_index.clone()) - .cache - .clone(); - let ancestry_cache = if ((module.resolved_imports.clone().len() as i64) == 1) { - import_cache.clone() - } else { - merge_type_env_cache(import_cache.clone(), kernel_cache.clone()) - }; - let local_deps_map = Rc::new(v1_rt::map_values(&local_bindings)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>>(), - |acc: Rc>>>, b: Rc| { - v1_rt::rc_map_insert( - acc, - b.name.clone(), - deps_excluding_leaf_self(b.clone(), source_indices.clone()), - ) - }, - ); - let local_str_bindings = Rc::new(v1_rt::map_values(&local_bindings)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, b: Rc| { - v1_rt::rc_map_insert(acc, b.name.clone(), b.clone()) - }, - ); - let all_deps_map = - v1_rt::rc_map_merge(ancestry_cache.deps_map.clone(), local_deps_map.clone()); - let new_cycle_names = - detect_type_cycles_kahn(all_deps_map.clone(), local_str_bindings.clone()); - let new_cycle_set_str = new_cycle_names.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert(acc, name.clone(), true) - }, - ); - let cycle_set_str = v1_rt::rc_map_merge( - v1_rt::rc_map_merge( - ancestry_cache.cycle_set_str.clone(), - new_cycle_set_str.clone(), - ), - compiler_recursive_name_set(), - ); - let cycle_set = Rc::new({ - let mut __result = Vec::new(); - for name in Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) - .iter() - .cloned() - { - __result.push(intern(intern_table.clone(), name.clone()).id.clone()); - } - __result - }); - let cross_type_set = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - true, - ) - }, - ); - let cycle_set_for_inductive = Rc::new(v1_rt::sorted_map_keys(&cycle_set_str)) - .iter() - .cloned() - .fold(v1_rt::rc_empty_set::<_>(), |acc: _, name: String| { - v1_rt::rc_set_insert(acc, name.clone()) - }); - let local_inductive_fields = build_item_inductive_fields( - module_items(module.module.clone()), - cycle_set_for_inductive.clone(), - source_indices.clone(), - ); - let parent_inductive_fields = match scope_parents.clone().first().cloned() { - Some(head_parent) => Rc::new( - scope_parents - .clone() - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ) - .iter() - .cloned() - .fold( - head_parent.inductive_fields.clone(), - |acc: Rc>>>>, parent: Rc| { - merge_inductive_fields(acc, parent.inductive_fields.clone()) - }, - ), - None => v1_rt::rc_empty_map::>>>(), - }; - let merged_inductive_fields = merge_inductive_fields( - parent_inductive_fields.clone(), - local_inductive_fields.clone(), - ); - let ancestry_str_bindings = ancestry_cache.str_bindings.clone(); - let visible_str_bindings = - v1_rt::rc_map_merge(ancestry_str_bindings.clone(), local_str_bindings.clone()); - let unresolved_env = Rc::new(TypeEnv { - module_path: module_name_str.clone(), - bindings: local_bindings.clone(), - str_bindings: local_str_bindings.clone(), - ancestry_str_bindings: ancestry_str_bindings.clone(), - parents: scope_parents.clone(), - recursive_types: cycle_set.clone(), - recursive_type_set: cross_type_set.clone(), - inductive_fields: merged_inductive_fields.clone(), - source_indices: source_indices.clone(), - intern_table: intern_table.clone(), - source_visible_names: v1_rt::rc_empty_map::(), - symbol_index: empty_symbol_index(), - }); - let type_env_cache = Rc::new(TypeEnvCache { - deps_map: all_deps_map.clone(), - str_bindings: visible_str_bindings.clone(), - cycle_set_str: cycle_set_str.clone(), - variant_locals: v1_rt::rc_empty_map::>(), - }); - Rc::new(BuildTypeEnvResult { - env: unresolved_env.clone(), - cache: type_env_cache.clone(), - diagnostics: Rc::new(vec![]), - binding_forks: Rc::new(vec![]), - }) - } -} - -pub fn build_item_info( - item: Rc, - source_indices: Rc>>, - module_name: String, -) -> Rc { - { - let kind = item_kind(item.clone()); - let res_names = Rc::new({ - let mut __result = Vec::new(); - for u in item.uses.clone().iter().cloned() { - __result.push(resource_use_name_at(u.clone(), source_indices.clone())); - } - __result - }); - let item_name_str = authored_name_at(source_indices.clone(), item.clone()); - match kind.clone() { - ItemKind::FuncItem => Rc::new(ItemInfo { - name: item_name_str.clone(), - module_name: module_name.clone(), - kind: kind.clone(), - service_names: if (item.body.clone() == None) { - Rc::new(vec![]) - } else { - collect_typed_service_calls( - item.body.clone().clone().unwrap(), - source_indices.clone(), - ) - }, - resource_names: res_names.clone(), - params: item.params.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - }), - ItemKind::FnItem => Rc::new(ItemInfo { - name: item_name_str.clone(), - module_name: module_name.clone(), - kind: kind.clone(), - service_names: if (item.body.clone() == None) { - Rc::new(vec![]) - } else { - collect_typed_service_calls( - item.body.clone().clone().unwrap(), - source_indices.clone(), - ) - }, - resource_names: res_names.clone(), - params: item.params.clone(), - is_self_recursive: if (item.body.clone() == None) { - false - } else { - expr_has_self_call( - item.body.clone().clone().unwrap(), - item_name_str.clone(), - source_indices.clone(), - ) - }, - has_non_tail_self_call: if (item.body.clone() == None) { - false - } else { - expr_has_non_tail_self_call( - item.body.clone().clone().unwrap(), - item_name_str.clone(), - true, - source_indices.clone(), - ) - }, - }), - _ => Rc::new(ItemInfo { - name: item_name_str.clone(), - module_name: module_name.clone(), - kind: kind.clone(), - service_names: Rc::new(vec![]), - resource_names: res_names.clone(), - params: item.params.clone(), - is_self_recursive: false, - has_non_tail_self_call: false, - }), - } - } -} - -pub fn analyze_item(item: Rc, env: Rc, module_name: String) -> Rc { - { - let resolved = resolve_item_types(item.clone(), env.clone(), module_name.clone()); - let ritem = resolved.item.clone(); - let is_func = ((ritem.params.clone().len() as i64) > 0); - let is_zero_arg_func = ((((ritem.params.clone().len() as i64) == 0) - && (ritem.inferred.clone() != None)) - && (ritem.body.clone() != None)); - let func_sig = if (is_func.clone() || is_zero_arg_func.clone()) { - { - let declared_rt = if (ritem.inferred.clone() != None) { - Some(resolved_type(ritem.clone())) - } else { - None - }; - Some(Rc::new(DeclaredFuncSig { - name: authored_name_at(env.source_indices.clone(), ritem.clone()), - params: ritem.params.clone(), - inferred: declared_rt.clone(), - is_async: ((ritem.uses.clone().len() as i64) > 0), - output_provenance: Rc::new(vec![]), - variant_provenance: v1_rt::rc_empty_map::< - String, - Rc>>>>, - >(), - })) - } - } else { - None - }; - let svc_entries = - if ((ritem.transport.clone() != None) && ((ritem.children.clone().len() as i64) > 0)) { - Rc::new({ - let mut __result = Vec::new(); - for c in ritem.children.clone().iter().cloned() { - __result.push(service_op_entry(c.clone(), env.source_indices.clone())); - } - __result - }) - } else { - Rc::new(vec![]) - }; - let svc_local = - if ((ritem.transport.clone() != None) && ((ritem.children.clone().len() as i64) > 0)) { - { - let root = namespace_root_from_properties( - ritem.properties.clone(), - authored_name_at(env.source_indices.clone(), ritem.clone()), - env.source_indices.clone(), - ); - Some(nominal_type_binding(root.clone())) - } - } else { - None - }; - Rc::new(ItemContribution { - resolved_item: ritem.clone(), - resolve_diagnostics: resolved.diagnostics.clone(), - func_sig: func_sig.clone(), - svc_entries: svc_entries.clone(), - svc_local: svc_local.clone(), - item_info: build_item_info( - ritem.clone(), - env.source_indices.clone(), - module_name.clone(), - ), - }) - } -} - -pub fn fold_module_contributions( - mut remaining: Rc>>, - mut resolved_items: Rc>>, - mut func_sigs: Rc>>, - mut svc_registry: Rc>>>>, - mut svc_locals: Rc>>, - mut item_registry: Rc>>, - mut diag_chunks: Rc>>>>, - mut source_indices: Rc>>, -) -> Rc { - loop { - match remaining.clone().first().cloned() { - None => { - break Rc::new(LocalContributionState { - resolved_items: resolved_items.clone(), - func_sigs: func_sigs.clone(), - svc_registry: svc_registry.clone(), - svc_locals: svc_locals.clone(), - item_registry: item_registry.clone(), - diag_chunks: diag_chunks.clone(), - }); - } - Some(contribution) => { - let next_func_sigs = match contribution.func_sig.clone() { - Some(sig) => { - v1_rt::rc_map_insert(func_sigs.clone(), sig.name.clone(), sig.clone()) - } - None => func_sigs.clone(), - }; - let next_svc_registry = if ((contribution.svc_entries.clone().len() as i64) > 0) { - v1_rt::rc_map_insert( - svc_registry.clone(), - authored_name_at( - source_indices.clone(), - contribution.resolved_item.clone(), - ), - contribution.svc_entries.clone(), - ) - } else { - svc_registry.clone() - }; - let next_svc_locals = match contribution.svc_local.clone() { - Some(binding) => v1_rt::rc_map_insert( - svc_locals.clone(), - binding.name.clone(), - binding.clone(), - ), - None => svc_locals.clone(), - }; - { - let __tco_0 = Rc::new( - remaining - .iter() - .cloned() - .skip(1 as usize) - .collect::>(), - ); - let __tco_1 = - v1_rt::rc_list_push(resolved_items, contribution.resolved_item.clone()); - let __tco_2 = next_func_sigs.clone(); - let __tco_3 = next_svc_registry.clone(); - let __tco_4 = next_svc_locals.clone(); - let __tco_5 = v1_rt::rc_map_insert( - item_registry, - contribution.item_info.clone().name.clone(), - contribution.item_info.clone(), - ); - let __tco_6 = - v1_rt::rc_list_push(diag_chunks, contribution.resolve_diagnostics.clone()); - remaining = __tco_0; - resolved_items = __tco_1; - func_sigs = __tco_2; - svc_registry = __tco_3; - svc_locals = __tco_4; - item_registry = __tco_5; - diag_chunks = __tco_6; - continue; - } - } - } - } -} - -pub fn constructor_binding_authority() -> String { - thread_local! { - static CACHED: String = { - "Constructor-owner ruling (§1c): a module's constructor namespace is FLAT — its own coproduct declarations plus its DIRECT imports' contributions, never transitive ancestry. Each arm name binds to its owning coproduct NODE (the binding edge carries the owner; no name re-lookup, so the owner need not be name-visible). One arm name bound to two DIFFERENT owners in one file = VariantCollision at env construction (the per-file wall); the same declaration reached via two import paths is one owner, not a collision. Kernel coproduct arms (Optional/Witness/...) merge low-priority afterwards, prelude semantics.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn insert_variant_owner_checked( - state: Rc, - arm_name: String, - owner: Rc, - source_indices: Rc>>, - module_name: String, -) -> Rc { - match v1_rt::map_get(&state.locals.clone(), arm_name.clone()) { - Some(prev) => { - let prev_name = authored_name_at(source_indices.clone(), prev.resolved.clone()); - let owner_name = authored_name_at(source_indices.clone(), owner.clone()); - let same_owner = (((prev_name.clone() == owner_name.clone()) - && (prev.resolved.clone().span.clone().file.clone() - == owner.span.clone().file.clone())) - && (prev.resolved.clone().span.clone().start.clone() - == owner.span.clone().start.clone())); - if same_owner.clone() { - state.clone() - } else { - Rc::new(VariantFoldState { - locals: state.locals.clone(), - collision_errors: v1_rt::concat( - state.collision_errors.clone(), - Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::VariantCollision { - variant: arm_name.clone(), - enum1: prev_name.clone(), - enum2: owner_name.clone(), - span: owner.span.clone(), - }), - module_name.clone(), - )]), - ), - }) - } - } - None => Rc::new(VariantFoldState { - locals: v1_rt::rc_map_insert( - state.locals.clone(), - arm_name.clone(), - Rc::new(TypeBinding { - name: arm_name.clone(), - resolved: owner.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ), - collision_errors: state.collision_errors.clone(), - }), - } -} - -pub fn bind_coproduct_item_arms( - state: Rc, - item: Rc, - source_indices: Rc>>, - module_name: String, -) -> Rc { - item.children.clone().iter().cloned().fold( - state.clone(), - |vacc: Rc, child: Rc| { - insert_variant_owner_checked( - vacc, - authored_name_at(source_indices.clone(), child.clone()), - item.clone(), - source_indices.clone(), - module_name.clone(), - ) - }, - ) -} - -pub fn build_local_variants( - items: Rc>>, - source_indices: Rc>>, - module_name: String, - init: Rc, -) -> Rc { - items - .clone() - .iter() - .cloned() - .fold(init.clone(), |acc: Rc, item: Rc| { - let item_is_coproduct = (item.connective.clone() == Connective::Disj); - if item_is_coproduct.clone() { - bind_coproduct_item_arms( - acc.clone(), - item.clone(), - source_indices.clone(), - module_name.clone(), - ) - } else { - acc.clone() - } - }) -} - -pub fn merge_global_bare_variant_locals_cost_note() -> String { - thread_local! { - static CACHED: String = { - "Cost shape (bare-minimum-cost, DESIGN 6): the census-eligible variant-owner pairs depend only on global_bare and the name-census si — whole-closure facts identical for every module — so build_global_bare_variant_locals computes them ONCE per closure in typecheck_with_census_extra and the base map threads down realize_module -> typecheck_module -> build_module_context. The former per-module shape rescanned the whole census and re-inserted every eligible pair into every module's locals: 464 modules x 12,554 census keys = 5.8M iterations and 1.29M persistent-map inserts = 31s of the host_effect_realize entry compile (typecheck-perf investigation, 2026-07-31; PR 7398 landed build_global_bare_variant_locals beside the per-module fold but never wired it). map_merge(base, state.locals) is value-identical to the old fold: overlay wins on collision exactly as the old skip-if-present arm kept state's binding, and the old checked-insert collision arm was unreachable (presence was checked before insert), so the global merge contributed zero collision errors then and now. Fidelity of the hoisted si: authored_name_at reads names identically under the raw closure source_indices and the kernel-augmented env.source_indices (kernel spans compute the same name in both arms; non-kernel misses fall back to node.name in both), and the census owners all live in closure files, so eligibility is unchanged.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn merge_global_bare_variant_locals( - state: Rc, - global_variant_base: Rc>>, -) -> Rc { - Rc::new(VariantFoldState { - locals: v1_rt::rc_map_merge(global_variant_base.clone(), state.locals.clone()), - collision_errors: state.collision_errors.clone(), - }) -} - -pub fn build_global_bare_census( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc>> { - build_symbol_index_census(modules.clone(), source_indices.clone()) - .global_bare - .clone() -} - -pub fn build_global_bare_variant_locals( - global_bare: Rc>>, - source_indices: Rc>>, -) -> Rc>> { - Rc::new(v1_rt::map_keys(&global_bare)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| match v1_rt::map_get( - &global_bare, - name.clone(), - ) - .as_deref() - .cloned() - { - Some(GlobalBareLookupState::GlobalBareUniqueBinding { binding, .. }) => { - let owner = binding.resolved.clone(); - if ((owner.connective.clone() == Connective::Disj) - && has_child_named(owner.clone(), name.clone(), source_indices.clone())) - { - v1_rt::rc_map_insert( - acc.clone(), - name.clone(), - Rc::new(TypeBinding { - name: name.clone(), - resolved: owner.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - } else { - acc.clone() - } - } - _ => acc.clone(), - }, - ) -} - -pub fn reexport_chain_authority() -> String { - thread_local! { - static CACHED: String = { - "A module re-exports its specific-name imports (get_exported_names in v1.compiler.resolve), so `import proxy { B }` where proxy itself imports B is an EXPLICIT import under the §1c ruling — the binder follows the specific-name chain to the defining module's coproduct (the import DAG is acyclic, so the recursion terminates; a chain hop that dead-ends binds nothing and the use site fails closed as UnresolvedType). Glob (is_all) imports bind the target's OWN coproduct arms only — glob re-export pass-through is not modeled here, matching get_exported_names which excludes is_all imports from the export surface.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn empty_variant_export_surface() -> Rc { - Rc::new(VariantExportSurface { - arm_owners: v1_rt::rc_empty_map::>(), - enum_items: v1_rt::rc_empty_map::>(), - }) -} - -pub fn add_coproduct_to_variant_surface( - acc: Rc, - item: Rc, - source_indices: Rc>>, -) -> Rc { - { - let enum_items = v1_rt::rc_map_insert( - acc.enum_items.clone(), - authored_name_at(source_indices.clone(), item.clone()), - item.clone(), - ); - let arm_owners = item.children.clone().iter().cloned().fold( - acc.arm_owners.clone(), - |arms: Rc>>, child: Rc| { - v1_rt::rc_map_insert( - arms, - authored_name_at(source_indices.clone(), child.clone()), - item.clone(), - ) - }, - ); - Rc::new(VariantExportSurface { - arm_owners: arm_owners.clone(), - enum_items: enum_items.clone(), - }) - } -} - -pub fn collect_own_variant_export_surface( - items: Rc>>, - source_indices: Rc>>, -) -> Rc { - items.clone().iter().cloned().fold( - empty_variant_export_surface(), - |acc: Rc, item: Rc| { - let item_is_coproduct = (item.connective.clone() == Connective::Disj); - if item_is_coproduct.clone() { - add_coproduct_to_variant_surface(acc.clone(), item.clone(), source_indices.clone()) - } else { - acc.clone() - } - }, - ) -} - -pub fn merge_name_from_proxy_surface( - acc: Rc, - proxy: Rc, - name: String, -) -> Rc { - { - let with_arm = match v1_rt::map_get(&proxy.arm_owners.clone(), name.clone()) { - Some(owner) => Rc::new(VariantExportSurface { - arm_owners: v1_rt::rc_map_insert( - acc.arm_owners.clone(), - name.clone(), - owner.clone(), - ), - enum_items: acc.enum_items.clone(), - }), - None => acc.clone(), - }; - match v1_rt::map_get(&proxy.enum_items.clone(), name.clone()) { - Some(item) => Rc::new(VariantExportSurface { - arm_owners: with_arm.arm_owners.clone(), - enum_items: v1_rt::rc_map_insert( - with_arm.enum_items.clone(), - name.clone(), - item.clone(), - ), - }), - None => with_arm.clone(), - } - } -} - -pub fn reexport_variant_surface_fragment( - imp: Rc, - surfaces: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let proxy_path = import_module_path_at(imp.clone(), source_indices.clone()); - match v1_rt::map_get(&surfaces, proxy_path.clone()) { - None => empty_variant_export_surface(), - Some(proxy) => import_specific_names_at(imp.clone(), source_indices.clone()) - .iter() - .cloned() - .fold( - empty_variant_export_surface(), - |acc: Rc, name: String| { - merge_name_from_proxy_surface(acc, proxy.clone(), name.clone()) - }, - ), - } - } -} - -pub fn merge_variant_surface_fragments( - acc: Rc, - frag: Rc, -) -> Rc { - Rc::new(VariantExportSurface { - arm_owners: v1_rt::rc_map_merge(acc.arm_owners.clone(), frag.arm_owners.clone()), - enum_items: v1_rt::rc_map_merge(acc.enum_items.clone(), frag.enum_items.clone()), - }) -} - -pub fn build_variant_export_surface( - tm: Rc, - surfaces: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let own = collect_own_variant_export_surface(tm.items.clone(), source_indices.clone()); - let reexports = Rc::new({ - let mut __result = Vec::new(); - for imp in module_imports(tm.module.clone()).iter().cloned() { - if !import_is_all(imp.clone()) { - __result.push(imp); - } - } - __result - }) - .iter() - .cloned() - .fold( - empty_variant_export_surface(), - |acc: Rc, imp: Rc| { - merge_variant_surface_fragments( - acc, - reexport_variant_surface_fragment( - imp.clone(), - surfaces.clone(), - source_indices.clone(), - ), - ) - }, - ); - Rc::new(VariantExportSurface { - arm_owners: v1_rt::rc_map_merge(reexports.arm_owners.clone(), own.arm_owners.clone()), - enum_items: v1_rt::rc_map_merge(reexports.enum_items.clone(), own.enum_items.clone()), - }) - } -} - -pub fn bind_imported_name_from_surface( - state: Rc, - surface: Rc, - name: String, - source_indices: Rc>>, - module_name: String, -) -> Rc { - { - let after_enum = match v1_rt::map_get(&surface.enum_items.clone(), name.clone()) { - Some(item) => bind_coproduct_item_arms( - state.clone(), - item.clone(), - source_indices.clone(), - module_name.clone(), - ), - None => state.clone(), - }; - match v1_rt::map_get(&surface.arm_owners.clone(), name.clone()) { - Some(owner) => insert_variant_owner_checked( - after_enum.clone(), - name.clone(), - owner.clone(), - source_indices.clone(), - module_name.clone(), - ), - None => after_enum.clone(), - } - } -} - -pub fn build_imported_variants( - resolved_imports: Rc>>, - parent_index: Rc>>, - variant_surfaces: Rc>>, - source_indices: Rc>>, - module_name: String, - init: Rc, -) -> Rc { - resolved_imports.clone().iter().cloned().fold( - init.clone(), - |acc: Rc, imp: Rc| { - let with_glob = if imp.is_all.clone() { - { - let source_items = match v1_rt::map_get(&parent_index, imp.module_path.clone()) - { - Some(parent_tm) => parent_tm.items.clone(), - None => Rc::new(vec![]), - }; - source_items.clone().iter().cloned().fold( - acc.clone(), - |iacc: Rc, item: Rc| { - let item_is_coproduct = (item.connective.clone() == Connective::Disj); - if item_is_coproduct.clone() { - bind_coproduct_item_arms( - iacc.clone(), - item.clone(), - source_indices.clone(), - module_name.clone(), - ) - } else { - iacc.clone() - } - }, - ) - } - } else { - acc.clone() - }; - imp.specific_names.clone().iter().cloned().fold( - with_glob.clone(), - |nacc: Rc, name: String| { - let surface = match v1_rt::map_get(&variant_surfaces, imp.module_path.clone()) { - Some(s) => s.clone(), - None => empty_variant_export_surface(), - }; - bind_imported_name_from_surface( - nacc, - surface.clone(), - name.clone(), - source_indices.clone(), - module_name.clone(), - ) - }, - ) - }, - ) -} - -pub fn build_module_context( - contributions: Rc>>, - parent_index: Rc>>, - variant_surfaces: Rc>>, - resolved_imports: Rc>>, - env: Rc, - module_name: String, - global_variant_base: Rc>>, -) -> Rc { - { - let local = fold_module_contributions( - contributions.clone(), - Rc::new(vec![]), - v1_rt::rc_empty_map::>(), - v1_rt::rc_empty_map::>>>(), - v1_rt::rc_empty_map::>(), - v1_rt::rc_empty_map::>(), - Rc::new(vec![]), - env.source_indices.clone(), - ); - let local_variant_fold = build_local_variants( - local.resolved_items.clone(), - env.source_indices.clone(), - module_name.clone(), - Rc::new(VariantFoldState { - locals: v1_rt::rc_empty_map::>(), - collision_errors: Rc::new(vec![]), - }), - ); - let variant_fold = merge_global_bare_variant_locals( - build_imported_variants( - resolved_imports.clone(), - parent_index.clone(), - variant_surfaces.clone(), - env.source_indices.clone(), - module_name.clone(), - local_variant_fold.clone(), - ), - global_variant_base.clone(), - ); - let variant_collision_errors = variant_fold.collision_errors.clone(); - let env_variant_locals = - merge_kernel_variant_locals_low_priority(env.clone(), variant_fold.locals.clone()); - let census_scope = Rc::new(v1_rt::map_keys(&env.symbol_index.clone().services.clone())) - .iter() - .cloned() - .fold( - Rc::new(InferScopeComponents { - svc_registry: v1_rt::rc_empty_map::>>>(), - svc_locals: v1_rt::rc_empty_map::>(), - }), - |acc: Rc, sname: String| match v1_rt::map_get( - &env.symbol_index.clone().services.clone(), - sname.clone(), - ) { - Some(sentry) => { - let sitem = sentry.item.clone(); - let entries = Rc::new({ - let mut __result = Vec::new(); - for c in sitem.children.clone().iter().cloned() { - __result.push(Rc::new(OpEntry { - name: authored_name_at(env.source_indices.clone(), c.clone()), - outputs: inferred_to_outputs( - qualify_borrowed_inferred( - c.inferred.clone(), - sentry.module_path.clone(), - env.clone(), - v1_rt::rc_empty_map::(), - ), - c.span.clone(), - env.source_indices.clone(), - ), - params: c.params.clone(), - })); - } - __result - }); - let root = namespace_root_from_properties( - sitem.properties.clone(), - sname.clone(), - env.source_indices.clone(), - ); - Rc::new(InferScopeComponents { - svc_registry: v1_rt::rc_map_insert( - acc.svc_registry.clone(), - sname.clone(), - entries.clone(), - ), - svc_locals: v1_rt::rc_map_insert( - acc.svc_locals.clone(), - root.clone(), - nominal_type_binding(root.clone()), - ), - }) - } - None => acc.clone(), - }, - ); - let merged_scope = merge_scope_from_imports( - resolved_imports.clone(), - parent_index.clone(), - env.clone(), - v1_rt::rc_map_merge( - census_scope.svc_registry.clone(), - local.svc_registry.clone(), - ), - v1_rt::rc_map_merge(census_scope.svc_locals.clone(), local.svc_locals.clone()), - ); - let parent_envs = Rc::new({ - let mut __result = Vec::new(); - for imp in resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&parent_index, imp.module_path.clone()) { - Some(typed_parent) => Rc::new(vec![typed_parent.func_env.clone()]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let resolve_result = resolve_func_sigs( - local.func_sigs.clone(), - parent_envs.clone(), - local.resolved_items.clone(), - module_name.clone(), - env.source_indices.clone(), - ); - let all_locals = Rc::new(v1_rt::map_values(&merged_scope.svc_locals.clone())) - .iter() - .cloned() - .fold( - env_variant_locals.clone(), - |acc: Rc>>, binding: Rc| { - v1_rt::rc_map_insert(acc, binding.name.clone(), binding.clone()) - }, - ); - Rc::new(ModuleContext { - resolved_items: local.resolved_items.clone(), - func_env: resolve_result.func_env.clone(), - svc_registry: merged_scope.svc_registry.clone(), - locals: all_locals.clone(), - variant_locals: env_variant_locals.clone(), - item_registry: local.item_registry.clone(), - diagnostics: v1_rt::concat( - v1_rt::concat( - Rc::new({ - let mut __result = Vec::new(); - for c in local.diag_chunks.clone().iter().cloned() { - __result.extend((*c.clone()).iter().cloned()); - } - __result - }), - resolve_result.diagnostics.clone(), - ), - variant_collision_errors.clone(), - ), - }) - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct TypecheckModuleResult { - pub typed: Rc, - pub diagnostics: Rc>>, - pub binding_forks: Rc>>, -} - -pub fn typecheck_module( - resolved: Rc, - parent_index: Rc>>, - variant_surfaces: Rc>>, - source_indices: Rc>>, - intern_table: Rc, - symbol_index: Rc, - global_variant_base: Rc>>, -) -> Rc { - { - let env_result = build_type_env( - resolved.clone(), - parent_index.clone(), - source_indices.clone(), - intern_table.clone(), - symbol_index.clone(), - ); - let env = env_result.env.clone(); - let env_cache = env_result.cache.clone(); - let env_diags = env_result.diagnostics.clone(); - let env_errors = Rc::new({ - let mut __result = Vec::new(); - for d in env_diags.clone().iter().cloned() { - if is_error_diagnostic(d.diagnostic.clone()) { - __result.push(d); - } - } - __result - }); - let seed_diags = builtin_kernel_seed_diagnostics(); - if ((env_errors.clone().len() as i64) > 0) { - return Rc::new(TypecheckModuleResult { - typed: Rc::new(TypedModule { - module: resolved.module.clone(), - items: Rc::new(vec![]), - type_env: env.clone(), - type_env_cache: env_cache.clone(), - interface: build_module_interface( - authored_name_at(source_indices.clone(), resolved.module.clone()), - resolved.module.clone(), - env.clone(), - env_cache.clone(), - source_indices.clone(), - ), - func_env: Rc::new(ResolvedFuncEnv { - name: authored_name_at(source_indices.clone(), resolved.module.clone()), - local: v1_rt::rc_empty_map::>(), - parents: Rc::new(vec![]), - }), - item_registry: v1_rt::rc_empty_map::>(), - occurrence_transport: Some(resolved.occurrence_transport.clone()), - }), - diagnostics: v1_rt::concat(env_diags.clone(), seed_diags.clone()), - binding_forks: env_result.binding_forks.clone(), - }); - } - let resolved_module_name = - authored_name_at(source_indices.clone(), resolved.module.clone()); - let contributions = Rc::new({ - let mut __result = Vec::new(); - for item in module_items(resolved.module.clone()).iter().cloned() { - __result.push(analyze_item( - item.clone(), - env.clone(), - resolved_module_name.clone(), - )); - } - __result - }); - let ctx = build_module_context( - contributions.clone(), - parent_index.clone(), - variant_surfaces.clone(), - resolved.resolved_imports.clone(), - env.clone(), - resolved_module_name.clone(), - global_variant_base.clone(), - ); - let data_locals = ctx.resolved_items.clone().iter().cloned().fold( - ctx.locals.clone(), - |acc: Rc>>, item: Rc| { - if ((((item.body.clone() != None) && ((item.params.clone().len() as i64) == 0)) - && (item.inferred.clone() == None)) - && (item.type_annotation.clone() != None)) - { - v1_rt::rc_map_insert( - acc.clone(), - authored_name_at(source_indices.clone(), item.clone()), - Rc::new(TypeBinding { - name: authored_name_at(source_indices.clone(), item.clone()), - resolved: item.type_annotation.clone().clone().unwrap(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - } else { - acc.clone() - } - }, - ); - let infer_scope = Rc::new(InferScope { - type_env: env.clone(), - func_env: ctx.func_env.clone(), - locals: data_locals.clone(), - body_locals: v1_rt::rc_empty_map::(), - match_bound_names: v1_rt::rc_empty_map::(), - module_name: resolved_module_name.clone(), - service_registry: ctx.svc_registry.clone(), - item_registry: ctx.item_registry.clone(), - caller_decl_name: "".to_string(), - lambda_param_provenance: v1_rt::rc_empty_map::>(), - }); - let typed_item_results = infer_items(ctx.resolved_items.clone(), infer_scope.clone()); - let typed_items = Rc::new({ - let mut __result = Vec::new(); - for tir in typed_item_results.clone().iter().cloned() { - __result.push(tir.item.clone()); - } - __result - }); - let infer_diags = Rc::new({ - let mut __result = Vec::new(); - for tir in typed_item_results.clone().iter().cloned() { - __result.extend((*tir.diagnostics.clone()).iter().cloned()); - } - __result - }); - let updated_func_env = populate_output_provenance( - typed_items.clone(), - ctx.func_env.clone(), - env.clone(), - data_locals.clone(), - ); - let reannotated_items = Rc::new({ - let mut __result = Vec::new(); - for item in typed_items.clone().iter().cloned() { - __result.push( - if (item.is_self_recursive.clone() && (item.body.clone() != None)) { - Rc::new(Node { - name: item.name.clone(), - span: item.span.clone(), - ident_span: item.ident_span.clone(), - children: item.children.clone(), - params: item.params.clone(), - inferred: item.inferred.clone(), - return_cardinality: item.return_cardinality.clone(), - uses: item.uses.clone(), - body: Some(annotate_descent_evidence( - item.body.clone().clone().unwrap(), - authored_name_at(source_indices.clone(), item.clone()), - item.params.clone(), - env.clone(), - data_locals.clone(), - updated_func_env.clone(), - )), - connective: item.connective.clone(), - transport: item.transport.clone(), - properties: item.properties.clone(), - type_annotation: item.type_annotation.clone(), - is_self_recursive: item.is_self_recursive.clone(), - has_non_tail_self_call: item.has_non_tail_self_call.clone(), - match_pattern: item.match_pattern.clone(), - expr_data: item.expr_data.clone(), - ident: None, - }) - } else { - item.clone() - }, - ); - } - __result - }); - let module_type_env_cache = Rc::new(TypeEnvCache { - deps_map: env_cache.deps_map.clone(), - str_bindings: env_cache.str_bindings.clone(), - cycle_set_str: env_cache.cycle_set_str.clone(), - variant_locals: ctx.variant_locals.clone(), - }); - let typed_base = module_node( - resolved_module_name.clone(), - module_imports(resolved.module.clone()), - ctx.resolved_items.clone(), - resolved.module.clone().span.clone(), - ); - let typed_module = Rc::new(Node { - ident_span: resolved.module.clone().ident_span.clone(), - ..(*typed_base.clone()).clone() - }); - Rc::new(TypecheckModuleResult { - typed: Rc::new(TypedModule { - module: typed_module.clone(), - items: reannotated_items.clone(), - type_env: env.clone(), - type_env_cache: module_type_env_cache.clone(), - interface: build_module_interface( - resolved_module_name.clone(), - typed_module.clone(), - env.clone(), - module_type_env_cache.clone(), - source_indices.clone(), - ), - func_env: updated_func_env.clone(), - item_registry: ctx.item_registry.clone(), - occurrence_transport: Some(resolved.occurrence_transport.clone()), - }), - diagnostics: frontier_occurrence_budget_checked( - resolved_module_name.clone(), - resolved.module.clone().span.clone(), - v1_rt::concat( - v1_rt::concat( - v1_rt::concat(env_diags.clone(), ctx.diagnostics.clone()), - infer_diags.clone(), - ), - seed_diags.clone(), - ), - ), - binding_forks: env_result.binding_forks.clone(), - }) - } -} - -pub fn typecheck_module_isolated( - resolved: Rc, - parent_index: Rc>>, - source_indices: Rc>>, - intern_table: Rc, -) -> Rc { - typecheck_module( - resolved.clone(), - parent_index.clone(), - v1_rt::rc_empty_map::>(), - source_indices.clone(), - intern_table.clone(), - empty_symbol_index(), - v1_rt::rc_empty_map::>(), - ) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct EnvResolveResult { - pub env: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BindingResult { - pub binding: Rc, - pub diagnostics: Rc>>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct BindingsAccum { - pub bindings: Rc>>, - pub str_bindings: Rc>>, - pub diagnostics: Rc>>, -} - -pub fn resolve_env_bindings( - env: Rc, - module_name: String, - local_names: Rc>, - deps_map: Rc>>>, -) -> Rc { - { - let remaining = Rc::new({ - let mut __result = Vec::new(); - for b in Rc::new({ - let mut __result = Vec::new(); - for b in Rc::new(v1_rt::map_values(&env.bindings.clone())) - .iter() - .cloned() - { - if v1_rt::map_contains_key( - &local_names, - intern(env.intern_table.clone(), b.name.clone()).id.clone(), - ) { - __result.push(b); - } - } - __result - }) - .iter() - .cloned() - { - __result.push(b.name.clone()); - } - __result - }); - topo_resolve_types( - remaining.clone(), - env.clone(), - module_name.clone(), - Rc::new(vec![]), - local_names.clone(), - deps_map.clone(), - (remaining.clone().len() as i64), - ) - } -} - -pub fn topo_resolve_types( - mut remaining: Rc>, - mut env: Rc, - mut module_name: String, - mut diagnostics: Rc>>, - mut local_names: Rc>, - mut deps_map: Rc>>>, - mut fuel: i64, -) -> Rc { - loop { - if ((remaining.clone().len() as i64) == 0) { - return Rc::new(EnvResolveResult { - env: env.clone(), - diagnostics: diagnostics.clone(), - }); - } - let remaining_set = remaining - .clone() - .iter() - .cloned() - .fold(v1_rt::rc_empty_set::<_>(), |acc: _, name: String| { - v1_rt::rc_set_insert(acc, name.clone()) - }); - let ready = Rc::new({ - let mut __result = Vec::new(); - for name in remaining.clone().iter().cloned() { - if match v1_rt::map_get(&deps_map, name.clone()) { - Some(deps) => { - let mut __all = true; - for dep in deps.clone().iter().cloned() { - if !((((is_kernel_type(dep.clone()) - || (dep.clone() == "None".to_string())) - || (dep.clone() == "".to_string())) - || is_recursive_type_by_name(env.clone(), dep.clone())) - || (v1_rt::set_contains(&remaining_set, dep.clone()) == false)) - { - __all = false; - break; - } - } - __all - } - None => true, - } { - __result.push(name); - } - } - __result - }); - if ((ready.clone().len() as i64) == 0) { - { - let stuck_accum = remaining.clone().iter().cloned().fold( - Rc::new(BindingsAccum { - bindings: env.bindings.clone(), - str_bindings: env.str_bindings.clone(), - diagnostics: Rc::new(vec![]), - }), - |acc: Rc, name: String| { - let ident = intern(env.intern_table.clone(), name.clone()).id.clone(); - match v1_rt::map_get(&env.bindings.clone(), ident.clone()) { - Some(binding) => { - let pre = binding.resolved.clone(); - let result = - resolve_node(pre.clone(), env.clone(), module_name.clone()); - let resolved = preserve_nominal_brand_on_resolve( - pre.clone(), - result.resolved.clone(), - binding.name.clone(), - env.source_indices.clone(), - ); - let updated_binding = Rc::new(TypeBinding { - name: name.clone(), - resolved: resolved.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }); - Rc::new(BindingsAccum { - bindings: v1_rt::rc_map_insert( - acc.bindings.clone(), - ident.clone(), - updated_binding.clone(), - ), - str_bindings: v1_rt::rc_map_insert( - acc.str_bindings.clone(), - name.clone(), - updated_binding.clone(), - ), - diagnostics: v1_rt::concat( - acc.diagnostics.clone(), - result.diagnostics.clone(), - ), - }) - } - None => acc.clone(), - } - }, - ); - return Rc::new(EnvResolveResult { - env: Rc::new(TypeEnv { - module_path: env.module_path.clone(), - bindings: stuck_accum.bindings.clone(), - str_bindings: stuck_accum.str_bindings.clone(), - ancestry_str_bindings: env.ancestry_str_bindings.clone(), - parents: env.parents.clone(), - recursive_types: env.recursive_types.clone(), - recursive_type_set: env.recursive_type_set.clone(), - inductive_fields: env.inductive_fields.clone(), - source_indices: env.source_indices.clone(), - intern_table: env.intern_table.clone(), - source_visible_names: env.source_visible_names.clone(), - symbol_index: env.symbol_index.clone(), - }), - diagnostics: v1_rt::concat( - diagnostics.clone(), - stuck_accum.diagnostics.clone(), - ), - }); - } - } - let ready_accum = ready.clone().iter().cloned().fold( - Rc::new(BindingsAccum { - bindings: env.bindings.clone(), - str_bindings: env.str_bindings.clone(), - diagnostics: Rc::new(vec![]), - }), - |acc: Rc, name: String| { - let ident = intern(env.intern_table.clone(), name.clone()).id.clone(); - match v1_rt::map_get(&env.bindings.clone(), ident.clone()) { - Some(binding) => { - let pre = binding.resolved.clone(); - let result = resolve_node(pre.clone(), env.clone(), module_name.clone()); - let resolved = preserve_nominal_brand_on_resolve( - pre.clone(), - result.resolved.clone(), - binding.name.clone(), - env.source_indices.clone(), - ); - let updated_binding = Rc::new(TypeBinding { - name: name.clone(), - resolved: resolved.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }); - Rc::new(BindingsAccum { - bindings: v1_rt::rc_map_insert( - acc.bindings.clone(), - ident.clone(), - updated_binding.clone(), - ), - str_bindings: v1_rt::rc_map_insert( - acc.str_bindings.clone(), - name.clone(), - updated_binding.clone(), - ), - diagnostics: v1_rt::concat( - acc.diagnostics.clone(), - result.diagnostics.clone(), - ), - }) - } - None => acc.clone(), - } - }, - ); - let ready_set = ready.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert(acc, name.clone(), true) - }, - ); - let next_remaining = Rc::new({ - let mut __result = Vec::new(); - for name in remaining.clone().iter().cloned() { - if (emit_map_has(ready_set.clone(), name.clone()) == false) { - __result.push(name); - } - } - __result - }); - { - let __tco_0 = next_remaining.clone(); - let __tco_1 = Rc::new(TypeEnv { - module_path: env.module_path.clone(), - bindings: ready_accum.bindings.clone(), - str_bindings: ready_accum.str_bindings.clone(), - ancestry_str_bindings: env.ancestry_str_bindings.clone(), - parents: env.parents.clone(), - recursive_types: env.recursive_types.clone(), - recursive_type_set: env.recursive_type_set.clone(), - inductive_fields: env.inductive_fields.clone(), - source_indices: env.source_indices.clone(), - intern_table: env.intern_table.clone(), - source_visible_names: env.source_visible_names.clone(), - symbol_index: env.symbol_index.clone(), - }); - let __tco_2 = v1_rt::concat(diagnostics, ready_accum.diagnostics.clone()); - let __tco_3 = (fuel - 1); - remaining = __tco_0; - env = __tco_1; - diagnostics = __tco_2; - fuel = __tco_3; - continue; - } - } -} - -pub fn collect_parent_envs( - resolved: Rc, - module_index: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let modules = Rc::new({ - let mut __result = Vec::new(); - for imp in resolved.resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&module_index, imp.module_path.clone()) { - Some(typed) => Rc::new(vec![typed.clone()]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let resolved_mod_name = authored_name_at(source_indices.clone(), resolved.module.clone()); - let diagnostics = Rc::new({ - let mut __result = Vec::new(); - for imp in resolved.resolved_imports.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get(&module_index, imp.module_path.clone()) { - Some(_) => Rc::new(vec![]), - None => Rc::new(vec![make_error_node( - Rc::new(CompilerDiagnostic::InternalError { - message: v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - v1_rt::concat( - "missing parent environment for imported module '" - .to_string(), - imp.module_path.clone(), - ), - "' while ordering '".to_string(), - ), - resolved_mod_name.clone(), - ), - "'".to_string(), - ), - span: imp.target_module.clone().clone().unwrap().span.clone(), - }), - resolved_mod_name.clone(), - )]), - }) - .iter() - .cloned(), - ); - } - __result - }); - Rc::new(ParentModulesResult { - modules: modules.clone(), - diagnostics: diagnostics.clone(), - }) - } -} - -pub fn variant_has_positional_payload_shape( - variant: Rc, - source_indices: Rc>>, -) -> bool { - (((variant.children.clone().len() as i64) == 1) - && match variant.children.clone().first().cloned() { - Some(f) => (field_node_name_at(f.clone(), source_indices.clone()) == "0".to_string()), - None => false, - }) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct EnumVariantShapeSets { - pub fielded: Rc>, - pub positional_payload: Rc>, -} - -pub fn enum_variant_shape_sets_for_item( - acc: Rc, - item: Rc, - si: Rc>>, - type_summaries: Rc>>, -) -> Rc { - { - let item_name = authored_name_at(si.clone(), item.clone()); - let is_enum = match v1_rt::map_get(&type_summaries, item_name.clone()) { - Some(summary) => match (*summary.repr.clone()).clone() { - TypeRepr::EnumRepr { unit_only: _, .. } => true, - _ => false, - }, - None => false, - }; - if is_enum.clone() { - item.children.clone().iter().cloned().fold( - acc, - |vacc: Rc, variant: Rc| { - let qualified = v1_rt::concat( - v1_rt::concat(item_name.clone(), "::".to_string()), - authored_name_at(si.clone(), variant.clone()), - ); - let is_positional_payload = - variant_has_positional_payload_shape(variant.clone(), si.clone()); - let has_fields = ((variant.children.clone().len() as i64) > 0); - if is_positional_payload.clone() { - Rc::new(EnumVariantShapeSets { - fielded: vacc.fielded.clone(), - positional_payload: v1_rt::rc_set_insert( - vacc.positional_payload.clone(), - qualified.clone(), - ), - }) - } else { - if has_fields.clone() { - Rc::new(EnumVariantShapeSets { - fielded: v1_rt::rc_set_insert( - vacc.fielded.clone(), - qualified.clone(), - ), - positional_payload: vacc.positional_payload.clone(), - }) - } else { - vacc.clone() - } - } - }, - ) - } else { - acc - } - } -} - -pub fn build_enum_variant_shape_sets( - modules: Rc>>, - type_summaries: Rc>>, -) -> Rc { - modules.clone().iter().cloned().fold( - Rc::new(EnumVariantShapeSets { - fielded: v1_rt::rc_empty_set::(), - positional_payload: v1_rt::rc_empty_set::(), - }), - |acc: Rc, m: Rc| { - m.items.clone().iter().cloned().fold( - acc, - |inner: Rc, item: Rc| { - enum_variant_shape_sets_for_item( - inner, - item.clone(), - m.type_env.clone().source_indices.clone(), - type_summaries.clone(), - ) - }, - ) - }, - ) -} - -pub fn build_emit_graph_info(modules: Rc>>) -> Rc { - { - let init = Rc::new(EmitInfoBuildState { - type_summaries: v1_rt::rc_empty_map::>(), - type_decl_items: v1_rt::rc_empty_map::>(), - fn_decl_items: v1_rt::rc_empty_map::>(), - }); - let built_raw = modules.clone().iter().cloned().fold( - init.clone(), - |state: Rc, typed_module: Rc| { - typed_module.items.clone().iter().cloned().fold( - state, - |inner_state: Rc, item: Rc| { - add_emit_item_summary( - inner_state, - item.clone(), - typed_module.type_env.clone().source_indices.clone(), - ) - }, - ) - }, - ); - let built = Rc::new(EmitInfoBuildState { - type_summaries: close_fn_fields(built_raw.type_summaries.clone()), - type_decl_items: built_raw.type_decl_items.clone(), - fn_decl_items: built_raw.fn_decl_items.clone(), - }); - let all_recursive = modules.clone().iter().cloned().fold( - v1_rt::rc_empty_set::<_>(), - |acc: _, m: Rc| { - Rc::new(v1_rt::map_keys( - &m.type_env.clone().recursive_type_set.clone(), - )) - .iter() - .cloned() - .fold(acc, |inner: _, ident: i64| { - v1_rt::rc_set_insert( - inner, - intern_str(m.type_env.clone().intern_table.clone(), ident.clone()), - ) - }) - }, - ); - let variant_shapes = - build_enum_variant_shape_sets(modules.clone(), built.type_summaries.clone()); - let vtoe = derive_variant_to_enum(built.type_summaries.clone()); - Rc::new(EmitGraphInfo { - type_summaries: built.type_summaries.clone(), - type_decl_items: built.type_decl_items.clone(), - fn_decl_items: built.fn_decl_items.clone(), - recursive_type_set: all_recursive.clone(), - fielded_variants: variant_shapes.fielded.clone(), - positional_payload_variants: variant_shapes.positional_payload.clone(), - shared_types: v1_rt::rc_empty_set::(), - ownership_index: v1_rt::rc_empty_map::>>(), - movable: v1_rt::rc_empty_set::(), - variant_to_enum: vtoe.clone(), - owned_bindings: v1_rt::rc_empty_set::(), - read_only_params_index: v1_rt::rc_empty_map::>>(), - read_only_params: v1_rt::rc_empty_set::(), - clone_bounded_type_params: v1_rt::rc_empty_map::>>(), - map_key_required_type_names: v1_rt::rc_empty_set::(), - clone_impl_required_type_params: v1_rt::rc_empty_map::>>(), - fn_generic_param_names: Rc::new(vec![]), - fn_type_env: empty_type_env(), - fn_return_type: None, - }) - } -} - -pub fn seed_kernel_intern_table(intern_table: Rc) -> Rc { - { - let intern_table = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold(intern_table.clone(), |t: Rc, name: String| { - intern(t, name.clone()).table.clone() - }); - let intern_table = Rc::new(vec![ - "Optional".to_string(), - "Present".to_string(), - "Absent".to_string(), - "value".to_string(), - "none".to_string(), - ]) - .iter() - .cloned() - .fold(intern_table.clone(), |t: Rc, name: String| { - intern(t, name.clone()).table.clone() - }); - Rc::new(v1_rt::map_keys(&compiler_recursive_types())) - .iter() - .cloned() - .fold(intern_table.clone(), |t: Rc, name: String| { - intern(t, name.clone()).table.clone() - }) - } -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct RealizeState { - pub module_index: Rc>>, - pub variant_surfaces: Rc>>, - pub item_registry: Rc>>, - pub diags_by_name: Rc>>>>, -} - -pub fn typecheck( - graph: Rc, - source_indices: Rc>>, - intern_table: Rc, -) -> Rc { - typecheck_with_census_extra( - graph.clone(), - source_indices.clone(), - intern_table.clone(), - Rc::new(vec![]), - source_indices.clone(), - ) -} - -pub fn typecheck_with_census_extra( - graph: Rc, - source_indices: Rc>>, - intern_table: Rc, - census_fill_modules: Rc>>, - census_si: Rc>>, -) -> Rc { - { - let intern_table = seed_kernel_intern_table(intern_table.clone()); - let resolved_by_name = graph.modules.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, rm: Rc| { - v1_rt::rc_map_insert( - acc, - authored_name_at(source_indices.clone(), rm.module.clone()), - rm.clone(), - ) - }, - ); - let symbol_index = symbol_index_with_qualified_fill( - build_symbol_index_census(graph.modules.clone(), census_si.clone()), - build_symbol_index_qualified_fill(census_fill_modules.clone(), census_si.clone()), - ); - let global_variant_base = build_global_bare_variant_locals( - symbol_index.global_bare.clone(), - source_indices.clone(), - ); - let state = graph.modules.clone().iter().cloned().fold( - Rc::new(RealizeState { - module_index: v1_rt::rc_empty_map::>(), - variant_surfaces: v1_rt::rc_empty_map::>(), - item_registry: v1_rt::rc_empty_map::>(), - diags_by_name: v1_rt::rc_empty_map::>>>(), - }), - |st: Rc, rm: Rc| { - realize_module( - authored_name_at(source_indices.clone(), rm.module.clone()), - resolved_by_name.clone(), - st, - source_indices.clone(), - intern_table.clone(), - symbol_index.clone(), - global_variant_base.clone(), - ) - }, - ); - let modules = Rc::new({ - let mut __result = Vec::new(); - for rm in graph.modules.clone().iter().cloned() { - __result.extend( - (*match v1_rt::map_get( - &state.module_index.clone(), - authored_name_at(source_indices.clone(), rm.module.clone()), - ) { - Some(typed) => Rc::new(vec![typed.clone()]), - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }); - let diag_chunks = Rc::new({ - let mut __result = Vec::new(); - for rm in graph.modules.clone().iter().cloned() { - __result.push( - match v1_rt::map_get( - &state.diags_by_name.clone(), - authored_name_at(source_indices.clone(), rm.module.clone()), - ) { - Some(d) => d.clone(), - None => Rc::new(vec![]), - }, - ); - } - __result - }); - let expanded_registry = - expand_transitive_services(modules.clone(), state.item_registry.clone(), 5); - Rc::new(TypedGraph { - modules: modules.clone(), - item_registry: expanded_registry.clone(), - diagnostics: Rc::new({ - let mut __result = Vec::new(); - for c in diag_chunks.clone().iter().cloned() { - __result.extend((*c.clone()).iter().cloned()); - } - __result - }), - }) - } -} - -pub fn realize_module( - name: String, - resolved_by_name: Rc>>, - state: Rc, - source_indices: Rc>>, - intern_table: Rc, - symbol_index: Rc, - global_variant_base: Rc>>, -) -> Rc { - stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { - match v1_rt::map_get(&state.module_index.clone(), name.clone()) { - Some(_) => state, - None => match v1_rt::map_get(&resolved_by_name, name.clone()) { - None => state, - Some(resolved) => { - let dep_state = resolved.resolved_imports.clone().iter().cloned().fold( - state, - |st: Rc, imp: Rc| { - realize_module( - imp.module_path.clone(), - resolved_by_name.clone(), - st, - source_indices.clone(), - intern_table.clone(), - symbol_index.clone(), - global_variant_base.clone(), - ) - }, - ); - let parent_result = collect_parent_envs( - resolved.clone(), - dep_state.module_index.clone(), - source_indices.clone(), - ); - let tc_result = typecheck_module( - resolved.clone(), - dep_state.module_index.clone(), - dep_state.variant_surfaces.clone(), - source_indices.clone(), - intern_table.clone(), - symbol_index.clone(), - global_variant_base.clone(), - ); - let typed = tc_result.typed.clone(); - let typed_path = authored_name_at(source_indices.clone(), typed.module.clone()); - Rc::new(RealizeState { - module_index: v1_rt::rc_map_insert( - dep_state.module_index.clone(), - typed_path.clone(), - typed.clone(), - ), - variant_surfaces: v1_rt::rc_map_insert( - dep_state.variant_surfaces.clone(), - typed_path.clone(), - build_variant_export_surface( - typed.clone(), - dep_state.variant_surfaces.clone(), - source_indices.clone(), - ), - ), - item_registry: v1_rt::rc_map_merge( - dep_state.item_registry.clone(), - typed.item_registry.clone(), - ), - diags_by_name: v1_rt::rc_map_insert( - dep_state.diags_by_name.clone(), - typed_path.clone(), - v1_rt::concat( - parent_result.diagnostics.clone(), - tc_result.diagnostics.clone(), - ), - ), - }) - } - }, - } - }) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct StrBindingsRewireAccum { - pub str_bindings: Rc>>, - pub ancestry_str_bindings: Rc>>, -} - -pub fn import_module_path_at( - imp: Rc, - source_indices: Rc>>, -) -> String { - authored_name_at(source_indices.clone(), imp.clone()) -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ExportIndexModuleAccum { - pub index: Rc>>, - pub seen_names: Rc>, -} - -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct ExportedTypeRelationBuild { - pub by_name: Rc>>, - pub by_module: Rc>>>, -} - -pub fn export_index_canonical_is_the_fold_element_note() -> String { - thread_local! { - static CACHED: String = { - "§6 bare-minimum cost, same receipt as module_exported_type_names_cost_note. The export-index module walk's canonical binding was `filter(bindings |> map_values, b => b.name == name) |> first` — a rescan of the WHOLE binding map (with a fresh Vec allocation) once per distinct name, i.e. O(|bindings|^2) per module per closure assembly. It is dead work by construction: the enclosing fold walks THAT SAME map_values sequence in order, and seen_names skips every repeat, so the first element whose name matches is always the fold's own current element. `canonical = binding` is therefore the identical value, not an approximation of it — the order both expressions read is one traversal of one map value, so the equality does not depend on map_values being stable ACROSS runs (§5941 determinism), only on the two reads of the same value agreeing, which the rewrite removes the need for entirely.".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn export_index_module_state( - acc: Rc>>, - m: Rc, -) -> Rc { - Rc::new(v1_rt::map_values(&m.type_env.clone().bindings.clone())) - .iter() - .cloned() - .fold( - Rc::new(ExportIndexModuleAccum { - index: acc.clone(), - seen_names: v1_rt::rc_empty_map::(), - }), - |state: Rc, binding: Rc| { - let name = binding.name.clone(); - if v1_rt::map_contains_key(&state.seen_names.clone(), name.clone()) { - state.clone() - } else { - { - let canonical = binding.clone(); - let seen_names = - v1_rt::rc_map_insert(state.seen_names.clone(), name.clone(), true); - let index = match v1_rt::map_get(&state.index.clone(), name.clone()) { - None => v1_rt::rc_map_insert( - state.index.clone(), - name.clone(), - Rc::new(TypeNameExportFacts { - exporter_count: 1, - canonical_binding: Some(canonical.clone()), - }), - ), - Some(facts) => v1_rt::rc_map_insert( - state.index.clone(), - name.clone(), - Rc::new(TypeNameExportFacts { - exporter_count: (facts.exporter_count.clone() + 1), - canonical_binding: Some(canonical.clone()), - }), - ), - }; - Rc::new(ExportIndexModuleAccum { - index: index.clone(), - seen_names: seen_names.clone(), - }) - } - } - }, - ) -} - -pub fn export_index_merge_module_both( - acc: Rc, - m: Rc, - source_indices: Rc>>, -) -> Rc { - { - let state = export_index_module_state(acc.by_name.clone(), m.clone()); - Rc::new(ExportedTypeRelationBuild { - by_name: state.index.clone(), - by_module: v1_rt::rc_map_insert( - acc.by_module.clone(), - authored_name_at(source_indices.clone(), m.module.clone()), - state.seen_names.clone(), - ), - }) - } -} - -pub fn build_export_indexes( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc { - modules.clone().iter().cloned().fold( - Rc::new(ExportedTypeRelationBuild { - by_name: v1_rt::rc_empty_map::>(), - by_module: v1_rt::rc_empty_map::>>(), - }), - |acc: Rc, m: Rc| { - export_index_merge_module_both(acc, m.clone(), source_indices.clone()) - }, - ) -} - -pub fn module_exported_type_names_cost_note() -> String { - thread_local! { - static CACHED: String = { - "Cost shape (§6 bare-minimum cost, floor batch-3 receipt 2026-07-25): the type names a module exports is ONE derived fact — a set — and both consumers in rewire_type_env_import_str_binding_identity read it. Before this row it existed twice: the caller's per-module `local_names` fold, and `module_exports_type_name`, a LINEAR SCAN (map_values allocates a Vec of every binding, then filters by name) re-run once per (consumer module x inherited key x direct import). Measured on 79 discovery entries: that pass alone was 191.1s of a 331.9s resolve wall (99% of all rewire time, 2.4s/entry) while the other two rewire passes together cost 1.8s. Hoisting the set per module and testing membership made the per-name exporter count O(direct imports) instead of O(direct imports x |parent bindings|), with no change to the predicate it computes. That per-name scan is itself now gone: direct_import_exporter_counts accumulates the whole relation in one traversal of the same sets and rewire_canonical_rewrites reads it by key, so the pass no longer pays a scan per candidate name at all. The caller reads its own row out of the SAME index rather than re-folding it (review 42566) — the Absent arm computes the true value from this one authority, so it is a structurally-unreachable fallback that is still honest, never a fabricated default (DESIGN section 5).".to_string() - }; - } - CACHED.with(|c: &String| c.clone()) -} - -pub fn module_exported_type_names(m: Rc) -> Rc> { - Rc::new(v1_rt::map_values(&m.type_env.clone().bindings.clone())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, b: Rc| { - v1_rt::rc_map_insert(acc, b.name.clone(), true) - }, - ) -} - -pub fn direct_import_export_name_sets( - m: Rc, - export_name_index: Rc>>>, - source_indices: Rc>>, -) -> Rc>>> { - Rc::new({ - let mut __result = Vec::new(); - for imp in module_imports(m.module.clone()).iter().cloned() { - __result.extend( - (*{ - let path = import_module_path_at(imp.clone(), source_indices.clone()); - match v1_rt::map_get(&export_name_index, path.clone()) { - Some(names) => Rc::new(vec![names.clone()]), - None => Rc::new(vec![]), - } - }) - .iter() - .cloned(), - ); - } - __result - }) -} - -pub fn direct_import_exporter_counts( - import_export_names: Rc>>>, -) -> Rc> { - import_export_names.clone().iter().cloned().fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, names: Rc>| { - Rc::new(v1_rt::map_keys(&names)).iter().cloned().fold( - acc, - |inner: Rc>, name: String| match v1_rt::map_get( - &inner, - name.clone(), - ) { - Some(seen) => { - v1_rt::rc_map_insert(inner.clone(), name.clone(), (seen.clone() + 1)) - } - None => v1_rt::rc_map_insert(inner.clone(), name.clone(), 1), - }, - ) - }, - ) -} - -pub fn direct_import_exporter_count_of( - exporter_counts: Rc>, - name: String, -) -> i64 { - match v1_rt::map_get(&exporter_counts, name.clone()) { - Some(n) => n.clone(), - None => 0, - } -} - -pub fn rewire_canonical_rewrites( - type_name_index: Rc>>, - exporter_counts: Rc>, - local_names: Rc>, - inherited_keys: Rc>, -) -> Rc>> { - inherited_keys.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| match v1_rt::map_get( - &type_name_index, - name.clone(), - ) { - None => acc.clone(), - Some(facts) => { - if ((v1_rt::map_contains_key(&local_names, name.clone()) - || (direct_import_exporter_count_of(exporter_counts.clone(), name.clone()) - > 1)) - || (facts.exporter_count.clone() > 1)) - { - acc.clone() - } else { - match facts.canonical_binding.clone() { - Some(canonical) => { - v1_rt::rc_map_insert(acc.clone(), name.clone(), canonical.clone()) - } - None => acc.clone(), - } - } - } - }, - ) -} - -pub fn rewire_str_binding_overlay( - str_bindings: Rc>>, - rewrites: Rc>>, -) -> Rc>> { - Rc::new(v1_rt::map_keys(&rewrites)).iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| match v1_rt::map_get( - &str_bindings, - name.clone(), - ) { - Some(_) => match v1_rt::map_get(&rewrites, name.clone()) { - Some(canonical) => { - v1_rt::rc_map_insert(acc.clone(), name.clone(), canonical.clone()) - } - None => acc.clone(), - }, - None => acc.clone(), - }, - ) -} - -pub fn rewire_type_env_import_str_binding_identity( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc>> { - { - let export_indexes = build_export_indexes(modules.clone(), source_indices.clone()); - let type_name_index = export_indexes.by_name.clone(); - let export_name_index = export_indexes.by_module.clone(); - Rc::new({ - let mut __result = Vec::new(); - for m in modules.clone().iter().cloned() { - __result.push({ - let local_names = match v1_rt::map_get( - &export_name_index, - authored_name_at(source_indices.clone(), m.module.clone()), - ) { - Some(names) => names.clone(), - None => module_exported_type_names(m.clone()), - }; - let import_export_names = direct_import_export_name_sets( - m.clone(), - export_name_index.clone(), - source_indices.clone(), - ); - let exporter_counts = - direct_import_exporter_counts(import_export_names.clone()); - let ancestry_keys = Rc::new(v1_rt::map_keys( - &m.type_env.clone().ancestry_str_bindings.clone(), - )); - let str_keys = - Rc::new(v1_rt::map_keys(&m.type_env.clone().str_bindings.clone())); - let inherited_keys = v1_rt::concat(ancestry_keys.clone(), str_keys.clone()); - let rewrites = rewire_canonical_rewrites( - type_name_index.clone(), - exporter_counts.clone(), - local_names.clone(), - inherited_keys.clone(), - ); - let rewired = Rc::new(StrBindingsRewireAccum { - str_bindings: v1_rt::rc_map_merge( - m.type_env.clone().str_bindings.clone(), - rewire_str_binding_overlay( - m.type_env.clone().str_bindings.clone(), - rewrites.clone(), - ), - ), - ancestry_str_bindings: v1_rt::rc_map_merge( - m.type_env.clone().ancestry_str_bindings.clone(), - rewrites.clone(), - ), - }); - Rc::new(TypedModule { - module: m.module.clone(), - items: m.items.clone(), - type_env: Rc::new(TypeEnv { - module_path: m.type_env.clone().module_path.clone(), - bindings: m.type_env.clone().bindings.clone(), - str_bindings: rewired.str_bindings.clone(), - ancestry_str_bindings: rewired.ancestry_str_bindings.clone(), - parents: m.type_env.clone().parents.clone(), - recursive_types: m.type_env.clone().recursive_types.clone(), - recursive_type_set: m.type_env.clone().recursive_type_set.clone(), - inductive_fields: m.type_env.clone().inductive_fields.clone(), - source_indices: m.type_env.clone().source_indices.clone(), - intern_table: m.type_env.clone().intern_table.clone(), - source_visible_names: m.type_env.clone().source_visible_names.clone(), - symbol_index: m.type_env.clone().symbol_index.clone(), - }), - type_env_cache: m.type_env_cache.clone(), - interface: m.interface.clone(), - func_env: m.func_env.clone(), - item_registry: m.item_registry.clone(), - occurrence_transport: m.occurrence_transport.clone(), - }) - }); - } - __result - }) - } -} - -pub fn compiler_kernel_type_env( - source_indices: Rc>>, - intern_table: Rc, -) -> Rc { - { - let kernel_bindings_base = Rc::new(v1_rt::map_keys(&kernel_type_set())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - Rc::new(TypeBinding { - name: name.clone(), - resolved: Rc::new(Node { - name: name.clone(), - span: kernel_span(name.clone()), - ident_span: Some(kernel_span(name.clone())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ) - }, - ); - let unit_span = kernel_span("Unit".to_string()); - let kernel_bindings = v1_rt::rc_map_insert( - kernel_bindings_base.clone(), - intern(intern_table.clone(), "Unit".to_string()).id.clone(), - Rc::new(TypeBinding { - name: "Unit".to_string(), - resolved: Rc::new(Node { - name: "Unit".to_string(), - span: unit_span.clone(), - ident_span: Some(unit_span.clone()), - children: Rc::new(vec![]), - connective: Connective::Conj, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ); - let present_value_field = Rc::new(Node { - name: "value".to_string(), - span: kernel_span("value".to_string()), - ident_span: Some(kernel_span("value".to_string())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: Some(Rc::new(InferredNode::TypeVariable { - id: "present_value".to_string(), - })), - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let present_variant = Rc::new(Node { - name: "Present".to_string(), - span: kernel_span("Present".to_string()), - ident_span: Some(kernel_span("Present".to_string())), - children: Rc::new(vec![present_value_field.clone()]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let absent_variant = Rc::new(Node { - name: "Absent".to_string(), - span: kernel_span("Absent".to_string()), - ident_span: Some(kernel_span("Absent".to_string())), - children: Rc::new(vec![]), - connective: Connective::NoConnective, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let kernel_optional = Rc::new(Node { - name: "Optional".to_string(), - span: kernel_span("Optional".to_string()), - ident_span: Some(kernel_span("Optional".to_string())), - children: Rc::new(vec![present_variant.clone(), absent_variant.clone()]), - connective: Connective::Disj, - params: Rc::new(vec![]), - inferred: None, - return_cardinality: Cardinality::Required, - uses: Rc::new(vec![]), - body: None, - transport: None, - properties: Rc::new(vec![]), - type_annotation: None, - is_self_recursive: false, - has_non_tail_self_call: false, - match_pattern: None, - expr_data: Rc::new(ExprData::NoExprData), - ident: None, - }); - let kernel_bindings = v1_rt::rc_map_insert( - kernel_bindings.clone(), - intern(intern_table.clone(), "Optional".to_string()) - .id - .clone(), - Rc::new(TypeBinding { - name: "Optional".to_string(), - resolved: kernel_optional.clone(), - provenance: Rc::new(SubValueRelation::SubValueUnknown), - }), - ); - let node_fields = inductive_fields_list_to_map(compiler_inductive_fields()); - let kernel_recursive_types = Rc::new({ - let mut __result = Vec::new(); - for name in Rc::new(v1_rt::map_keys(&compiler_recursive_types())) - .iter() - .cloned() - { - __result.push(intern(intern_table.clone(), name.clone()).id.clone()); - } - __result - }); - let kernel_recursive_type_set = Rc::new(v1_rt::map_keys(&compiler_recursive_types())) - .iter() - .cloned() - .fold( - v1_rt::rc_empty_map::(), - |acc: Rc>, name: String| { - v1_rt::rc_map_insert( - acc, - intern(intern_table.clone(), name.clone()).id.clone(), - true, - ) - }, - ); - Rc::new(TypeEnv { - module_path: "".to_string(), - bindings: kernel_bindings.clone(), - str_bindings: str_bindings_from_bindings(kernel_bindings.clone()), - ancestry_str_bindings: v1_rt::rc_empty_map::>(), - parents: Rc::new(vec![]), - recursive_types: kernel_recursive_types.clone(), - recursive_type_set: kernel_recursive_type_set.clone(), - inductive_fields: node_fields.clone(), - source_indices: source_indices.clone(), - intern_table: intern_table.clone(), - source_visible_names: v1_rt::rc_empty_map::(), - symbol_index: empty_symbol_index(), - }) - } -} - -pub fn rewire_type_env_parent_links( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc>> { - { - let index = modules.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, m: Rc| { - v1_rt::rc_map_insert( - acc, - authored_name_at(source_indices.clone(), m.module.clone()), - m.clone(), - ) - }, - ); - let shared_kernel = match Rc::new({ - let mut __result = Vec::new(); - for m in modules.clone().iter().cloned() { - __result.extend( - (*match m.type_env.clone().parents.clone().last().cloned() { - Some(kernel) => { - if v1_rt::map_is_empty(&kernel.bindings.clone()) { - Rc::new(vec![]) - } else { - Rc::new(vec![kernel.clone()]) - } - } - None => Rc::new(vec![]), - }) - .iter() - .cloned(), - ); - } - __result - }) - .first() - .cloned() - { - Some(kernel) => kernel.clone(), - None => match modules.clone().first().cloned() { - Some(m) => compiler_kernel_type_env( - source_indices.clone(), - m.type_env.clone().intern_table.clone(), - ), - None => compiler_kernel_type_env(source_indices.clone(), empty_intern_table()), - }, - }; - Rc::new({ - let mut __result = Vec::new(); - for m in modules.clone().iter().cloned() { - __result.push({ - let import_parents = Rc::new({ - let mut __result = Vec::new(); - for imp in module_imports(m.module.clone()).iter().cloned() { - __result.extend( - (*{ - let path = - import_module_path_at(imp.clone(), source_indices.clone()); - match v1_rt::map_get(&index, path.clone()) { - Some(parent) => Rc::new(vec![interface_env_for_import( - path.clone(), - parent.type_env.clone(), - )]), - None => Rc::new(vec![]), - } - }) - .iter() - .cloned(), - ); - } - __result - }); - Rc::new(TypedModule { - module: m.module.clone(), - items: m.items.clone(), - type_env: Rc::new(TypeEnv { - module_path: m.type_env.clone().module_path.clone(), - bindings: m.type_env.clone().bindings.clone(), - str_bindings: m.type_env.clone().str_bindings.clone(), - ancestry_str_bindings: m.type_env.clone().ancestry_str_bindings.clone(), - parents: v1_rt::concat( - import_parents.clone(), - Rc::new(vec![shared_kernel.clone()]), - ), - recursive_types: m.type_env.clone().recursive_types.clone(), - recursive_type_set: m.type_env.clone().recursive_type_set.clone(), - inductive_fields: m.type_env.clone().inductive_fields.clone(), - source_indices: m.type_env.clone().source_indices.clone(), - intern_table: m.type_env.clone().intern_table.clone(), - source_visible_names: m.type_env.clone().source_visible_names.clone(), - symbol_index: m.type_env.clone().symbol_index.clone(), - }), - type_env_cache: m.type_env_cache.clone(), - interface: m.interface.clone(), - func_env: m.func_env.clone(), - item_registry: m.item_registry.clone(), - occurrence_transport: m.occurrence_transport.clone(), - }) - }); - } - __result - }) - } -} - -pub fn rewire_func_env_parent_links( - modules: Rc>>, - source_indices: Rc>>, -) -> Rc>> { - { - let index = modules.clone().iter().cloned().fold( - v1_rt::rc_empty_map::>(), - |acc: Rc>>, m: Rc| { - v1_rt::rc_map_insert( - acc, - authored_name_at(source_indices.clone(), m.module.clone()), - m.clone(), - ) - }, - ); - Rc::new({ - let mut __result = Vec::new(); - for m in modules.clone().iter().cloned() { - __result.push({ - let parents = Rc::new({ - let mut __result = Vec::new(); - for imp in module_imports(m.module.clone()).iter().cloned() { - __result.extend( - (*{ - let path = - import_module_path_at(imp.clone(), source_indices.clone()); - match v1_rt::map_get(&index, path.clone()) { - Some(parent) => Rc::new(vec![parent.func_env.clone()]), - None => Rc::new(vec![]), - } - }) - .iter() - .cloned(), - ); - } - __result - }); - Rc::new(TypedModule { - module: m.module.clone(), - items: m.items.clone(), - type_env: m.type_env.clone(), - type_env_cache: m.type_env_cache.clone(), - interface: m.interface.clone(), - func_env: Rc::new(ResolvedFuncEnv { - name: m.func_env.clone().name.clone(), - local: m.func_env.clone().local.clone(), - parents: flatten_parent_envs(parents.clone()), - }), - item_registry: m.item_registry.clone(), - occurrence_transport: m.occurrence_transport.clone(), - }) - }); - } - __result - }) - } -} - -pub fn reconcile( - graph: Rc, - source_indices: Rc>>, - intern_table: Rc, -) -> Rc { - reconcile_with_census_extra( - graph.clone(), - source_indices.clone(), - intern_table.clone(), - Rc::new(vec![]), - source_indices.clone(), - ) -} - -pub fn reconcile_with_census_extra( - graph: Rc, - source_indices: Rc>>, - intern_table: Rc, - census_fill_modules: Rc>>, - census_si: Rc>>, -) -> Rc { - { - let typed = typecheck_with_census_extra( - graph.clone(), - source_indices.clone(), - intern_table.clone(), - census_fill_modules.clone(), - census_si.clone(), - ); - let modules = rewire_type_env_parent_links(typed.modules.clone(), source_indices.clone()); - let modules = - rewire_type_env_import_str_binding_identity(modules.clone(), source_indices.clone()); - let modules = rewire_func_env_parent_links(modules.clone(), source_indices.clone()); - let emit_info = build_emit_graph_info(modules.clone()); - Rc::new(ResolvedGraph { - modules: modules.clone(), - item_registry: typed.item_registry.clone(), - diagnostics: typed.diagnostics.clone(), - emit_graph_info: emit_info.clone(), - }) - } -} From caf490baccc24e04cffddd405a2e15bb4ed786ae Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 18:35:56 +0000 Subject: [PATCH 10/17] (a) fork dissolution + measured (c) exposure; placeholder-carrier hypothesis refuted by execution --- src/v1/04_infer.dag | 27 ++++++++++++---- src/v1/stage0/src/v1_compiler_infer.rs | 44 ++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index c4c11ebc6ab..e592cdfa4ad 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -1112,11 +1112,20 @@ fn record_lit_fields_from_expected(type_name: String?, expected: Node?, scope: I } } -fn field_declared_type_node(sf: Node) -> Node { - match sf.inferred { - Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) - _ => field_node_type_expr(n: sf) - } +fn field_type_expr_is_stripped_placeholder(te: Node, source_indices: Map) -> Bool { + authored_name_at(source_indices: source_indices, node: te) == "" + && te.children |> count == 0 + && te.params |> count == 0 +} + +fn field_substitution_carrier(sf: Node, source_indices: Map) -> Node { + let te = field_node_type_expr(n: sf) + if field_type_expr_is_stripped_placeholder(te: te, source_indices: source_indices) { + match sf.inferred { + Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) + _ => te + } + } else { te } } fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: InferScope) -> List? { @@ -1146,7 +1155,7 @@ fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: In Node { name: sf.name, span: sf.span, ident_span: sf.ident_span, children: sf.children, connective: sf.connective, params: sf.params, - inferred: Present { value: Resolved { node: substitute_generics(n: field_declared_type_node(sf: sf), subst: subst, source_indices: scope.type_env.source_indices) } }, + inferred: Present { value: Resolved { node: substitute_generics(n: field_substitution_carrier(sf: sf, source_indices: scope.type_env.source_indices), subst: subst, source_indices: scope.type_env.source_indices) } }, return_cardinality: sf.return_cardinality, uses: sf.uses, body: sf.body, transport: sf.transport, properties: sf.properties, type_annotation: sf.type_annotation, is_self_recursive: sf.is_self_recursive, @@ -5405,7 +5414,11 @@ fn infer_record_lit_structural(type_name: String?, field_inits: List, span } let field_declared_type = match struct_fields |> filter(sf => authored_name_at(source_indices: scope.type_env.source_indices, node: sf) == fi_name) |> first { Present { value: sf } => - Present { value: field_declared_type_node(sf: sf) } + let ft = match sf.inferred { + Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) + _ => field_node_type_expr(n: sf) + } + Present { value: ft } Absent => none } let field_expected = match field_declared_type { diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index 257025e4802..fcf096fee7d 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -1711,12 +1711,29 @@ pub fn record_lit_fields_from_expected( } } -pub fn field_declared_type_node(sf: Rc) -> Rc { - match sf.inferred.as_deref() { - Some(InferredNode::Resolved { node: rt }) => { - preserve_outer_optional_cardinality(sf.clone(), rt.clone()) +pub fn field_type_expr_is_stripped_placeholder( + te: Rc, + source_indices: Rc>>, +) -> bool { + authored_name_at(source_indices.clone(), te.clone()) == *"" + && te.children.len() == 0 + && te.params.len() == 0 +} + +pub fn field_substitution_carrier( + sf: Rc, + source_indices: Rc>>, +) -> Rc { + let te = field_node_type_expr(sf.clone()); + if field_type_expr_is_stripped_placeholder(te.clone(), source_indices.clone()) { + match sf.inferred.as_deref() { + Some(InferredNode::Resolved { node: rt }) => { + preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + } + _ => te.clone(), } - _ => field_node_type_expr(sf.clone()), + } else { + te.clone() } } @@ -1767,8 +1784,13 @@ match exp.children.clone().iter().cloned().skip(pair.0.clone() as usize).next() inferred: Some(Rc::new( InferredNode::Resolved { node: substitute_generics( - field_declared_type_node( + field_substitution_carrier( sf.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), ), subst.clone(), scope @@ -9872,7 +9894,15 @@ pub fn infer_record_lit_structural( .first() .cloned() { - Some(sf) => Some(field_declared_type_node(sf.clone())), + Some(sf) => { + let ft = match sf.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + } + _ => field_node_type_expr(sf.clone()), + }; + Some(ft.clone()) + } None => None, }; let field_expected = match field_declared_type.clone() { From 2b7a17af9ac137ca73401cacd1529eff2c94ce5f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 19:07:08 +0000 Subject: [PATCH 11/17] (c) an UNESTABLISHED return type must not become a lambda's body expectation --- src/v1/04_infer.dag | 18 +++++++++++---- src/v1/stage0/src/v1_compiler_infer.rs | 32 ++++++++++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index e592cdfa4ad..02e70fea12a 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -1224,6 +1224,12 @@ fn set_element_types_mismatch(recv_elem: Node, operand_elem: Node, source_indice && !node_type_compatible(left: recv_elem, right: operand_elem, source_indices: source_indices) } +fn type_node_is_established(n: Node, source_indices: Map) -> Bool { + authored_name_at(source_indices: source_indices, node: n) != "" + || n.children |> count > 0 + || n.params |> count > 0 +} + fn type_node_is_callable(n: Node) -> Bool { n.params |> count > 0 } @@ -4592,10 +4598,14 @@ fn infer_expr_body(texpr: Node, scope: InferScope, expected: Node?) -> InferResu let body_expected = if expected != none { let exp = expected.value if exp.params |> count > 0 { - let declared_ret = resolved_type(n: exp) - if is_fully_resolved(n: declared_ret, source_indices: scope.type_env.source_indices) { - Present { value: declared_ret } - } else { none } + match exp.inferred { + Present { value: Resolved { node: declared_ret } } => + if type_node_is_established(n: declared_ret, source_indices: scope.type_env.source_indices) + && is_fully_resolved(n: declared_ret, source_indices: scope.type_env.source_indices) { + Present { value: declared_ret } + } else { none } + _ => none + } } else { none } } else { none } let body_scope = InferScope { diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index fcf096fee7d..fd4d8604836 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -1929,6 +1929,15 @@ pub fn set_element_types_mismatch( )) } +pub fn type_node_is_established( + n: Rc, + source_indices: Rc>>, +) -> bool { + authored_name_at(source_indices.clone(), n.clone()) != *"" + || n.children.len() > 0 + || n.params.len() > 0 +} + pub fn type_node_is_callable(n: Rc) -> bool { ((n.params.clone().len() as i64) > 0) } @@ -8280,16 +8289,21 @@ if ((call_ambiguity_cands.clone().len() as i64) > 0) { { let exp = expected.clone().unwrap(); if ((exp.params.clone().len() as i64) > 0) { - { - let declared_ret = resolved_type(exp.clone()); - if is_fully_resolved( - declared_ret.clone(), - scope.type_env.clone().source_indices.clone(), - ) { - Some(declared_ret.clone()) - } else { - None + match exp.inferred.as_deref() { + Some(InferredNode::Resolved { node: declared_ret }) => { + if type_node_is_established( + declared_ret.clone(), + scope.type_env.clone().source_indices.clone(), + ) && is_fully_resolved( + declared_ret.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + Some(declared_ret.clone()) + } else { + None + } } + _ => None, } } else { None From ffddac8b553370206f91052859f5fff03a2b0452 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 19:20:47 +0000 Subject: [PATCH 12/17] Install the emitted mirror for v1_compiler_infer.rs (regen candidate, not hand-tuned) --- src/v1/stage0/src/v1_compiler_infer.rs | 40 ++++++++++++++------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index 19491e57029..a57fe3fccc7 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -1717,25 +1717,27 @@ pub fn field_type_expr_is_stripped_placeholder( te: Rc, source_indices: Rc>>, ) -> bool { - authored_name_at(source_indices.clone(), te.clone()) == *"" - && te.children.len() == 0 - && te.params.len() == 0 + (((authored_name_at(source_indices.clone(), te.clone()) == "".to_string()) + && ((te.children.clone().len() as i64) == 0)) + && ((te.params.clone().len() as i64) == 0)) } pub fn field_substitution_carrier( sf: Rc, source_indices: Rc>>, ) -> Rc { - let te = field_node_type_expr(sf.clone()); - if field_type_expr_is_stripped_placeholder(te.clone(), source_indices.clone()) { - match sf.inferred.as_deref() { - Some(InferredNode::Resolved { node: rt }) => { - preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + { + let te = field_node_type_expr(sf.clone()); + if field_type_expr_is_stripped_placeholder(te.clone(), source_indices.clone()) { + match sf.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + } + _ => te.clone(), } - _ => te.clone(), + } else { + te.clone() } - } else { - te.clone() } } @@ -1935,9 +1937,9 @@ pub fn type_node_is_established( n: Rc, source_indices: Rc>>, ) -> bool { - authored_name_at(source_indices.clone(), n.clone()) != *"" - || n.children.len() > 0 - || n.params.len() > 0 + (((authored_name_at(source_indices.clone(), n.clone()) != "".to_string()) + || ((n.children.clone().len() as i64) > 0)) + || ((n.params.clone().len() as i64) > 0)) } pub fn type_node_is_callable(n: Rc) -> bool { @@ -8296,15 +8298,17 @@ if ((call_ambiguity_cands.clone().len() as i64) > 0) { { let exp = expected.clone().unwrap(); if ((exp.params.clone().len() as i64) > 0) { - match exp.inferred.as_deref() { - Some(InferredNode::Resolved { node: declared_ret }) => { - if type_node_is_established( + match exp.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: declared_ret, .. + }) => { + if (type_node_is_established( declared_ret.clone(), scope.type_env.clone().source_indices.clone(), ) && is_fully_resolved( declared_ret.clone(), scope.type_env.clone().source_indices.clone(), - ) { + )) { Some(declared_ret.clone()) } else { None From 0c9374733945f160075016b9aad68cacd53a41bd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 22 Aug 2026 23:08:46 +0000 Subject: [PATCH 13/17] Delete four dissolved frontier rows (observed=0), fix two ContentHash construction defects the wall caught, admit list literals at FreeMonoid --- dag/gunbc/accelerator_demo_plan.dag | 2 +- .../claim/realization_width_witness_test.dag | 2 +- src/v1/04_infer.dag | 49 +++++------------ src/v1/stage0/src/v1_compiler_infer.rs | 53 ++++++++----------- 4 files changed, 36 insertions(+), 70 deletions(-) diff --git a/dag/gunbc/accelerator_demo_plan.dag b/dag/gunbc/accelerator_demo_plan.dag index bc9242e328b..4fe8fd61d9f 100644 --- a/dag/gunbc/accelerator_demo_plan.dag +++ b/dag/gunbc/accelerator_demo_plan.dag @@ -54,7 +54,7 @@ fn relu_mul_add_schedule() -> std.realization_schedule.Schedule { fn build_realization_plan(schedule: std.realization_schedule.Schedule) -> RealizationPlan { RealizationPlan { - target: demo_target_label + target: std.content_hash.content_hash_of_value(value: demo_target_label) objective: RealizationObjective { goals: [] } schedule: schedule total: demo_plan_total() diff --git a/dag/test/claim/realization_width_witness_test.dag b/dag/test/claim/realization_width_witness_test.dag index 078f04c2f3e..13958d36189 100644 --- a/dag/test/claim/realization_width_witness_test.dag +++ b/dag/test/claim/realization_width_witness_test.dag @@ -20,7 +20,7 @@ fn witness_threads_4() -> HardwareThreadCount { fn synthetic_plan() -> RealizationPlan { RealizationPlan { - target: "width-witness-target" + target: std.content_hash.content_hash_of_value(value: "width-witness-target") objective: RealizationObjective { goals: [] } schedule: [ [RunnableSingleClaim { entry: gate_entry, function: compile_gate_fn, profile: runnable_resource_profile_negligible() }], diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index 223ed6b9665..15d42165261 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -1,5 +1,5 @@ module v1.compiler.infer -import std.types { SourceSpan, NonEmptyStr, container_param_name, kernel_type_set, is_kernel_type } +import std.types { SourceSpan, NonEmptyStr, container_param_name, container_template_algebra, kernel_type_set, is_kernel_type } import std.content_hash { ContentHash, Fnv1a64Structural, @@ -1224,6 +1224,15 @@ fn set_element_types_mismatch(recv_elem: Node, operand_elem: Node, source_indice && !node_type_compatible(left: recv_elem, right: operand_elem, source_indices: source_indices) } +fn node_admits_list_literal(n: Node, source_indices: Map) -> Bool { + node_is_element_collection(n: n, source_indices: source_indices) + || ((n.children |> count) == 1 + && match container_template_algebra(name: qualified_last_segment(name: authored_name_at(source_indices: source_indices, node: n))) { + Present { value: _ } => true + Absent => false + }) +} + fn type_node_is_established(n: Node, source_indices: Map) -> Bool { authored_name_at(source_indices: source_indices, node: n) != "" || n.children |> count > 0 @@ -2817,7 +2826,7 @@ fn method_pipe_map_keys_values_fallback(recv_rt: Node, method_name: String, scop } } -data method_existence_wall_note: String = "WALL (DESIGN §5) — an unresolved method REFUSES; it never inherits the receiver type. The deleted else-arm returned recv_rt with an EMPTY diagnostic list, so an unknown method on List became another List: a success-shaped answer that survived a whole collection pipeline, stamped PlainMethodSemantics as if it had resolved. Nothing refused until InterpError::Unimplemented { what: \"method 'filter_map'\" } — whole-tree compile reported ZERO blocking errors while live dispatch returned HTTP 500 (#7479). THE DECIDABILITY PREDICATE IS THE LOAD-BEARING PART. It is PER-RECEIVER, not per-name: refuse exactly when kernel_profile_lookup returns a profile for the receiver canonical container kind, because tier0 (lookup_structural_method) has already consulted that profile algebra templates and missed — so reaching this arm with a kernel-profiled receiver PROVES the method is absent from that receiver complete declared surface. This is the same authority tier0 reads, not a second relation minted here (§3). A NAME-GRAIN PREDICATE WAS TRIED AND IS WRONG, and the receipt is worth keeping because it is subtle: gating on membership in a declared method-name roster admits any rostered name on ANY receiver, so List |> starts_with(..) and List |> to_upper() compiled clean while the diagnostic claimed the receiver was under-resolved — a fail-open with a message that also LIED about its cause, since Container(List,Primitive(Int)) is fully resolved (codex review 45327, confirmed by execution). Per-receiver closes both: those two now REFUSE. THE ONE MEASURED OBSTACLE TO PER-RECEIVER WAS A REAL §3 FORK, AND IT IS FIXED HERE RATHER THAN WORKED AROUND: free_monoid_scalar_templates omitted count while the interpreter dispatches it natively on strings (the length/count/size arm), so String |> count reached this arm and was admitted only by the fail-open — a hollow green. count is now declared on the String profile, matching the runtime, so it resolves at tier0 and never reaches here. WHAT STAYS UNDECIDED, and why refusing there would fabricate: a receiver with NO kernel profile has no complete declared surface to prove absence against. THE LARGEST MEASURED CLASS WAS NOT UNDECIDABLE AT ALL AND IS NOW DECIDED — a where-refinement alias arrived as Product(NonEmptyStr) only because resolve_method_receiver_type short-circuits on Conj and never peeled to the String base; peeling it (where_refinement_receiver_peel_note) moved 12 corpus sites out of this residue in both directions at once, resolving the correct .length() calls AND making a bogus method on a branded string a hard MethodNotFound. What remains genuinely has no surface: a lambda parameter whose type never propagates so the receiver has no authored name at all (the LexMatchThunk { apply: fn(s) } idiom in src/v2/compiler/01_tokenize.dag and the StoreObjectFold lambdas in extdeps/git/object_store.dag), a coproduct payload bound by pattern destructuring arriving typed Primitive(ok) (a correct labels |> list_push(label)), a bare type variable, and an Optional whose cardinality is dropped before lookup so the inner product is what arrives. Refusing those would red correct code, which is the mirror image of the fabricated success this wall deletes. A RECEIVER WITH NO AUTHORED NAME AT ALL is not weak evidence about the method — it is no evidence about anything, because the receiver's own type was never established upstream. That is a different judgment failure from 'this receiver has a surface and the method is not on it', so it carries its own diagnostic, ReceiverTypeUnestablished, whose message names that cause instead of implying the method is missing. THE DIAGNOSTIC NAMES THE CAUSE; THE ROSTER BOUNDS THE ADMISSION, and separating those two was a correction. The class was first admitted on the CAUSE alone — any anonymous receiver, non-blocking — on the reasoning that the wall cannot tell an existing method from a nonexistent one when the receiver has no type, so refusing would refuse both. That reasoning is sound about DECIDABILITY and wrong about ADMISSION: it made every future anonymous-receiver call green, including one whose method does not exist, so the exception was unbounded exactly where existence is unknown (codex review 45459). Counting a diagnostic does not stop invalid code reaching the live system. Admission is now gated on the same declared roster as every other unestablished shape, keyed (module, method, Primitive()), so the seven measured occurrences are admitted and a new one anywhere else REFUSES as MethodExistenceUndecided. That is a ratchet that can only shrink, and blocking a new instance of a known deficit is the factory model rather than an inconvenience. Everything that has a name but no surface stays in the same shape-keyed roster. MethodExistenceUndecided carries what is left as a typed, located, COUNTED non-blocking diagnostic (the is_error_diagnostic partition, UnlistedImportUse precedent) so the frequency stays observable and prioritizable rather than zeroed by construction — and it now means exactly ONE thing, receiver surface not established, rather than doubling as a name-grain escape. Both arms return error_type, never recv_rt, so one located refusal does not cascade downstream. AND THE WALL IS REACHED FROM EVERY ARM, WHICH IT WAS NOT AT FIRST: the decision lived inline in the final else of method_pipe_map_keys_values_fallback, so an unresolved map_keys, sorted_map_keys or map_values whose receiver is not a keyed collection took an EARLIER branch and returned recv_rt with an empty diagnostic list — the identical success-shaped fallback this wall exists to delete, preserved in the two special cases that ran before it (codex review 45430). A wall reachable only from the default arm is not a wall, and prose about the default arm cannot see the two arms in front of it. The decision is now method_existence_decision, held once and called from all three, with the control run against the prior binary rather than reasoned about: List |> map_keys and |> map_values compile with exit 0 on the pre-routing binary and produce two located MethodNotFound refusals on this one. Positive controls: map/filter/fold/flat_map resolve at tier0 and service ops at tier1, neither reaching this arm. THE UPSTREAM DEFECTS ARE NAMED BY THE MEASUREMENT, one fixed here and the rest left as promotion triggers that would each let the wall decide a further non-kernel receiver: (1) FIXED — a where-refinement alias resolving to a Product shape instead of peeling to its declared base before method lookup; (2) a lambda parameter receiver whose type never propagates from the declared fn type it is bound under; (3) a coproduct payload binding typed as the VARIANT name rather than the field type; (4) an optional receiver whose cardinality is dropped so the inner product reaches lookup in place of Optional own surface. Each is carried as a row in unresolved_method_frontier, keyed on the receiver shape that is the evidence for it, except (2) which is the ReceiverTypeUnestablished cause class above. THE INSTRUMENT WAS WRONG BEFORE THE WALL WAS, and that is the most transferable thing here: this wall was measured with `gunbc run --entry dag/tools/generated_artifact_gate.dag`, which reaches only that gate's import closure, and it reported CLEAN while twelve real sites sat outside it — they surfaced from CI instead. The whole-corpus instrument is `gunbc compile --source-root dag --source-root src/v2 --target dag`, the same compile-clean gate CI runs, and it resolves 1629 sources against 2740 indexed modules. A narrow instrument reporting clean is indistinguishable from a wall that works, which is the §5 specification-without-execution trap wearing the shape of a green run. A FOURTH SHAPE was then found and NOT fixed: a brand alias can also arrive as a plain qualified LEAF (Primitive(std.types.NonEmptyStr)) rather than the refinement Conj the peel walks. Three head-resolution strategies were implemented and measured against it — lookup_type_for on the node, lookup_type_by_name on the qualified name, and on its last segment — none recovered the refinement, so the machinery was DELETED rather than shipped unproven and the site is a declared row. Unproven machinery that decides nothing is worse than a declared row that admits what it cannot decide. Dissolve-on: primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete surface, the count-style forks are unwritable rather than hand-reconciled, and MethodExistenceUndecided is deleted." +data method_existence_wall_note: String = "WALL (DESIGN §5) — an unresolved method REFUSES; it never inherits the receiver type. The deleted else-arm returned recv_rt with an EMPTY diagnostic list, so an unknown method on List became another List: a success-shaped answer that survived a whole collection pipeline, stamped PlainMethodSemantics as if it had resolved. Nothing refused until InterpError::Unimplemented { what: \"method 'filter_map'\" } — whole-tree compile reported ZERO blocking errors while live dispatch returned HTTP 500 (#7479). THE DECIDABILITY PREDICATE IS THE LOAD-BEARING PART. It is PER-RECEIVER, not per-name: refuse exactly when kernel_profile_lookup returns a profile for the receiver canonical container kind, because tier0 (lookup_structural_method) has already consulted that profile algebra templates and missed — so reaching this arm with a kernel-profiled receiver PROVES the method is absent from that receiver complete declared surface. This is the same authority tier0 reads, not a second relation minted here (§3). A NAME-GRAIN PREDICATE WAS TRIED AND IS WRONG, and the receipt is worth keeping because it is subtle: gating on membership in a declared method-name roster admits any rostered name on ANY receiver, so List |> starts_with(..) and List |> to_upper() compiled clean while the diagnostic claimed the receiver was under-resolved — a fail-open with a message that also LIED about its cause, since Container(List,Primitive(Int)) is fully resolved (codex review 45327, confirmed by execution). Per-receiver closes both: those two now REFUSE. THE ONE MEASURED OBSTACLE TO PER-RECEIVER WAS A REAL §3 FORK, AND IT IS FIXED HERE RATHER THAN WORKED AROUND: free_monoid_scalar_templates omitted count while the interpreter dispatches it natively on strings (the length/count/size arm), so String |> count reached this arm and was admitted only by the fail-open — a hollow green. count is now declared on the String profile, matching the runtime, so it resolves at tier0 and never reaches here. WHAT STAYS UNDECIDED, and why refusing there would fabricate: a receiver with NO kernel profile has no complete declared surface to prove absence against. THE LARGEST MEASURED CLASS WAS NOT UNDECIDABLE AT ALL AND IS NOW DECIDED — a where-refinement alias arrived as Product(NonEmptyStr) only because resolve_method_receiver_type short-circuits on Conj and never peeled to the String base; peeling it (where_refinement_receiver_peel_note) moved 12 corpus sites out of this residue in both directions at once, resolving the correct .length() calls AND making a bogus method on a branded string a hard MethodNotFound. What remains genuinely has no surface: a lambda parameter whose type never propagates so the receiver has no authored name at all (the LexMatchThunk { apply: fn(s) } idiom in src/v2/compiler/01_tokenize.dag; the StoreObjectFold lambdas in extdeps/git/object_store.dag were the second instance and are RESOLVED — once a generic field's substituted type reached the field expectation and an unestablished return stopped being certified as resolved, their `map` and `flat_map` rows measured zero observed and were deleted), a coproduct payload bound by pattern destructuring arriving typed Primitive(ok) (a correct labels |> list_push(label)), a bare type variable, and an Optional whose cardinality is dropped before lookup so the inner product is what arrives. Refusing those would red correct code, which is the mirror image of the fabricated success this wall deletes. A RECEIVER WITH NO AUTHORED NAME AT ALL is not weak evidence about the method — it is no evidence about anything, because the receiver's own type was never established upstream. That is a different judgment failure from 'this receiver has a surface and the method is not on it', so it carries its own diagnostic, ReceiverTypeUnestablished, whose message names that cause instead of implying the method is missing. THE DIAGNOSTIC NAMES THE CAUSE; THE ROSTER BOUNDS THE ADMISSION, and separating those two was a correction. The class was first admitted on the CAUSE alone — any anonymous receiver, non-blocking — on the reasoning that the wall cannot tell an existing method from a nonexistent one when the receiver has no type, so refusing would refuse both. That reasoning is sound about DECIDABILITY and wrong about ADMISSION: it made every future anonymous-receiver call green, including one whose method does not exist, so the exception was unbounded exactly where existence is unknown (codex review 45459). Counting a diagnostic does not stop invalid code reaching the live system. Admission is now gated on the same declared roster as every other unestablished shape, keyed (module, method, Primitive()), so the seven measured occurrences are admitted and a new one anywhere else REFUSES as MethodExistenceUndecided. That is a ratchet that can only shrink, and blocking a new instance of a known deficit is the factory model rather than an inconvenience. Everything that has a name but no surface stays in the same shape-keyed roster. MethodExistenceUndecided carries what is left as a typed, located, COUNTED non-blocking diagnostic (the is_error_diagnostic partition, UnlistedImportUse precedent) so the frequency stays observable and prioritizable rather than zeroed by construction — and it now means exactly ONE thing, receiver surface not established, rather than doubling as a name-grain escape. Both arms return error_type, never recv_rt, so one located refusal does not cascade downstream. AND THE WALL IS REACHED FROM EVERY ARM, WHICH IT WAS NOT AT FIRST: the decision lived inline in the final else of method_pipe_map_keys_values_fallback, so an unresolved map_keys, sorted_map_keys or map_values whose receiver is not a keyed collection took an EARLIER branch and returned recv_rt with an empty diagnostic list — the identical success-shaped fallback this wall exists to delete, preserved in the two special cases that ran before it (codex review 45430). A wall reachable only from the default arm is not a wall, and prose about the default arm cannot see the two arms in front of it. The decision is now method_existence_decision, held once and called from all three, with the control run against the prior binary rather than reasoned about: List |> map_keys and |> map_values compile with exit 0 on the pre-routing binary and produce two located MethodNotFound refusals on this one. Positive controls: map/filter/fold/flat_map resolve at tier0 and service ops at tier1, neither reaching this arm. THE UPSTREAM DEFECTS ARE NAMED BY THE MEASUREMENT, one fixed here and the rest left as promotion triggers that would each let the wall decide a further non-kernel receiver: (1) FIXED — a where-refinement alias resolving to a Product shape instead of peeling to its declared base before method lookup; (2) a lambda parameter receiver whose type never propagates from the declared fn type it is bound under; (3) a coproduct payload binding typed as the VARIANT name rather than the field type; (4) an optional receiver whose cardinality is dropped so the inner product reaches lookup in place of Optional own surface. Each is carried as a row in unresolved_method_frontier, keyed on the receiver shape that is the evidence for it, except (2) which is the ReceiverTypeUnestablished cause class above. THE INSTRUMENT WAS WRONG BEFORE THE WALL WAS, and that is the most transferable thing here: this wall was measured with `gunbc run --entry dag/tools/generated_artifact_gate.dag`, which reaches only that gate's import closure, and it reported CLEAN while twelve real sites sat outside it — they surfaced from CI instead. The whole-corpus instrument is `gunbc compile --source-root dag --source-root src/v2 --target dag`, the same compile-clean gate CI runs, and it resolves 1629 sources against 2740 indexed modules. A narrow instrument reporting clean is indistinguishable from a wall that works, which is the §5 specification-without-execution trap wearing the shape of a green run. A FOURTH SHAPE was then found and NOT fixed: a brand alias can also arrive as a plain qualified LEAF (Primitive(std.types.NonEmptyStr)) rather than the refinement Conj the peel walks. Three head-resolution strategies were implemented and measured against it — lookup_type_for on the node, lookup_type_by_name on the qualified name, and on its last segment — none recovered the refinement, so the machinery was DELETED rather than shipped unproven and the site is a declared row. Unproven machinery that decides nothing is worse than a declared row that admits what it cannot decide. Dissolve-on: primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete surface, the count-style forks are unwritable rather than hand-reconciled, and MethodExistenceUndecided is deleted." data where_refinement_receiver_peel_note: String = "A where-refinement type is a Conj carrying its base as its single child and its predicates in type_annotation, and resolve_method_receiver_type SHORT-CIRCUITS on connective == Conj — it treats any product as already-structural and returns it untouched. So NonEmptyStr, declared `String where non_empty`, reached method lookup as Product(NonEmptyStr) and String's algebra profile was never consulted: `.length()` on a branded string had no surface to resolve against and no surface to prove absence against either, which put 12 correct corpus sites (8 in extdeps.filesystem.linux, 4 across gunbc.design) in the wall's undecided residue. This peel is the fix, and the FIRST version of it was a §3 violation that this note asserted its way past — worth recording, because the note is where the defect actually lived. It hand-rolled a second recursive walker over the Conj/annotation/single-child shape and then CLAIMED, in this sentence, that the refinement chain had one traversal authority and the peel was its second consumer. Both walkers independently encoded the shape test, the lookup_type_for base resolution and the recursion, so they could drift apart silently; the prose asserted the property instead of the code establishing it (codex review 45410). WHY THESE READ NODE STORAGE DIRECTLY, since it is asked and the answer is not a per-function one: they are 2 of the 589 direct Node-storage reads in this file (579 of them on origin/main), which is the v1 seed's pervasive and only idiom — the seed IS the traversal, the stage that walks the tree so that later stages need not. There is no canonical query or fold surface reachable from here: fold_node and node_query live in src/v2/std, no v1 seed module imports v2 at all, and v1 COMPILES v2, so routing v1 inference through v2's fold inverts the bootstrap rather than tidying it. DESIGN's fold_node line is scoped to the 7 v2 stages and is a DRY example within v2, not a rule binding the seed. So the disposition here is the SEED'S disposition, the same trigger the hand-Rust receipt carries — the v1 seed shrinks to zero at v2 self-host and these dissolve with it — and attaching a separate per-function trigger to 2 reads while 587 identical reads beside them carry none would be a fabricated bound, describing separable work that does not exist (codex review 45570). The repair is the extraction the claim described: where_refinement_chain is the one walk, it yields the refinement chain from the surface alias down to its ground base, and it has exactly two consumers — type_where_refinement_predicates_transitive flat_maps the immediate predicates over the chain, and peel_where_refinement_base takes its last link. The shape test itself is is_where_refinement_type, held once. Now there is one traversal authority, and it is one because the code says so. It runs only where the wall was already about to refuse or admit, so no previously-resolving call changes meaning; tier0 keeps first claim on the unpeeled receiver, which is what preserves a method declared on the brand itself. The consequence that matters is not that 12 sites went green — it is that they became DECIDABLE IN BOTH DIRECTIONS: once the peeled receiver is kernel-profiled, a method genuinely absent from String now refuses as MethodNotFound instead of resting in the frontier. Widening what the wall can decide is the only move that shrinks the frontier without either fabricating a success or fabricating a refusal." @@ -2840,38 +2849,6 @@ fn unresolved_method_frontier() -> List { cause: "receiver is a lambda parameter whose type is never inferred, so it arrives with NO authored name at all. The call is a product FIELD holding a callable — the LexMatchThunk { apply: fn(s) } idiom — not a method at all.", dissolution: unbound_dissolution(description: "lambda-parameter receiver typing, so the receiver resolves to its declared product and apply is found as a field") }, - { - module_name: "extdeps.git.object_store", - method: "map", - occurrences: 2, - receiver_shape: "Primitive()", - cause: "receiver is `tree.entries` where `tree` is the parameter of a lambda stored in a StoreObjectFold record field, so the field's declared fn type never reaches the lambda's parameter and the projection off it has no established type.", - dissolution: unbound_dissolution(description: "lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in") - }, - { - module_name: "extdeps.git.object_store", - method: "flat_map", - occurrences: 1, - receiver_shape: "Primitive()", - cause: "same StoreObjectFold lambda-parameter shape as the `map` row above; listed separately because the key names one method on one receiver shape, never a module-wide pass.", - dissolution: unbound_dissolution(description: "lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in") - }, - { - module_name: "extdeps.mercurial", - method: "any", - occurrences: 3, - receiver_shape: "Primitive()", - cause: "receiver is an untyped parameter of a lambda stored in a fold record field, the same shape as the object_store rows.", - dissolution: unbound_dissolution(description: "lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in") - }, - { - module_name: "gunbc.scm_compatibility.mercurial", - method: "map", - occurrences: 3, - receiver_shape: "Primitive()", - cause: "receiver is `missing_changesets`, an untyped parameter of the `partial:` lambda in a MercurialRepositoryCompletenessFold record field.", - dissolution: unbound_dissolution(description: "lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in") - }, { module_name: "extdeps.dns.domain_name", method: "list_push", @@ -2957,7 +2934,7 @@ fn frontier_occurrence_budget_diags(module_name: String, module_span: SourceSpan |> flat_map(r => frontier_row_budget_diags(row: r, diagnostics: diagnostics, module_name: module_name, module_span: module_span)) } -data frontier_occurrence_budget_note: String = "THE COUNT IS WHAT MAKES THE FRONTIER A RATCHET INSTEAD OF AN EXEMPTION. Keying admission on (module, method, receiver_shape) bounds WHERE an unresolved call may live but not HOW MANY may live there, so a second call in the same module, on the same method, failing to resolve the same way, inherited the admission — and that is not hypothetical: the measured rows are not all singletons (v2.compiler.tokenize admits seven `apply` calls, extdeps.mercurial three `any`, gunbc.scm_compatibility.mercurial three `map`), so a row admitting seven would silently admit an eighth (codex review 45464). Each row therefore declares its MEASURED occurrence count and this fold refuses the excess, located on the first offending call. THE COMPARISON IS EQUALITY, AND IT WAS FIRST WRITTEN AS A CEILING, WHICH DID NOT RATCHET. `observed > declared` was justified here on the reasoning that a narrower compile closure sees fewer occurrences of a module's rows, so equality would red a partial build. That reasoning is WRONG about this check: it runs per MODULE, and every occurrence of a module's rows is present whenever that module is typechecked at all — a closure that omits the module never runs its rows, so there is no partial-visibility case to protect. What the ceiling actually did was let seven shrink to six while the declared seven stood, so a seventh call could return silently: a static limit, not a ratchet, and the note claimed the ratchet anyway (codex review 45491). Equality closes it in the only way that works — fixing a call reds until the declared count is lowered, which removes the headroom a reintroduction would have slipped into. Both directions are asserted in the witness, because the under-count half is the half that makes it a ratchet and it is the one an author is tempted to relax. WHY NOT A STABLE PER-OCCURRENCE KEY, which would close this exactly: std.occurrence_identity is the corpus authority for occurrence identity and its own scope law forbids filename, SourceSpan, authored name, structural Node equality and content hash as identity inputs, allocating OccurrenceId inside one graph-scoped allocator instead. An allocator-assigned integer cannot appear as a literal in a declared row, because it is not stable across compiles — so a per-occurrence key is not merely unimplemented here, it is unavailable from the authority that owns the concept. The count is the strongest bound the substrate currently supports. Dissolve-on: a content-addressed occurrence identity stable across edits (the namespace lane's containment addressing), at which point rows key on the occurrence itself and the count field deletes." +data frontier_occurrence_budget_note: String = "THE COUNT IS WHAT MAKES THE FRONTIER A RATCHET INSTEAD OF AN EXEMPTION. Keying admission on (module, method, receiver_shape) bounds WHERE an unresolved call may live but not HOW MANY may live there, so a second call in the same module, on the same method, failing to resolve the same way, inherited the admission — and that is not hypothetical: the measured rows are not all singletons (v2.compiler.tokenize admits seven `apply` calls; the extdeps.mercurial `any` and gunbc.scm_compatibility.mercurial `map` rows cited here were three apiece until the lambda-parameter receiver class was resolved and both dissolved to zero observed, so they are deleted and the surviving multi-occurrence example is tokenize's), so a row admitting seven would silently admit an eighth (codex review 45464). Each row therefore declares its MEASURED occurrence count and this fold refuses the excess, located on the first offending call. THE COMPARISON IS EQUALITY, AND IT WAS FIRST WRITTEN AS A CEILING, WHICH DID NOT RATCHET. `observed > declared` was justified here on the reasoning that a narrower compile closure sees fewer occurrences of a module's rows, so equality would red a partial build. That reasoning is WRONG about this check: it runs per MODULE, and every occurrence of a module's rows is present whenever that module is typechecked at all — a closure that omits the module never runs its rows, so there is no partial-visibility case to protect. What the ceiling actually did was let seven shrink to six while the declared seven stood, so a seventh call could return silently: a static limit, not a ratchet, and the note claimed the ratchet anyway (codex review 45491). Equality closes it in the only way that works — fixing a call reds until the declared count is lowered, which removes the headroom a reintroduction would have slipped into. Both directions are asserted in the witness, because the under-count half is the half that makes it a ratchet and it is the one an author is tempted to relax. WHY NOT A STABLE PER-OCCURRENCE KEY, which would close this exactly: std.occurrence_identity is the corpus authority for occurrence identity and its own scope law forbids filename, SourceSpan, authored name, structural Node equality and content hash as identity inputs, allocating OccurrenceId inside one graph-scoped allocator instead. An allocator-assigned integer cannot appear as a literal in a declared row, because it is not stable across compiles — so a per-occurrence key is not merely unimplemented here, it is unavailable from the authority that owns the concept. The count is the strongest bound the substrate currently supports. Dissolve-on: a content-addressed occurrence identity stable across edits (the namespace lane's containment addressing), at which point rows key on the occurrence itself and the count field deletes." fn frontier_occurrence_budget_checked(module_name: String, module_span: SourceSpan, diagnostics: List) -> List { concat(diagnostics, frontier_occurrence_budget_diags(module_name: module_name, module_span: module_span, diagnostics: diagnostics)) @@ -4509,7 +4486,7 @@ fn infer_expr_body(texpr: Node, scope: InferScope, expected: Node?) -> InferResu let empty_list_diags = if count(elem_results) == 0 { match expected { Present { value: exp } => - if node_is_element_collection(n: exp, source_indices: scope.type_env.source_indices) { + if node_admits_list_literal(n: exp, source_indices: scope.type_env.source_indices) { match exp.children |> first { Present { value: _ } => [] Absent => [inference_error(message: "empty list literal: expected type has no element type", span: span, module_name: scope.module_name)] diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index a57fe3fccc7..a61fc525b19 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -47,7 +47,9 @@ use crate::std_termination::PositiveDescentAmount::OneStep; pub use crate::std_termination::{ positive_descent_amount_from_positive_int, proportional_divisor_from_int_at_least_two, }; -pub use crate::std_types::{container_param_name, is_kernel_type, kernel_type_set}; +pub use crate::std_types::{ + container_param_name, container_template_algebra, is_kernel_type, kernel_type_set, +}; pub use crate::std_types::{NonEmptyStr, SourceSpan}; pub use crate::v1_compiler_infer_access::AccessCheckResultNode; pub use crate::v1_compiler_infer_access::{check_index_access_node, check_slice_access_node}; @@ -1933,6 +1935,21 @@ pub fn set_element_types_mismatch( )) } +pub fn node_admits_list_literal( + n: Rc, + source_indices: Rc>>, +) -> bool { + (node_is_element_collection(n.clone(), source_indices.clone()) + || (((n.children.clone().len() as i64) == 1) + && match container_template_algebra(qualified_last_segment(authored_name_at( + source_indices.clone(), + n.clone(), + ))) { + Some(_) => true, + None => false, + })) +} + pub fn type_node_is_established( n: Rc, source_indices: Rc>>, @@ -4586,7 +4603,7 @@ pub fn method_pipe_map_keys_values_fallback( pub fn method_existence_wall_note() -> String { thread_local! { static CACHED: String = { - "WALL (DESIGN §5) — an unresolved method REFUSES; it never inherits the receiver type. The deleted else-arm returned recv_rt with an EMPTY diagnostic list, so an unknown method on List became another List: a success-shaped answer that survived a whole collection pipeline, stamped PlainMethodSemantics as if it had resolved. Nothing refused until InterpError::Unimplemented { what: \"method 'filter_map'\" } — whole-tree compile reported ZERO blocking errors while live dispatch returned HTTP 500 (#7479). THE DECIDABILITY PREDICATE IS THE LOAD-BEARING PART. It is PER-RECEIVER, not per-name: refuse exactly when kernel_profile_lookup returns a profile for the receiver canonical container kind, because tier0 (lookup_structural_method) has already consulted that profile algebra templates and missed — so reaching this arm with a kernel-profiled receiver PROVES the method is absent from that receiver complete declared surface. This is the same authority tier0 reads, not a second relation minted here (§3). A NAME-GRAIN PREDICATE WAS TRIED AND IS WRONG, and the receipt is worth keeping because it is subtle: gating on membership in a declared method-name roster admits any rostered name on ANY receiver, so List |> starts_with(..) and List |> to_upper() compiled clean while the diagnostic claimed the receiver was under-resolved — a fail-open with a message that also LIED about its cause, since Container(List,Primitive(Int)) is fully resolved (codex review 45327, confirmed by execution). Per-receiver closes both: those two now REFUSE. THE ONE MEASURED OBSTACLE TO PER-RECEIVER WAS A REAL §3 FORK, AND IT IS FIXED HERE RATHER THAN WORKED AROUND: free_monoid_scalar_templates omitted count while the interpreter dispatches it natively on strings (the length/count/size arm), so String |> count reached this arm and was admitted only by the fail-open — a hollow green. count is now declared on the String profile, matching the runtime, so it resolves at tier0 and never reaches here. WHAT STAYS UNDECIDED, and why refusing there would fabricate: a receiver with NO kernel profile has no complete declared surface to prove absence against. THE LARGEST MEASURED CLASS WAS NOT UNDECIDABLE AT ALL AND IS NOW DECIDED — a where-refinement alias arrived as Product(NonEmptyStr) only because resolve_method_receiver_type short-circuits on Conj and never peeled to the String base; peeling it (where_refinement_receiver_peel_note) moved 12 corpus sites out of this residue in both directions at once, resolving the correct .length() calls AND making a bogus method on a branded string a hard MethodNotFound. What remains genuinely has no surface: a lambda parameter whose type never propagates so the receiver has no authored name at all (the LexMatchThunk { apply: fn(s) } idiom in src/v2/compiler/01_tokenize.dag and the StoreObjectFold lambdas in extdeps/git/object_store.dag), a coproduct payload bound by pattern destructuring arriving typed Primitive(ok) (a correct labels |> list_push(label)), a bare type variable, and an Optional whose cardinality is dropped before lookup so the inner product is what arrives. Refusing those would red correct code, which is the mirror image of the fabricated success this wall deletes. A RECEIVER WITH NO AUTHORED NAME AT ALL is not weak evidence about the method — it is no evidence about anything, because the receiver's own type was never established upstream. That is a different judgment failure from 'this receiver has a surface and the method is not on it', so it carries its own diagnostic, ReceiverTypeUnestablished, whose message names that cause instead of implying the method is missing. THE DIAGNOSTIC NAMES THE CAUSE; THE ROSTER BOUNDS THE ADMISSION, and separating those two was a correction. The class was first admitted on the CAUSE alone — any anonymous receiver, non-blocking — on the reasoning that the wall cannot tell an existing method from a nonexistent one when the receiver has no type, so refusing would refuse both. That reasoning is sound about DECIDABILITY and wrong about ADMISSION: it made every future anonymous-receiver call green, including one whose method does not exist, so the exception was unbounded exactly where existence is unknown (codex review 45459). Counting a diagnostic does not stop invalid code reaching the live system. Admission is now gated on the same declared roster as every other unestablished shape, keyed (module, method, Primitive()), so the seven measured occurrences are admitted and a new one anywhere else REFUSES as MethodExistenceUndecided. That is a ratchet that can only shrink, and blocking a new instance of a known deficit is the factory model rather than an inconvenience. Everything that has a name but no surface stays in the same shape-keyed roster. MethodExistenceUndecided carries what is left as a typed, located, COUNTED non-blocking diagnostic (the is_error_diagnostic partition, UnlistedImportUse precedent) so the frequency stays observable and prioritizable rather than zeroed by construction — and it now means exactly ONE thing, receiver surface not established, rather than doubling as a name-grain escape. Both arms return error_type, never recv_rt, so one located refusal does not cascade downstream. AND THE WALL IS REACHED FROM EVERY ARM, WHICH IT WAS NOT AT FIRST: the decision lived inline in the final else of method_pipe_map_keys_values_fallback, so an unresolved map_keys, sorted_map_keys or map_values whose receiver is not a keyed collection took an EARLIER branch and returned recv_rt with an empty diagnostic list — the identical success-shaped fallback this wall exists to delete, preserved in the two special cases that ran before it (codex review 45430). A wall reachable only from the default arm is not a wall, and prose about the default arm cannot see the two arms in front of it. The decision is now method_existence_decision, held once and called from all three, with the control run against the prior binary rather than reasoned about: List |> map_keys and |> map_values compile with exit 0 on the pre-routing binary and produce two located MethodNotFound refusals on this one. Positive controls: map/filter/fold/flat_map resolve at tier0 and service ops at tier1, neither reaching this arm. THE UPSTREAM DEFECTS ARE NAMED BY THE MEASUREMENT, one fixed here and the rest left as promotion triggers that would each let the wall decide a further non-kernel receiver: (1) FIXED — a where-refinement alias resolving to a Product shape instead of peeling to its declared base before method lookup; (2) a lambda parameter receiver whose type never propagates from the declared fn type it is bound under; (3) a coproduct payload binding typed as the VARIANT name rather than the field type; (4) an optional receiver whose cardinality is dropped so the inner product reaches lookup in place of Optional own surface. Each is carried as a row in unresolved_method_frontier, keyed on the receiver shape that is the evidence for it, except (2) which is the ReceiverTypeUnestablished cause class above. THE INSTRUMENT WAS WRONG BEFORE THE WALL WAS, and that is the most transferable thing here: this wall was measured with `gunbc run --entry dag/tools/generated_artifact_gate.dag`, which reaches only that gate's import closure, and it reported CLEAN while twelve real sites sat outside it — they surfaced from CI instead. The whole-corpus instrument is `gunbc compile --source-root dag --source-root src/v2 --target dag`, the same compile-clean gate CI runs, and it resolves 1629 sources against 2740 indexed modules. A narrow instrument reporting clean is indistinguishable from a wall that works, which is the §5 specification-without-execution trap wearing the shape of a green run. A FOURTH SHAPE was then found and NOT fixed: a brand alias can also arrive as a plain qualified LEAF (Primitive(std.types.NonEmptyStr)) rather than the refinement Conj the peel walks. Three head-resolution strategies were implemented and measured against it — lookup_type_for on the node, lookup_type_by_name on the qualified name, and on its last segment — none recovered the refinement, so the machinery was DELETED rather than shipped unproven and the site is a declared row. Unproven machinery that decides nothing is worse than a declared row that admits what it cannot decide. Dissolve-on: primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete surface, the count-style forks are unwritable rather than hand-reconciled, and MethodExistenceUndecided is deleted.".to_string() + "WALL (DESIGN §5) — an unresolved method REFUSES; it never inherits the receiver type. The deleted else-arm returned recv_rt with an EMPTY diagnostic list, so an unknown method on List became another List: a success-shaped answer that survived a whole collection pipeline, stamped PlainMethodSemantics as if it had resolved. Nothing refused until InterpError::Unimplemented { what: \"method 'filter_map'\" } — whole-tree compile reported ZERO blocking errors while live dispatch returned HTTP 500 (#7479). THE DECIDABILITY PREDICATE IS THE LOAD-BEARING PART. It is PER-RECEIVER, not per-name: refuse exactly when kernel_profile_lookup returns a profile for the receiver canonical container kind, because tier0 (lookup_structural_method) has already consulted that profile algebra templates and missed — so reaching this arm with a kernel-profiled receiver PROVES the method is absent from that receiver complete declared surface. This is the same authority tier0 reads, not a second relation minted here (§3). A NAME-GRAIN PREDICATE WAS TRIED AND IS WRONG, and the receipt is worth keeping because it is subtle: gating on membership in a declared method-name roster admits any rostered name on ANY receiver, so List |> starts_with(..) and List |> to_upper() compiled clean while the diagnostic claimed the receiver was under-resolved — a fail-open with a message that also LIED about its cause, since Container(List,Primitive(Int)) is fully resolved (codex review 45327, confirmed by execution). Per-receiver closes both: those two now REFUSE. THE ONE MEASURED OBSTACLE TO PER-RECEIVER WAS A REAL §3 FORK, AND IT IS FIXED HERE RATHER THAN WORKED AROUND: free_monoid_scalar_templates omitted count while the interpreter dispatches it natively on strings (the length/count/size arm), so String |> count reached this arm and was admitted only by the fail-open — a hollow green. count is now declared on the String profile, matching the runtime, so it resolves at tier0 and never reaches here. WHAT STAYS UNDECIDED, and why refusing there would fabricate: a receiver with NO kernel profile has no complete declared surface to prove absence against. THE LARGEST MEASURED CLASS WAS NOT UNDECIDABLE AT ALL AND IS NOW DECIDED — a where-refinement alias arrived as Product(NonEmptyStr) only because resolve_method_receiver_type short-circuits on Conj and never peeled to the String base; peeling it (where_refinement_receiver_peel_note) moved 12 corpus sites out of this residue in both directions at once, resolving the correct .length() calls AND making a bogus method on a branded string a hard MethodNotFound. What remains genuinely has no surface: a lambda parameter whose type never propagates so the receiver has no authored name at all (the LexMatchThunk { apply: fn(s) } idiom in src/v2/compiler/01_tokenize.dag; the StoreObjectFold lambdas in extdeps/git/object_store.dag were the second instance and are RESOLVED — once a generic field's substituted type reached the field expectation and an unestablished return stopped being certified as resolved, their `map` and `flat_map` rows measured zero observed and were deleted), a coproduct payload bound by pattern destructuring arriving typed Primitive(ok) (a correct labels |> list_push(label)), a bare type variable, and an Optional whose cardinality is dropped before lookup so the inner product is what arrives. Refusing those would red correct code, which is the mirror image of the fabricated success this wall deletes. A RECEIVER WITH NO AUTHORED NAME AT ALL is not weak evidence about the method — it is no evidence about anything, because the receiver's own type was never established upstream. That is a different judgment failure from 'this receiver has a surface and the method is not on it', so it carries its own diagnostic, ReceiverTypeUnestablished, whose message names that cause instead of implying the method is missing. THE DIAGNOSTIC NAMES THE CAUSE; THE ROSTER BOUNDS THE ADMISSION, and separating those two was a correction. The class was first admitted on the CAUSE alone — any anonymous receiver, non-blocking — on the reasoning that the wall cannot tell an existing method from a nonexistent one when the receiver has no type, so refusing would refuse both. That reasoning is sound about DECIDABILITY and wrong about ADMISSION: it made every future anonymous-receiver call green, including one whose method does not exist, so the exception was unbounded exactly where existence is unknown (codex review 45459). Counting a diagnostic does not stop invalid code reaching the live system. Admission is now gated on the same declared roster as every other unestablished shape, keyed (module, method, Primitive()), so the seven measured occurrences are admitted and a new one anywhere else REFUSES as MethodExistenceUndecided. That is a ratchet that can only shrink, and blocking a new instance of a known deficit is the factory model rather than an inconvenience. Everything that has a name but no surface stays in the same shape-keyed roster. MethodExistenceUndecided carries what is left as a typed, located, COUNTED non-blocking diagnostic (the is_error_diagnostic partition, UnlistedImportUse precedent) so the frequency stays observable and prioritizable rather than zeroed by construction — and it now means exactly ONE thing, receiver surface not established, rather than doubling as a name-grain escape. Both arms return error_type, never recv_rt, so one located refusal does not cascade downstream. AND THE WALL IS REACHED FROM EVERY ARM, WHICH IT WAS NOT AT FIRST: the decision lived inline in the final else of method_pipe_map_keys_values_fallback, so an unresolved map_keys, sorted_map_keys or map_values whose receiver is not a keyed collection took an EARLIER branch and returned recv_rt with an empty diagnostic list — the identical success-shaped fallback this wall exists to delete, preserved in the two special cases that ran before it (codex review 45430). A wall reachable only from the default arm is not a wall, and prose about the default arm cannot see the two arms in front of it. The decision is now method_existence_decision, held once and called from all three, with the control run against the prior binary rather than reasoned about: List |> map_keys and |> map_values compile with exit 0 on the pre-routing binary and produce two located MethodNotFound refusals on this one. Positive controls: map/filter/fold/flat_map resolve at tier0 and service ops at tier1, neither reaching this arm. THE UPSTREAM DEFECTS ARE NAMED BY THE MEASUREMENT, one fixed here and the rest left as promotion triggers that would each let the wall decide a further non-kernel receiver: (1) FIXED — a where-refinement alias resolving to a Product shape instead of peeling to its declared base before method lookup; (2) a lambda parameter receiver whose type never propagates from the declared fn type it is bound under; (3) a coproduct payload binding typed as the VARIANT name rather than the field type; (4) an optional receiver whose cardinality is dropped so the inner product reaches lookup in place of Optional own surface. Each is carried as a row in unresolved_method_frontier, keyed on the receiver shape that is the evidence for it, except (2) which is the ReceiverTypeUnestablished cause class above. THE INSTRUMENT WAS WRONG BEFORE THE WALL WAS, and that is the most transferable thing here: this wall was measured with `gunbc run --entry dag/tools/generated_artifact_gate.dag`, which reaches only that gate's import closure, and it reported CLEAN while twelve real sites sat outside it — they surfaced from CI instead. The whole-corpus instrument is `gunbc compile --source-root dag --source-root src/v2 --target dag`, the same compile-clean gate CI runs, and it resolves 1629 sources against 2740 indexed modules. A narrow instrument reporting clean is indistinguishable from a wall that works, which is the §5 specification-without-execution trap wearing the shape of a green run. A FOURTH SHAPE was then found and NOT fixed: a brand alias can also arrive as a plain qualified LEAF (Primitive(std.types.NonEmptyStr)) rather than the refinement Conj the peel walks. Three head-resolution strategies were implemented and measured against it — lookup_type_for on the node, lookup_type_by_name on the qualified name, and on its last segment — none recovered the refinement, so the machinery was DELETED rather than shipped unproven and the site is a declared row. Unproven machinery that decides nothing is worse than a declared row that admits what it cannot decide. Dissolve-on: primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete surface, the count-style forks are unwritable rather than hand-reconciled, and MethodExistenceUndecided is deleted.".to_string() }; } CACHED.with(|c: &String| c.clone()) @@ -4619,34 +4636,6 @@ pub fn unresolved_method_frontier() -> Rc>> receiver_shape: "Primitive()".to_string(), cause: "receiver is a lambda parameter whose type is never inferred, so it arrives with NO authored name at all. The call is a product FIELD holding a callable — the LexMatchThunk { apply: fn(s) } idiom — not a method at all.".to_string(), dissolution: unbound_dissolution("lambda-parameter receiver typing, so the receiver resolves to its declared product and apply is found as a field".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.git.object_store".to_string(), - method: "map".to_string(), - occurrences: 2, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is `tree.entries` where `tree` is the parameter of a lambda stored in a StoreObjectFold record field, so the field's declared fn type never reaches the lambda's parameter and the projection off it has no established type.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.git.object_store".to_string(), - method: "flat_map".to_string(), - occurrences: 1, - receiver_shape: "Primitive()".to_string(), - cause: "same StoreObjectFold lambda-parameter shape as the `map` row above; listed separately because the key names one method on one receiver shape, never a module-wide pass.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "extdeps.mercurial".to_string(), - method: "any".to_string(), - occurrences: 3, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is an untyped parameter of a lambda stored in a fold record field, the same shape as the object_store rows.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), -}), Rc::new(UnresolvedMethodFrontierRow { - module_name: "gunbc.scm_compatibility.mercurial".to_string(), - method: "map".to_string(), - occurrences: 3, - receiver_shape: "Primitive()".to_string(), - cause: "receiver is `missing_changesets`, an untyped parameter of the `partial:` lambda in a MercurialRepositoryCompletenessFold record field.".to_string(), - dissolution: unbound_dissolution("lambda-parameter receiver typing from the declared fn type of the record field the lambda is stored in".to_string()), }), Rc::new(UnresolvedMethodFrontierRow { module_name: "extdeps.dns.domain_name".to_string(), method: "list_push".to_string(), @@ -4807,7 +4796,7 @@ pub fn frontier_occurrence_budget_diags( pub fn frontier_occurrence_budget_note() -> String { thread_local! { static CACHED: String = { - "THE COUNT IS WHAT MAKES THE FRONTIER A RATCHET INSTEAD OF AN EXEMPTION. Keying admission on (module, method, receiver_shape) bounds WHERE an unresolved call may live but not HOW MANY may live there, so a second call in the same module, on the same method, failing to resolve the same way, inherited the admission — and that is not hypothetical: the measured rows are not all singletons (v2.compiler.tokenize admits seven `apply` calls, extdeps.mercurial three `any`, gunbc.scm_compatibility.mercurial three `map`), so a row admitting seven would silently admit an eighth (codex review 45464). Each row therefore declares its MEASURED occurrence count and this fold refuses the excess, located on the first offending call. THE COMPARISON IS EQUALITY, AND IT WAS FIRST WRITTEN AS A CEILING, WHICH DID NOT RATCHET. `observed > declared` was justified here on the reasoning that a narrower compile closure sees fewer occurrences of a module's rows, so equality would red a partial build. That reasoning is WRONG about this check: it runs per MODULE, and every occurrence of a module's rows is present whenever that module is typechecked at all — a closure that omits the module never runs its rows, so there is no partial-visibility case to protect. What the ceiling actually did was let seven shrink to six while the declared seven stood, so a seventh call could return silently: a static limit, not a ratchet, and the note claimed the ratchet anyway (codex review 45491). Equality closes it in the only way that works — fixing a call reds until the declared count is lowered, which removes the headroom a reintroduction would have slipped into. Both directions are asserted in the witness, because the under-count half is the half that makes it a ratchet and it is the one an author is tempted to relax. WHY NOT A STABLE PER-OCCURRENCE KEY, which would close this exactly: std.occurrence_identity is the corpus authority for occurrence identity and its own scope law forbids filename, SourceSpan, authored name, structural Node equality and content hash as identity inputs, allocating OccurrenceId inside one graph-scoped allocator instead. An allocator-assigned integer cannot appear as a literal in a declared row, because it is not stable across compiles — so a per-occurrence key is not merely unimplemented here, it is unavailable from the authority that owns the concept. The count is the strongest bound the substrate currently supports. Dissolve-on: a content-addressed occurrence identity stable across edits (the namespace lane's containment addressing), at which point rows key on the occurrence itself and the count field deletes.".to_string() + "THE COUNT IS WHAT MAKES THE FRONTIER A RATCHET INSTEAD OF AN EXEMPTION. Keying admission on (module, method, receiver_shape) bounds WHERE an unresolved call may live but not HOW MANY may live there, so a second call in the same module, on the same method, failing to resolve the same way, inherited the admission — and that is not hypothetical: the measured rows are not all singletons (v2.compiler.tokenize admits seven `apply` calls; the extdeps.mercurial `any` and gunbc.scm_compatibility.mercurial `map` rows cited here were three apiece until the lambda-parameter receiver class was resolved and both dissolved to zero observed, so they are deleted and the surviving multi-occurrence example is tokenize's), so a row admitting seven would silently admit an eighth (codex review 45464). Each row therefore declares its MEASURED occurrence count and this fold refuses the excess, located on the first offending call. THE COMPARISON IS EQUALITY, AND IT WAS FIRST WRITTEN AS A CEILING, WHICH DID NOT RATCHET. `observed > declared` was justified here on the reasoning that a narrower compile closure sees fewer occurrences of a module's rows, so equality would red a partial build. That reasoning is WRONG about this check: it runs per MODULE, and every occurrence of a module's rows is present whenever that module is typechecked at all — a closure that omits the module never runs its rows, so there is no partial-visibility case to protect. What the ceiling actually did was let seven shrink to six while the declared seven stood, so a seventh call could return silently: a static limit, not a ratchet, and the note claimed the ratchet anyway (codex review 45491). Equality closes it in the only way that works — fixing a call reds until the declared count is lowered, which removes the headroom a reintroduction would have slipped into. Both directions are asserted in the witness, because the under-count half is the half that makes it a ratchet and it is the one an author is tempted to relax. WHY NOT A STABLE PER-OCCURRENCE KEY, which would close this exactly: std.occurrence_identity is the corpus authority for occurrence identity and its own scope law forbids filename, SourceSpan, authored name, structural Node equality and content hash as identity inputs, allocating OccurrenceId inside one graph-scoped allocator instead. An allocator-assigned integer cannot appear as a literal in a declared row, because it is not stable across compiles — so a per-occurrence key is not merely unimplemented here, it is unavailable from the authority that owns the concept. The count is the strongest bound the substrate currently supports. Dissolve-on: a content-addressed occurrence identity stable across edits (the namespace lane's containment addressing), at which point rows key on the occurrence itself and the count field deletes.".to_string() }; } CACHED.with(|c: &String| c.clone()) @@ -8074,7 +8063,7 @@ if ((call_ambiguity_cands.clone().len() as i64) > 0) { let empty_list_diags = if ((elem_results.clone().len() as i64) == 0) { match expected.clone() { Some(exp) => { - if node_is_element_collection( + if node_admits_list_literal( exp.clone(), scope.type_env.clone().source_indices.clone(), ) { From 6b6ad94f39b4f0865158798017dc16f479aa2d25 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 23 Aug 2026 00:50:33 +0000 Subject: [PATCH 14/17] (c) sibling: an UNESTABLISHED substituted param type must not bind a lambda parameter as an error type --- .probe/body.md | 103 +++ .probe/cmin/m.dag | 19 + .probe/cmin/o2/Cargo.toml | 17 + .probe/cmin/o2/src/emitted_population.rs | 6 + .probe/cmin/o2/src/lib.rs | 65 ++ .probe/cmin/o2/src/main.rs | 5 + .probe/cmin/o2/src/t_c.rs | 48 ++ .probe/cmin/o2/src/v1_rt.rs | 864 ++++++++++++++++++++++ .probe/cmin/out/Cargo.toml | 17 + .probe/cmin/out/src/emitted_population.rs | 6 + .probe/cmin/out/src/lib.rs | 65 ++ .probe/cmin/out/src/main.rs | 5 + .probe/cmin/out/src/t_c.rs | 48 ++ .probe/cmin/out/src/v1_rt.rs | 864 ++++++++++++++++++++++ .probe/crec/m.dag | 19 + .probe/crec/o2/Cargo.toml | 17 + .probe/crec/o2/src/emitted_population.rs | 6 + .probe/crec/o2/src/lib.rs | 65 ++ .probe/crec/o2/src/main.rs | 5 + .probe/crec/o2/src/t_crec.rs | 37 + .probe/crec/o2/src/v1_rt.rs | 864 ++++++++++++++++++++++ .probe/crec/out/Cargo.toml | 17 + .probe/crec/out/src/emitted_population.rs | 6 + .probe/crec/out/src/lib.rs | 65 ++ .probe/crec/out/src/main.rs | 5 + .probe/crec/out/src/t_crec.rs | 37 + .probe/crec/out/src/v1_rt.rs | 864 ++++++++++++++++++++++ .probe/ka/m.dag | 7 + .probe/ka/o2/Cargo.toml | 17 + .probe/ka/o2/src/emitted_population.rs | 6 + .probe/ka/o2/src/lib.rs | 65 ++ .probe/ka/o2/src/main.rs | 5 + .probe/ka/o2/src/probe_m.rs | 22 + .probe/ka/o2/src/v1_rt.rs | 864 ++++++++++++++++++++++ .probe/ka/out/Cargo.toml | 17 + .probe/ka/out/src/emitted_population.rs | 6 + .probe/ka/out/src/lib.rs | 65 ++ .probe/ka/out/src/main.rs | 5 + .probe/ka/out/src/probe_m.rs | 22 + .probe/ka/out/src/v1_rt.rs | 864 ++++++++++++++++++++++ .probe/kb2/m.dag | 7 + .probe/pair/m.dag | 35 + src/v1/04_infer.dag | 8 +- src/v1/stage0/src/v1_compiler_infer.rs | 27 +- 44 files changed, 6174 insertions(+), 7 deletions(-) create mode 100644 .probe/body.md create mode 100644 .probe/cmin/m.dag create mode 100644 .probe/cmin/o2/Cargo.toml create mode 100644 .probe/cmin/o2/src/emitted_population.rs create mode 100644 .probe/cmin/o2/src/lib.rs create mode 100644 .probe/cmin/o2/src/main.rs create mode 100644 .probe/cmin/o2/src/t_c.rs create mode 100644 .probe/cmin/o2/src/v1_rt.rs create mode 100644 .probe/cmin/out/Cargo.toml create mode 100644 .probe/cmin/out/src/emitted_population.rs create mode 100644 .probe/cmin/out/src/lib.rs create mode 100644 .probe/cmin/out/src/main.rs create mode 100644 .probe/cmin/out/src/t_c.rs create mode 100644 .probe/cmin/out/src/v1_rt.rs create mode 100644 .probe/crec/m.dag create mode 100644 .probe/crec/o2/Cargo.toml create mode 100644 .probe/crec/o2/src/emitted_population.rs create mode 100644 .probe/crec/o2/src/lib.rs create mode 100644 .probe/crec/o2/src/main.rs create mode 100644 .probe/crec/o2/src/t_crec.rs create mode 100644 .probe/crec/o2/src/v1_rt.rs create mode 100644 .probe/crec/out/Cargo.toml create mode 100644 .probe/crec/out/src/emitted_population.rs create mode 100644 .probe/crec/out/src/lib.rs create mode 100644 .probe/crec/out/src/main.rs create mode 100644 .probe/crec/out/src/t_crec.rs create mode 100644 .probe/crec/out/src/v1_rt.rs create mode 100644 .probe/ka/m.dag create mode 100644 .probe/ka/o2/Cargo.toml create mode 100644 .probe/ka/o2/src/emitted_population.rs create mode 100644 .probe/ka/o2/src/lib.rs create mode 100644 .probe/ka/o2/src/main.rs create mode 100644 .probe/ka/o2/src/probe_m.rs create mode 100644 .probe/ka/o2/src/v1_rt.rs create mode 100644 .probe/ka/out/Cargo.toml create mode 100644 .probe/ka/out/src/emitted_population.rs create mode 100644 .probe/ka/out/src/lib.rs create mode 100644 .probe/ka/out/src/main.rs create mode 100644 .probe/ka/out/src/probe_m.rs create mode 100644 .probe/ka/out/src/v1_rt.rs create mode 100644 .probe/kb2/m.dag create mode 100644 .probe/pair/m.dag diff --git a/.probe/body.md b/.probe/body.md new file mode 100644 index 00000000000..a5a16734824 --- /dev/null +++ b/.probe/body.md @@ -0,0 +1,103 @@ +Two below-floor fail-opens in v1 inference, closed together. Row (a) could not land without row (c), which it exposed; both are here with executing discriminating REDs and positive controls. Row (b) is deliberately **not** in this PR — it is the largest row and follows separately. + +## What is implemented + +**Row (a) — a record literal's field type is not enforced when the declaring type carries type parameters.** `type BoxI { v: Int }` — parameter declared but unused, field a plain kernel type — accepted `BoxI { v: "s" }` silently. Below floor (§4b): "values inhabit declared types" is the ordinary compiler floor, so this is not a rung. + +Cause, established by reading the producer rather than by repair-and-measure: a field carries its declared type in `sf.inferred` while `field_node_type_expr` (`children[0]`) is a stripped placeholder. `record_lit_instantiated_fields` substituted into the placeholder, so the instantiated path **preempted a working expectation with a nameless node**. Forcing a wrong-arity bailout restores the judgment on the same declaration, which is what proves preemption rather than absence. + +Discriminating RED and positive control, both executing: + +``` +BoxI { v: "s" } RC=1 type mismatch: expected 'Primitive(Int)', got 'Primitive(String)' +BoxI { v: 1 } RC=0 clean +``` + +## Row (c) — SOLVED + +**An unestablished return type must not become a lambda's body expectation.** + +Found by instrumenting the lambda arm after two hypotheses died. The measurement: + +``` +[PROBE] lambda exp shape=Node(fn) params=1 inferred=Resolved(Primitive()) +``` + +The substituted arrow's resolved return is a **nameless** node — `Primitive()`, the same spelling as the `ReceiverTypeUnestablished` class — and `is_fully_resolved` returns **true** for it, because `type_resolution_verdict` folds over children and a nameless node has none, so an empty fold yields `FullyResolved`. **Could-not-establish passes the established guard**, becomes the lambda's body expectation, and an empty list literal checked against it refuses with `expected type is not a collection`: a **fabricated refusal**, ⊥-as-ignorance used as ⊥-as-answer (§5). + +The fix is positive establishment — the discipline the method wall already uses. `type_node_is_established`: a type node with no authored name, no children and no params carries no information and must not become an expectation. The arm declines to answer where it has nothing to answer with, rather than answering with a nameless node. + +| arm | baseline | patched | +|---|---|---| +| minimal (c) repro — generic fold, `fn` field returning `R`, body `[]` | 1 diagnostic | **clean** | +| `dag/std/claim_evidence.dag` | 0 empty-list, 18 files / 11 diagnostics | **0 empty-list, 18 files / 11 diagnostics** | +| `dag/extdeps/git/object_store.dag` | 0 empty-list | **0 empty-list** | + +Source roots for the per-entry arms: `dag` **and** `src/v2`, `--entry`-scoped. + +## Residual at the same seam, found by crossing the two variables — NOT closed here + +`type_node_is_established` has two variables — nameless, and has-children — and the corner neither is obviously about is a node that is **nameless but has children**: `Container(List, Primitive())`, which the instrumentation saw 3 times. My predicate calls that established, so it becomes the expectation. Running that corner: + +``` +type Fold { a: fn(String) -> List b: fn(String) -> List } +fn use_it(i: Inf) -> List { go(i: i, f: Fold { a: fn(v) { [1] }, ... }) } + ^^^ List where List is required +``` + +| arm | baseline | patched | +|---|---|---| +| element type correct (`[v]`) | clean | clean | +| element type **wrong** (`[1]`) | **clean** | **clean** | + +**Establishment is shallow: the node has children, but its element is itself unestablished, so no mismatch is provable and the wrong element type is admitted silently.** This is pre-existing — baseline admits it identically — so it is not a regression introduced here, and it is *not* closed by this PR. + +**The residual has no author, which is why no review would surface it.** Nothing decided that a container with an unestablished element counts as established: the guard asks a shallow question, the comparison is handed a node it can prove nothing about, and the admission is whatever the structural comparison happens to do. A silently-admitting position whose admission nobody wrote is invisible to review of any individual change, because no change introduced it. + +It is stated rather than left to be found because the honest scope of (c) is **"removes a fabricated refusal at this seam"**, not "closes the class at this seam". Closing it needs a deeper *comparison*, not a deeper establishment check — widening the establishment guard can only admit fewer expectations, which is strictly more lenient. That comparison is the post-substitution generic field access lane `declared_type_conformance_note` already names as its own, and it belongs with row (b). + +## The census rows: measured, then deleted + +`object_store`'s frontier rows were **confounded** while that module also carried empty-list blockers, because a blocking error truncates the diagnostic set. With (c) fixed they fire on a clean module. Rather than edit counts to quiet CI, the declared-vs-observed numbers were measured: + +| row | declared | observed | +|---|---|---| +| `extdeps.mercurial` `any` | 3 | **0** | +| `gunbc.scm_compatibility.mercurial` `map` | 3 | **0** | +| `extdeps.git.object_store` `map` | 2 | **0** | +| `extdeps.git.object_store` `flat_map` | 1 | **0** | + +Not fewer — **fully dissolved**, which is the direction the row text distinguishes: *more* means "a new unresolved call has appeared and the receiver's type should be established rather than the count raised"; *fewer* means "the row must be lowered or deleted so the ratchet keeps its new ground." At zero the honest action is **deletion** — a row declaring a deficit that no longer exists is a false claim, and a lowered non-zero floor would leave headroom for a silent reintroduction. + +This is also independent confirmation that the repair does what the chain predicted. `method_existence_wall_note` names two live instances of the `ReceiverTypeUnestablished` lambda-parameter class: the `StoreObjectFold` lambdas in `object_store` — **now closed** — and `LexMatchThunk` in tokenize, still open and consistent with `arm_b` staying red. Two prose notes citing the deleted rows as live examples are corrected in the same diff. + +## Corpus defects the wall caught — fixed, not suppressed + +`RealizationPlan { target: ContentHash }` was handed a raw `String` at two sites, which `std.content_hash`'s own authority forbids in as many words: *"Fixtures needing stable identities hash their labels with `content_hash_of_value`, never by labeling arbitrary text as a digest."* Both now route through the sanctioned mint. These are **genuine below-floor defects**, silently admitted before this PR — the fail-open this lane exists to close. + +One false refusal I did introduce, and fixed: `EffectPlan { steps: FreeMonoid<...> }` with `steps: []`. The corpus writes both `[...]` and `[]` into `FreeMonoid` fields, so list-literal sugar is the intended inhabitant; the collection test consulted the **alias** table (surface spellings only) while `container_template_algebra_rows` — the same authority — already carries `"FreeMonoid": "FreeMonoid"`. Fixed by reading the authority that already knows, not by adding a row. + +Per-entry verification, roots `dag` + `src/v2`: `accelerator_demo_plan` **0 blocking**, `realization_width_witness_test` **0 blocking**, `extdeps/mercurial` **0 blocking**, `host_effect_plan_witness_test` at its exact baseline pair with the empty-list gone. + +## Receipts + +- `--required-regen`: `first_generation_equal=true planned=132 executed=132 declared_divergent=1 [main.rs]`. The mirror on this branch is the **emitter's own candidate**, installed rather than hand-tuned — a hand-unioned mirror is consistent-looking and unattributable. +- The tree compiles (predicate 2). Regen green alone is a fixed-point predicate over the emitter, not a validity predicate over the emitted Rust; both are stated because neither implies the other. +- Exactly one mirror differs from `origin/main` (`v1_compiler_infer.rs`), so no measurement here is a hybrid of main's emitter against these sources. +- Precondition regime: these specimens red on a **stock** binary, not only on a tree carrying a deletion. + +## Row (b), open, and the largest + +Six seams plus `Pair`. Joined this session to the `v2.compiler.tokenize` `apply` frontier row (7 occurrences) by a one-variable pair: `type Fold { delimited: fn(Thunk, Thunk) -> String }` compiles clean; `type Fold { delimited: fn(R, R) -> String }` at `Fold` refuses with `receiver type 'Primitive()' establishes no method surface`. One cause covers both halves — a type-parameter-typed position loses its type at instantiation, whether that position is a field **value** (`Box { v: T }`) or a lambda **parameter's declared type** (`open_r: R`). `LexMatchThunk` itself is concrete; the generic carrier is the algebra. + +## Instrument notes, because two of them cost real time + +- **Identical counts across two arms are not agreement — they are one instrument run twice.** A stage0 mirror patch staged in `/tmp` was destroyed by a container restart; the restore failed silently and an hour of "patched vs baseline" was baseline vs baseline, reporting 11/11 and 158/158. The `.dag` is the authority but **the mirror is what executes**; a patched `.dag` with an unpatched mirror builds clean and looks like a repair that changed nothing. +- **The whole-corpus compile now refuses by construction** rather than being SIGKILLed — `WholeCorpusCompileBudgetBelowMeasuredDemand` (`gunbc.whole_corpus_compile_admission`), which refused remotely at 7.06 GB available against 7.5 GB measured demand. Its own message names the trap: an exit-137 count is "a memorial to a killed process". Everything above is `--entry`-scoped for that reason. + +## Pairing + +The measurement of what this repair exposes is pre-registered in #8894 (population, `unexplained = 0`, file-grain join rule) **before** the exposure exists. eager-lark-892 is parked on this branch; they get the repair SHA and its parent before anything lands, so the population is never chosen after the answer is visible. The `algebra_genericity_pair` control is the chain's **terminal** red — `arm_b` red after (c) or (a) is expected and must not be weakened to green. + +Ref: parent `19f0be86dd` via merge `ca11d6f683`. No number here is carried from an earlier ref. + diff --git a/.probe/cmin/m.dag b/.probe/cmin/m.dag new file mode 100644 index 00000000000..e161f52a6e0 --- /dev/null +++ b/.probe/cmin/m.dag @@ -0,0 +1,19 @@ +module t.c +type Link { id: String } +type Inf = Applicable { link: Link } | Insufficient { why: String } +type InfFold { + applicable: fn(Link) -> R + insufficient: fn(String) -> R +} +fn inf_fold(inf: Inf, fold: InfFold) -> R { + match inf { + Applicable { link: link } => fold.applicable(link) + Insufficient { why: why } => fold.insufficient(why) + } +} +fn links(inf: Inf) -> List { + inf_fold(inf: inf, fold: InfFold { + applicable: fn(link) { [link] }, + insufficient: fn(_) { [] }, + }) +} diff --git a/.probe/cmin/o2/Cargo.toml b/.probe/cmin/o2/Cargo.toml new file mode 100644 index 00000000000..f105b3fd945 --- /dev/null +++ b/.probe/cmin/o2/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "v1_compiled" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +im = { version = "15.1", features = ["serde"] } +unicode-ident = "1" +unicode-properties = { version = "0.1", features = ["emoji"] } +serde = { version = "1", features = ["derive", "rc"] } +serde_json = "1" +stacker = "0.1" +clap = { version = "4", features = ["derive"] } +lazy_static = "1" +ureq = { version = "2", features = ["json"] } diff --git a/.probe/cmin/o2/src/emitted_population.rs b/.probe/cmin/o2/src/emitted_population.rs new file mode 100644 index 00000000000..63d35c87266 --- /dev/null +++ b/.probe/cmin/o2/src/emitted_population.rs @@ -0,0 +1,6 @@ +// Cargo.toml +// src/emitted_population.rs +// src/lib.rs +// src/main.rs +// src/t_c.rs +// src/v1_rt.rs diff --git a/.probe/cmin/o2/src/lib.rs b/.probe/cmin/o2/src/lib.rs new file mode 100644 index 00000000000..def3498783c --- /dev/null +++ b/.probe/cmin/o2/src/lib.rs @@ -0,0 +1,65 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_imports, unused_variables, unused_mut, unused_parens, dead_code, non_shorthand_field_patterns, suspicious_double_ref_op, clippy::all)] +#![deny(unreachable_patterns)] +#![recursion_limit = "256"] + +use im::{OrdSet as BTreeSet, Vector as Vec}; + +pub mod t_c; +pub mod v1_rt; + +pub struct NonEmptyVec(Vec); + +impl std::fmt::Debug for NonEmptyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("NonEmptyVec").field(&self.0).finish() + } +} + +impl Clone for NonEmptyVec { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl PartialEq for NonEmptyVec { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl NonEmptyVec { + pub fn new(items: Vec) -> Result { + if items.is_empty() { + Err("NonEmptyVec requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct NonEmptyBTreeSet(std::collections::BTreeSet); + +impl NonEmptyBTreeSet { + pub fn new(items: std::collections::BTreeSet) -> Result { + if items.is_empty() { + Err("NonEmptyBTreeSet requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn as_set(&self) -> &std::collections::BTreeSet { + &self.0 + } + + pub fn into_set(self) -> std::collections::BTreeSet { + self.0 + } +} diff --git a/.probe/cmin/o2/src/main.rs b/.probe/cmin/o2/src/main.rs new file mode 100644 index 00000000000..63177e5007e --- /dev/null +++ b/.probe/cmin/o2/src/main.rs @@ -0,0 +1,5 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_parens, clippy::all, clippy::disallowed_macros)] + +fn main() {} diff --git a/.probe/cmin/o2/src/t_c.rs b/.probe/cmin/o2/src/t_c.rs new file mode 100644 index 00000000000..6f0054fa08a --- /dev/null +++ b/.probe/cmin/o2/src/t_c.rs @@ -0,0 +1,48 @@ +// Generated by v1 compiler -- do not edit. +// Source module: t.c + +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use crate::v1_rt::{VecCompat, VecJoin}; +use std::rc::Rc; +use crate::v1_rt; +use crate::NonEmptyVec; +use crate::NonEmptyBTreeSet; +use self::Inf::*; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Link { + pub id: String, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[serde(tag = "_variant")] +pub enum Inf { + Applicable { + link: Rc, + }, + Insufficient { + why: String, + }, +} + +#[derive(Clone)] +pub struct InfFold { + pub applicable: Rc) -> R>, + pub insufficient: Rc R>, + pub _phantom: std::marker::PhantomData, +} + +pub fn inf_fold(inf: Rc, fold: Rc>) -> R { + match (*inf.clone()).clone() { + Inf::Applicable { link: link, .. } => (fold.applicable)(link.clone()), + Inf::Insufficient { why: why, .. } => (fold.insufficient)(why.clone()), +} +} + +pub fn links(inf: Rc) -> Rc>> { + inf_fold(inf.clone(), Rc::new(InfFold { + applicable: { Rc::new(move |link| Rc::new(vec![link.clone()])) }, + insufficient: { Rc::new(move |_| Rc::new(vec![])) }, + _phantom: std::marker::PhantomData, +})) +} diff --git a/.probe/cmin/o2/src/v1_rt.rs b/.probe/cmin/o2/src/v1_rt.rs new file mode 100644 index 00000000000..fb7794c32ce --- /dev/null +++ b/.probe/cmin/o2/src/v1_rt.rs @@ -0,0 +1,864 @@ +//! Runtime shims for v2 compiler intrinsic operations. +//! Generated by the v2 compiler -- do not edit. + +#![allow(unused_variables, dead_code)] + +use im::{HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +#[cfg(feature = "text_lookup_work_counter")] +thread_local! { + static TEXT_LOOKUP_CHARS_WALKED: Cell = Cell::new(0); +} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn reset_text_lookup_chars_walked() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(0)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn reset_text_lookup_chars_walked() {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn take_text_lookup_chars_walked() -> u64 { + TEXT_LOOKUP_CHARS_WALKED.with(|c| { + let walked = c.get(); + c.set(0); + walked + }) +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn take_text_lookup_chars_walked() -> u64 { 0 } + +#[cfg(feature = "text_lookup_work_counter")] +fn record_substring_chars_walked(s: &str, start: usize, take_len: usize) { + let walked = if s.is_ascii() { + take_len as u64 + } else { + (start + take_len) as u64 + }; + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + walked)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_substring_chars_walked(_s: &str, _start: usize, _take_len: usize) {} + +#[cfg(feature = "text_lookup_work_counter")] +fn record_source_chars_slice_walked(units: u64) { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + units)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_source_chars_slice_walked(_units: u64) {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn record_source_chars_index_lookup() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + 1)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn record_source_chars_index_lookup() {} + +/// Read-only silent-pick telemetry for resolution divergence census slice 2. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpPickSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, + pub chosen_module_path: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpTieSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct FnParentFirstHitSite { + pub env_module_path: String, + pub name: String, + pub parent_match_count: usize, + pub chosen_parent_module: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct SilentPickTelemetry { + pub global_bare_lcp_picks: std::vec::Vec, + pub global_bare_lcp_ties: std::vec::Vec, + pub fn_parent_first_hits: std::vec::Vec, +} + +thread_local! { + static RESOLUTION_SILENT_PICK_ENABLED: Cell = const { Cell::new(false) }; + static RESOLUTION_SILENT_PICK: RefCell = RefCell::new(SilentPickTelemetry::default()); +} + +pub fn resolution_silent_pick_enable() { + RESOLUTION_SILENT_PICK.with(|t| *t.borrow_mut() = SilentPickTelemetry::default()); + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(true)); +} + +pub fn resolution_silent_pick_disable() -> SilentPickTelemetry { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(false)); + RESOLUTION_SILENT_PICK.with(|t| std::mem::take(&mut *t.borrow_mut())) +} + +pub fn resolution_silent_pick_is_enabled() -> bool { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.get()) +} + +pub fn resolution_silent_pick_record_global_bare_lcp_pick( + env_module_path: String, + name: String, + candidate_count: i64, + chosen_module_path: String, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_picks.push(GlobalBareLcpPickSite { + env_module_path, + name, + candidate_count, + chosen_module_path, + }); + }); +} + +pub fn resolution_silent_pick_record_global_bare_lcp_tie( + env_module_path: String, + name: String, + candidate_count: i64, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_ties.push(GlobalBareLcpTieSite { + env_module_path, + name, + candidate_count, + }); + }); +} + +// NameResolutionPolicy gate (namespace-resolution-design.md 13, 8 step 4): default +// true = NamespaceOnlyY — strict unique-on-chain in the type/value path and +// exactly-one across the fn parent closure, with typed Ambiguous refusals. +// false = ImportScoped (legacy resolver, byte-for-byte). Host-side setter only; +// no .dag surface can flip it (no escape hatch — a flip is an explicit host decision). +thread_local! { + static NAME_RESOLUTION_POLICY_NAMESPACE_ONLY: Cell = const { Cell::new(true) }; +} + +pub fn name_resolution_policy_set_namespace_only(enabled: bool) { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.set(enabled)); +} + +pub fn name_resolution_policy_is_namespace_only() -> bool { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.get()) +} + +// N1a measurement arm (type-ref hit≠bind discriminator): default false = production +// fail-open path. Host-side setter only — compile_dag_diagnostic_census arms for the +// nested synthetic compile; no .dag surface can flip it (same shape as +// name_resolution_policy — no escape hatch). +thread_local! { + static TYPE_REF_HIT_NE_BIND_MEASURE: Cell = const { Cell::new(false) }; +} + +pub fn type_ref_hit_ne_bind_measure_set(enabled: bool) { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.set(enabled)); +} + +pub fn type_ref_hit_ne_bind_measure_active() -> bool { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.get()) +} + +pub fn with_type_ref_hit_ne_bind_measure(f: impl FnOnce() -> T) -> T { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|c| { + let prev = c.get(); + c.set(true); + let out = f(); + c.set(prev); + out + }) +} + +pub fn resolution_silent_pick_record_fn_parent_first_hit( + env_module_path: String, + name: String, + parent_match_count: i64, + chosen_parent_module: String, +) { + let parent_match_count = parent_match_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || parent_match_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().fn_parent_first_hits.push(FnParentFirstHitSite { + env_module_path, + name, + parent_match_count, + chosen_parent_module, + }); + }); +} + +// Vec here is im's persistent Vector (one realization with the +// interpreter's Value::List). VecCompat papers the std-Vec API deltas the +// emitter's method rows rely on (first/push/with_capacity; join via VecJoin) +// so emitted call sites stay identical across carriers. +pub trait VecCompat { + fn first(&self) -> Option<&T>; + fn push(&mut self, item: T); + fn with_capacity(capacity: usize) -> Self; +} + +impl VecCompat for Vec { + fn first(&self) -> Option<&T> { self.front() } + fn push(&mut self, item: T) { self.push_back(item); } + fn with_capacity(_capacity: usize) -> Self { Vec::new() } +} + +pub trait VecJoin { + fn join(&self, sep: &str) -> String; +} + +impl VecJoin for Vec { + fn join(&self, sep: &str) -> String { + self.iter().cloned().collect::>().join(sep) + } +} + +pub trait V2Concat { + fn v1_concat(self, other: Self) -> Self; +} + +impl V2Concat for String { + fn v1_concat(mut self, other: String) -> String { self.push_str(&other); self } +} + +impl V2Concat for Vec { + fn v1_concat(mut self, other: Vec) -> Vec { self.extend(other); self } +} + +pub fn concat(a: T, b: T) -> T { a.v1_concat(b) } + +/// Ascii-aware variant taking a precomputed `is_ascii` flag (the `RcStr` carrier fact) +/// instead of rescanning the whole string on every call -- the per-call `s.is_ascii()` +/// scan is what made repeated indexing over a large string O(n^2) (STRING-INDEX-0). +pub fn char_at_ascii_aware(s: &str, is_ascii: bool, pos: i64) -> String { + let pos = pos.max(0) as usize; + if is_ascii { + let bytes = s.as_bytes(); + if pos >= bytes.len() { return String::new(); } + return String::from(bytes[pos] as char); + } + s.chars().nth(pos).map(|ch| ch.to_string()).unwrap_or_default() +} + +pub fn char_at(s: &str, pos: i64) -> String { + char_at_ascii_aware(s, s.is_ascii(), pos) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn string_length_ascii_aware(s: &str, is_ascii: bool) -> i64 { + if is_ascii { s.len() as i64 } else { s.chars().count() as i64 } +} + +pub fn string_length(s: &str) -> i64 { + string_length_ascii_aware(s, s.is_ascii()) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn substring_ascii_aware(s: &str, is_ascii: bool, start: i64, end: i64) -> String { + let start = start.max(0) as usize; + let end = end.max(0) as usize; + if end <= start { return String::new(); } + if is_ascii { + let len = s.len(); + if start >= len { return String::new(); } + let out_end = end.min(len); + let take_len = out_end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + return s[start..out_end].to_string(); + } + let take_len = end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + s.chars().skip(start).take(take_len).collect() +} + +pub fn substring(s: &str, start: i64, end: i64) -> String { + substring_ascii_aware(s, s.is_ascii(), start, end) +} + +pub fn string_contains(s: &str, sub: String) -> bool { + s.contains(&*sub) +} + +pub fn contains(s: String, sub: String) -> bool { string_contains(&s, sub) } + +pub fn starts_with(s: String, prefix: String) -> bool { s.starts_with(&*prefix) } + +pub fn ends_with(s: String, suffix: String) -> bool { s.ends_with(&*suffix) } + +pub fn trim(s: String) -> String { s.trim().to_string() } + +pub fn count(items: Rc>) -> i64 { items.len() as i64 } + +pub fn str_eq(a: String, b: String) -> bool { a == b } + +pub fn to_string(value: i64) -> String { value.to_string() } + +/// RFC 3629 UTF-8 decode of a byte vector. Fail-closed on invalid UTF-8. +pub fn utf8_decode_bytes(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_vec()).map_err(|e| format!("invalid UTF-8 in access payload: {}", e)) +} + +pub fn clamp(val: i64, min_val: i64, max_val: i64) -> i64 { + val.clamp(min_val, max_val) +} + +pub fn lookup(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn index_by String>(list: Vec, key_fn: F) -> HashMap { + let mut map = HashMap::new(); + for item in list { let key = key_fn(&item); map.insert(key, item); } + map +} + +pub fn empty_map() -> HashMap { HashMap::new() } + +pub fn map_insert(mut map: HashMap, key: K, value: V) -> HashMap { + map.insert(key, value); map +} + +pub fn map_merge(mut base: HashMap, overlay: HashMap) -> HashMap { + base.extend(overlay); base +} + +pub fn map_get(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn map_keys(m: &HashMap) -> Vec { m.keys().cloned().collect() } + +pub fn sorted_map_keys(m: &HashMap) -> Vec { let mut keys = map_keys(m); keys.sort(); keys } + +pub fn map_is_empty(m: &HashMap) -> bool { m.is_empty() } + +// Sound identity hint (see 04_infer.dag substitute_generics): returns true => +// the two are structurally equal. The compiled realization answers with pointer +// identity (conservative: may say false when equal); never true-when-unequal, so +// callers that return the original on true preserve output structure. Owned Rc +// args (cheap refcount bump) keep the inner element pointers, so ptr_eq on the +// clones equals ptr_eq on the originals -- lets the .dag pass args by value and +// emit through the normal clone path (no all-args-by-ref emit rule needed). +pub fn rc_ptr_eq(a: Rc, b: Rc) -> bool { Rc::ptr_eq(&a, &b) } + +pub fn rc_vec_ptr_eq(a: Rc>>, b: Rc>>) -> bool { + a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| Rc::ptr_eq(x, y)) +} + +pub fn map_values(m: &HashMap) -> Vec { m.values().cloned().collect() } + +pub fn list_concat(mut a: Vec, b: Vec) -> Vec { a.extend(b); a } + +pub fn list_push(mut list: Vec, item: T) -> Vec { list.push_back(item); list } + +pub fn append(list: Rc>, item: T) -> Vec { + let mut v = (*list).clone(); + v.push_back(item); + v +} + +pub fn chars_to_string(chars: &Rc>, start: i64, end: i64) -> String { + let len = chars.len(); + let start = (start.max(0) as usize).min(len); + let end = (end.max(0) as usize).min(len).max(start); + let units = (end.saturating_sub(start)) as u64; + record_source_chars_slice_walked(units); + // Focus caches the current RRB chunk, so per-char access is contiguous-slice + // speed; a plain iter().skip(start) walks O(start) per call, which summed + // quadratically across a tokenize pass (profiled 2026-07-06). + let mut focus = chars.focus(); + let mut out = String::with_capacity(end - start); + for i in start..end { + if let Some(ch) = char::from_u32(*focus.index(i) as u32) { + out.push(ch); + } + } + out +} + +pub fn parse_int(s: String) -> Option { s.parse::().ok() } + +pub fn map_contains_key(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn map_has(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn rc_empty_set() -> Rc> { + Rc::new(BTreeSet::new()) +} + +pub fn rc_set_insert(mut s: Rc>, x: T) -> Rc> { + Rc::make_mut(&mut s).insert(x); + s +} + +pub fn rc_set_union(a: Rc>, b: Rc>) -> Rc> { + let mut out = a; + for x in b.iter().cloned() { + Rc::make_mut(&mut out).insert(x); + } + out +} + +pub fn set_contains>>(s: S, x: T) -> bool { + s.as_ref().contains(&x) +} + +pub fn reverse(list: Rc>) -> Rc> { + Rc::new(list.iter().cloned().rev().collect()) +} + +pub fn replace(s: String, from: String, to: String) -> String { + s.replace(&from, &to) +} + +// -- Rc-wrapped container operations (FF-8) --------------------------------- +// These mirror the bare Vec/HashMap functions above but operate on Rc-wrapped +// containers for O(1) clone cost. Generated code using Rc container templates +// will call these. Read-only functions (map_get, map_keys, map_values, lookup, +// map_contains_key, map_has) work with Rc via auto-deref. + +// take_owned: move out of a uniquely-held Rc; clone when shared. With every +// container realized persistently (im), the shared-arm clone is cheap +// structural sharing — an ordinary designed path, not a degradation arm, so +// no counter and no refusal (the clone-fallback guard class was deleted with +// the Rc carriers it policed). +pub fn take_owned(x: Rc) -> T { + match Rc::try_unwrap(x) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } +} + +pub fn rc_list_push(list: Rc>, item: T) -> Rc> { + let mut v = list; + Rc::make_mut(&mut v).push_back(item); + v +} + +pub fn rc_list_concat(a: Rc>, b: Rc>) -> Rc> { + let mut result = a; + Rc::make_mut(&mut result).extend(b.iter().cloned()); + result +} + +// Every rc_* update here rides a persistent carrier (im HashMap/Vector/ +// OrdSet — one realization with the interpreter's Value::Map/List/Set), so +// make_mut's clone arm is O(1) structural sharing and each update copies an +// O(log n) node path — a designed update, never a degradation arm. +pub fn rc_map_insert(map: Rc>, key: K, value: V) -> Rc> { + let mut m = map; + Rc::make_mut(&mut m).insert(key, value); + m +} + +pub fn rc_map_merge(base: Rc>, overlay: Rc>) -> Rc> { + let mut result = base; + let inner = Rc::make_mut(&mut result); + for (k, v) in overlay.iter() { + inner.insert(k.clone(), v.clone()); + } + result +} + +pub fn rc_index_by String>(list: Rc>, key_fn: F) -> Rc> { + Rc::new(list.iter().map(|v| (key_fn(v), v.clone())).collect()) +} + +pub fn rc_empty_map() -> Rc> { Rc::new(HashMap::new()) } + +impl V2Concat for Rc> { + fn v1_concat(self, other: Rc>) -> Rc> { rc_list_concat(self, other) } +} + +pub fn scan_while(s: &str, start: i64, pred: impl Fn(String) -> bool) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && pred(String::from(bytes[pos] as char)) { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if pred(ch.to_string()) { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn skip_horizontal_ws(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && (bytes[pos] == b' ' || bytes[pos] == b'\t') { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == ' ' || ch == '\t' { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn scan_to_eol(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let start = start.min(bytes.len()); + for i in start..bytes.len() { if bytes[i] == b'\n' { return i as i64; } } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == '\n' { return pos as i64; } + pos += 1; + } + pos as i64 +} + +pub fn scan_string_end(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() { + if bytes[pos] == b'\\' { pos += 2; } + else if bytes[pos] == b'\"' { return (pos + 1) as i64; } + else { pos += 1; } + } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + let mut escaped = false; + for ch in s.chars().skip(start) { + if escaped { + escaped = false; + pos += 1; + } else if ch == '\\' { + escaped = true; + pos += 1; + } else if ch == '\"' { + return (pos + 1) as i64; + } else { + pos += 1; + } + } + pos as i64 +} + +pub fn code_point(c: String) -> i64 { + c.chars().next().map(|ch| ch as i64).unwrap_or(0) +} + +pub fn from_code_point(cp: i64) -> String { + char::from_u32(cp as u32).map(|c| c.to_string()).unwrap_or_default() +} + +pub fn is_xid_start(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_start).unwrap_or(false) +} + +pub fn is_xid_continue(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_continue).unwrap_or(false) +} + +pub fn is_emoji_ident(cp: i64) -> bool { + use unicode_properties::emoji::UnicodeEmoji; + use unicode_properties::emoji::EmojiStatus; + char::from_u32(cp as u32).map(|c| matches!(c.emoji_status(), EmojiStatus::EmojiPresentation | EmojiStatus::EmojiPresentationAndModifierBase | EmojiStatus::EmojiPresentationAndEmojiComponent | EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent) && !unicode_ident::is_xid_continue(c)).unwrap_or(false) +} + +// FreeMonoid host bridge (String = FreeMonoid) — relocated from v2_std_algebra +// so the Char authority (i64 / std.types.Char) is not pinned to v2_std_nat::Nat. +pub fn freemonoid_empty() -> Rc> { + Rc::new(Vec::new()) +} + +pub fn list_snoc_item(xs: Rc>, item: T) -> Rc> { + let mut out = xs.as_ref().clone(); + out.push_back(item); + Rc::new(out) +} + +pub fn fold_list(xs: Rc>, init: A, f: F) -> A +where + F: Fn(A, T) -> A, +{ + let mut acc = init; + for item in xs.iter() { + acc = f(acc, item.clone()); + } + acc +} + +const FNV1A64_OFFSET: u64 = 0xcbf29ce484222325; +const FNV1A64_PRIME: u64 = 0x100000001b3; + +fn fnv1a64(bytes: &[u8]) -> u64 { + let mut hash = FNV1A64_OFFSET; + for b in bytes { + hash ^= *b as u64; + hash = hash.wrapping_mul(FNV1A64_PRIME); + } + hash +} + +pub type Hash = String; + +const HASH_DIGEST_LEN: usize = 16; + +pub fn is_hash_digest(s: &str) -> bool { + s.len() == HASH_DIGEST_LEN && s.bytes().all(|b| b.is_ascii_hexdigit()) +} + +fn expect_hash_digest(s: &str, arg: &str) { + if !is_hash_digest(s) { + panic!("{} must be a 16-char hex Hash digest", arg); + } +} + +/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the +/// raw gantt key=value shape (process-absolute millis and rss-mib fields) dissolves into the observation projection. +#[allow(dead_code)] +pub const GANTT_CENSUS_MARKER: &str = "[gantt]"; + +/// Mirror of `gunbc.observation_ci_render.ci_minute_switch_seconds`. +const OBS_MINUTE_SWITCH_SECONDS: u64 = 90; + +pub fn obs_human_duration(ms: u64) -> String { + if ms < 1_000 { + format!("{ms}ms") + } else if ms < OBS_MINUTE_SWITCH_SECONDS * 1_000 { + format!("{} seconds", ms / 1_000) + } else { + format!("{} minutes", ms / 60_000) + } +} + +/// Mirror of `gunbc.observation_ci_render.ci_human_elapsed`. +pub fn obs_human_elapsed(wall_nanos: u128) -> String { + if wall_nanos < 1_000_000 { + format!("{wall_nanos}ns") + } else { + obs_human_duration((wall_nanos / 1_000_000) as u64) + } +} + +fn obs_phase_emoji() -> bool { + std::env::var("GITHUB_ACTIONS").as_deref() == Ok("true") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_begin_line` — +/// `ci_event_line(Begin) ∘ ci_render_line`. Justified divergence from the +/// interpreter seed boundary used by floor prelude marks: `trace_mark` runs +/// inside compile itself (hand-synced path and interpreter intrinsic), and +/// calling back into the interpreter to render would recurse. Proven +/// byte-equal to the `.dag` oracle by the seed RED. +pub fn render_phase_begin_line_mirror(phase: &str, emoji: bool) -> String { + let glyph = if emoji { "🔄" } else { "◐" }; + format!("{glyph} started {phase}") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_concluded_line` — +/// `ci_event_line(Concluded{Done}) ∘ ci_render_line`. Same justified-divergence +/// note as `render_phase_begin_line_mirror`. +pub fn render_phase_concluded_line_mirror(phase: &str, elapsed_ms: u64, emoji: bool) -> String { + let glyph = if emoji { "✅" } else { "✓" }; + format!("{glyph} {phase} done in {}", obs_human_duration(elapsed_ms)) +} + +/// Stage-boundary trace mark — the v1-seed interim realization of the v2 per-RealizedStep +/// CostAccount (std.realization_measurement). Wired (gantt flip): projects Begin/Concluded +/// on a PhaseSegment via the observation mirrors of `ci_event_line`. Segment wall on +/// Concluded (matched `.begin`→`.done`, else delta since last mark) — never the old +/// process-absolute millis field. RSS stays on heartbeat/measurement (`ci_event_line` does +/// not project `event.rss` — explicit divergence from the deleted rss-mib field). +/// +/// **Dissolution trigger (DESIGN §6):** delete this fn, the `trace_mark` registry row in +/// `04_method.dag` (+ hand-synced twin `v1_compiler_infer_method.rs`), the nine +/// `trace_mark(...)` marks in `compile.dag` (+ hand-synced `v1_compiler_compile.rs`), and +/// the interpreter arm in `v1_interpreter.rs` when realization_measurement_loop **Phase 0** +/// (`docs/plans/realization-measurement-loop.md`) lands a `.dag` `PerformanceReceipt` +/// per-stage carrier that a floor witness consumes by execution (the same retirement event +/// as `phase_profile.rs` / `GUNBC_FLOOR_GANTT`, per `docs/plans/ci-floor-fractal-gantt.md` +/// § dissolution). Receipt = that witness green with these marks deleted and stage walls +/// still attributable from the model path. +pub fn trace_mark(label: String) { + use std::sync::{Mutex, OnceLock}; + use std::time::Instant; + static TRACE_T0: OnceLock = OnceLock::new(); + static LAST_MARK: OnceLock> = OnceLock::new(); + static OPENS: OnceLock>> = OnceLock::new(); + let t0 = TRACE_T0.get_or_init(Instant::now); + let last = LAST_MARK.get_or_init(|| Mutex::new(*t0)); + let opens = OPENS.get_or_init(|| Mutex::new(std::collections::HashMap::new())); + let emoji = obs_phase_emoji(); + let now = Instant::now(); + let _ = GANTT_CENSUS_MARKER; + if let Some(phase) = label.strip_suffix(".begin") { + if let Ok(mut map) = opens.lock() { + map.insert(phase.to_string(), now); + } + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!("{}", render_phase_begin_line_mirror(phase, emoji)); + } else if let Some(phase) = label.strip_suffix(".done") { + let elapsed_ms = { + let started = opens.lock().ok().and_then(|mut m| m.remove(phase)); + match started { + Some(t) => now.saturating_duration_since(t).as_millis() as u64, + None => { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + now.saturating_duration_since(prev).as_millis() as u64 + } + } + }; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(phase, elapsed_ms, emoji) + ); + } else { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + let elapsed_ms = now.saturating_duration_since(prev).as_millis() as u64; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(&label, elapsed_ms, emoji) + ); + } +} + +/// Content hash over raw bytes — the byte-level single authority. `atom_identity_hash` +/// is the `String` projection of this. Use this directly for arbitrary binary content +/// (e.g. an executable or serialized payload): routing bytes through `String`/ +/// `from_utf8_lossy` first collapses every invalid UTF-8 sequence to U+FFFD, so distinct +/// byte sequences would hash equal — a §5 silent-collision fail-open for content-addressing. +pub fn bytes_identity_hash(bytes: &[u8]) -> Hash { + format!("{:016x}", fnv1a64(bytes)) +} + +pub fn atom_identity_hash(s: String) -> Hash { + bytes_identity_hash(s.as_bytes()) +} + +pub fn hash_combine(a: Hash, b: Hash) -> Hash { + expect_hash_digest(&a, "a"); + expect_hash_digest(&b, "b"); + let mut bytes = a.into_bytes(); + bytes.push(0); + bytes.extend_from_slice(b.as_bytes()); + format!("{:016x}", fnv1a64(&bytes)) +} + +#[derive(Debug, Clone)] +pub struct FilesystemReadResult { + pub content: String, +} + +pub fn filesystem_read(path: String) -> FilesystemReadResult { + let content = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("failed to read {}: {}", path, e)); + FilesystemReadResult { content } +} +fn int_relu(x: i64) -> i64 { + if x > 0 { x } else { 0 } +} + +/// Opcode wire authority: `extdeps.languages.simd.kernel.relu_mul_add_wire_op_codes`. +/// Scaffold regen-sync: see `host_kernel_relu_mul_add_op_codes_scaffold_note` until feature:dag-kernel-realization-handler. +const RELU_MUL_ADD_OP_CODES: [i64; 3] = [1, 2, 3]; + +fn assert_relu_mul_add_op_codes(op_codes: &[i64], _handler: &str) { + if op_codes != RELU_MUL_ADD_OP_CODES { + panic!("unsupported op_codes in accelerator demo kernel"); + } +} + +/// Host bridge: `.dag` passes `std.numerical_contract.FmaContractionPolicy`; interpreter maps to 0/1 until target_model emit. +pub fn contiguous_loop_elementwise_float_kernel( + op_codes: &[i64], + fma_contraction_policy: i64, + a: &[f64], + b: &[f64], + c: &[f64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_float_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let elem = match fma_contraction_policy { + 0 => { + let prod = a[i] * b[i]; + prod + c[i] + }, + 1 => a[i].mul_add(b[i], c[i]), + _ => panic!("unknown fma_contraction_policy"), + }; + out.push(if elem > 0.0 { elem } else { 0.0 }); + } + out +} + +/// Integer oracle authority: `gunbc.accelerator_demo_eval` via interpreter `Int` binops (`*`/`+`). +/// Host kernel uses `wrapping_*` to mirror release interpreter overflow semantics; demo fixtures +/// stay in-range under `IntegerExact` — out-of-range inputs are outside the bit-exact bar. +pub fn contiguous_loop_elementwise_kernel( + op_codes: &[i64], + a: &[i64], + b: &[i64], + c: &[i64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let tmp = a[i].wrapping_mul(b[i]).wrapping_add(c[i]); + out.push(int_relu(tmp)); + } + out +} diff --git a/.probe/cmin/out/Cargo.toml b/.probe/cmin/out/Cargo.toml new file mode 100644 index 00000000000..f105b3fd945 --- /dev/null +++ b/.probe/cmin/out/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "v1_compiled" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +im = { version = "15.1", features = ["serde"] } +unicode-ident = "1" +unicode-properties = { version = "0.1", features = ["emoji"] } +serde = { version = "1", features = ["derive", "rc"] } +serde_json = "1" +stacker = "0.1" +clap = { version = "4", features = ["derive"] } +lazy_static = "1" +ureq = { version = "2", features = ["json"] } diff --git a/.probe/cmin/out/src/emitted_population.rs b/.probe/cmin/out/src/emitted_population.rs new file mode 100644 index 00000000000..63d35c87266 --- /dev/null +++ b/.probe/cmin/out/src/emitted_population.rs @@ -0,0 +1,6 @@ +// Cargo.toml +// src/emitted_population.rs +// src/lib.rs +// src/main.rs +// src/t_c.rs +// src/v1_rt.rs diff --git a/.probe/cmin/out/src/lib.rs b/.probe/cmin/out/src/lib.rs new file mode 100644 index 00000000000..def3498783c --- /dev/null +++ b/.probe/cmin/out/src/lib.rs @@ -0,0 +1,65 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_imports, unused_variables, unused_mut, unused_parens, dead_code, non_shorthand_field_patterns, suspicious_double_ref_op, clippy::all)] +#![deny(unreachable_patterns)] +#![recursion_limit = "256"] + +use im::{OrdSet as BTreeSet, Vector as Vec}; + +pub mod t_c; +pub mod v1_rt; + +pub struct NonEmptyVec(Vec); + +impl std::fmt::Debug for NonEmptyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("NonEmptyVec").field(&self.0).finish() + } +} + +impl Clone for NonEmptyVec { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl PartialEq for NonEmptyVec { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl NonEmptyVec { + pub fn new(items: Vec) -> Result { + if items.is_empty() { + Err("NonEmptyVec requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct NonEmptyBTreeSet(std::collections::BTreeSet); + +impl NonEmptyBTreeSet { + pub fn new(items: std::collections::BTreeSet) -> Result { + if items.is_empty() { + Err("NonEmptyBTreeSet requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn as_set(&self) -> &std::collections::BTreeSet { + &self.0 + } + + pub fn into_set(self) -> std::collections::BTreeSet { + self.0 + } +} diff --git a/.probe/cmin/out/src/main.rs b/.probe/cmin/out/src/main.rs new file mode 100644 index 00000000000..63177e5007e --- /dev/null +++ b/.probe/cmin/out/src/main.rs @@ -0,0 +1,5 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_parens, clippy::all, clippy::disallowed_macros)] + +fn main() {} diff --git a/.probe/cmin/out/src/t_c.rs b/.probe/cmin/out/src/t_c.rs new file mode 100644 index 00000000000..6f0054fa08a --- /dev/null +++ b/.probe/cmin/out/src/t_c.rs @@ -0,0 +1,48 @@ +// Generated by v1 compiler -- do not edit. +// Source module: t.c + +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use crate::v1_rt::{VecCompat, VecJoin}; +use std::rc::Rc; +use crate::v1_rt; +use crate::NonEmptyVec; +use crate::NonEmptyBTreeSet; +use self::Inf::*; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Link { + pub id: String, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[serde(tag = "_variant")] +pub enum Inf { + Applicable { + link: Rc, + }, + Insufficient { + why: String, + }, +} + +#[derive(Clone)] +pub struct InfFold { + pub applicable: Rc) -> R>, + pub insufficient: Rc R>, + pub _phantom: std::marker::PhantomData, +} + +pub fn inf_fold(inf: Rc, fold: Rc>) -> R { + match (*inf.clone()).clone() { + Inf::Applicable { link: link, .. } => (fold.applicable)(link.clone()), + Inf::Insufficient { why: why, .. } => (fold.insufficient)(why.clone()), +} +} + +pub fn links(inf: Rc) -> Rc>> { + inf_fold(inf.clone(), Rc::new(InfFold { + applicable: { Rc::new(move |link| Rc::new(vec![link.clone()])) }, + insufficient: { Rc::new(move |_| Rc::new(vec![])) }, + _phantom: std::marker::PhantomData, +})) +} diff --git a/.probe/cmin/out/src/v1_rt.rs b/.probe/cmin/out/src/v1_rt.rs new file mode 100644 index 00000000000..fb7794c32ce --- /dev/null +++ b/.probe/cmin/out/src/v1_rt.rs @@ -0,0 +1,864 @@ +//! Runtime shims for v2 compiler intrinsic operations. +//! Generated by the v2 compiler -- do not edit. + +#![allow(unused_variables, dead_code)] + +use im::{HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +#[cfg(feature = "text_lookup_work_counter")] +thread_local! { + static TEXT_LOOKUP_CHARS_WALKED: Cell = Cell::new(0); +} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn reset_text_lookup_chars_walked() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(0)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn reset_text_lookup_chars_walked() {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn take_text_lookup_chars_walked() -> u64 { + TEXT_LOOKUP_CHARS_WALKED.with(|c| { + let walked = c.get(); + c.set(0); + walked + }) +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn take_text_lookup_chars_walked() -> u64 { 0 } + +#[cfg(feature = "text_lookup_work_counter")] +fn record_substring_chars_walked(s: &str, start: usize, take_len: usize) { + let walked = if s.is_ascii() { + take_len as u64 + } else { + (start + take_len) as u64 + }; + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + walked)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_substring_chars_walked(_s: &str, _start: usize, _take_len: usize) {} + +#[cfg(feature = "text_lookup_work_counter")] +fn record_source_chars_slice_walked(units: u64) { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + units)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_source_chars_slice_walked(_units: u64) {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn record_source_chars_index_lookup() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + 1)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn record_source_chars_index_lookup() {} + +/// Read-only silent-pick telemetry for resolution divergence census slice 2. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpPickSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, + pub chosen_module_path: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpTieSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct FnParentFirstHitSite { + pub env_module_path: String, + pub name: String, + pub parent_match_count: usize, + pub chosen_parent_module: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct SilentPickTelemetry { + pub global_bare_lcp_picks: std::vec::Vec, + pub global_bare_lcp_ties: std::vec::Vec, + pub fn_parent_first_hits: std::vec::Vec, +} + +thread_local! { + static RESOLUTION_SILENT_PICK_ENABLED: Cell = const { Cell::new(false) }; + static RESOLUTION_SILENT_PICK: RefCell = RefCell::new(SilentPickTelemetry::default()); +} + +pub fn resolution_silent_pick_enable() { + RESOLUTION_SILENT_PICK.with(|t| *t.borrow_mut() = SilentPickTelemetry::default()); + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(true)); +} + +pub fn resolution_silent_pick_disable() -> SilentPickTelemetry { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(false)); + RESOLUTION_SILENT_PICK.with(|t| std::mem::take(&mut *t.borrow_mut())) +} + +pub fn resolution_silent_pick_is_enabled() -> bool { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.get()) +} + +pub fn resolution_silent_pick_record_global_bare_lcp_pick( + env_module_path: String, + name: String, + candidate_count: i64, + chosen_module_path: String, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_picks.push(GlobalBareLcpPickSite { + env_module_path, + name, + candidate_count, + chosen_module_path, + }); + }); +} + +pub fn resolution_silent_pick_record_global_bare_lcp_tie( + env_module_path: String, + name: String, + candidate_count: i64, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_ties.push(GlobalBareLcpTieSite { + env_module_path, + name, + candidate_count, + }); + }); +} + +// NameResolutionPolicy gate (namespace-resolution-design.md 13, 8 step 4): default +// true = NamespaceOnlyY — strict unique-on-chain in the type/value path and +// exactly-one across the fn parent closure, with typed Ambiguous refusals. +// false = ImportScoped (legacy resolver, byte-for-byte). Host-side setter only; +// no .dag surface can flip it (no escape hatch — a flip is an explicit host decision). +thread_local! { + static NAME_RESOLUTION_POLICY_NAMESPACE_ONLY: Cell = const { Cell::new(true) }; +} + +pub fn name_resolution_policy_set_namespace_only(enabled: bool) { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.set(enabled)); +} + +pub fn name_resolution_policy_is_namespace_only() -> bool { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.get()) +} + +// N1a measurement arm (type-ref hit≠bind discriminator): default false = production +// fail-open path. Host-side setter only — compile_dag_diagnostic_census arms for the +// nested synthetic compile; no .dag surface can flip it (same shape as +// name_resolution_policy — no escape hatch). +thread_local! { + static TYPE_REF_HIT_NE_BIND_MEASURE: Cell = const { Cell::new(false) }; +} + +pub fn type_ref_hit_ne_bind_measure_set(enabled: bool) { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.set(enabled)); +} + +pub fn type_ref_hit_ne_bind_measure_active() -> bool { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.get()) +} + +pub fn with_type_ref_hit_ne_bind_measure(f: impl FnOnce() -> T) -> T { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|c| { + let prev = c.get(); + c.set(true); + let out = f(); + c.set(prev); + out + }) +} + +pub fn resolution_silent_pick_record_fn_parent_first_hit( + env_module_path: String, + name: String, + parent_match_count: i64, + chosen_parent_module: String, +) { + let parent_match_count = parent_match_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || parent_match_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().fn_parent_first_hits.push(FnParentFirstHitSite { + env_module_path, + name, + parent_match_count, + chosen_parent_module, + }); + }); +} + +// Vec here is im's persistent Vector (one realization with the +// interpreter's Value::List). VecCompat papers the std-Vec API deltas the +// emitter's method rows rely on (first/push/with_capacity; join via VecJoin) +// so emitted call sites stay identical across carriers. +pub trait VecCompat { + fn first(&self) -> Option<&T>; + fn push(&mut self, item: T); + fn with_capacity(capacity: usize) -> Self; +} + +impl VecCompat for Vec { + fn first(&self) -> Option<&T> { self.front() } + fn push(&mut self, item: T) { self.push_back(item); } + fn with_capacity(_capacity: usize) -> Self { Vec::new() } +} + +pub trait VecJoin { + fn join(&self, sep: &str) -> String; +} + +impl VecJoin for Vec { + fn join(&self, sep: &str) -> String { + self.iter().cloned().collect::>().join(sep) + } +} + +pub trait V2Concat { + fn v1_concat(self, other: Self) -> Self; +} + +impl V2Concat for String { + fn v1_concat(mut self, other: String) -> String { self.push_str(&other); self } +} + +impl V2Concat for Vec { + fn v1_concat(mut self, other: Vec) -> Vec { self.extend(other); self } +} + +pub fn concat(a: T, b: T) -> T { a.v1_concat(b) } + +/// Ascii-aware variant taking a precomputed `is_ascii` flag (the `RcStr` carrier fact) +/// instead of rescanning the whole string on every call -- the per-call `s.is_ascii()` +/// scan is what made repeated indexing over a large string O(n^2) (STRING-INDEX-0). +pub fn char_at_ascii_aware(s: &str, is_ascii: bool, pos: i64) -> String { + let pos = pos.max(0) as usize; + if is_ascii { + let bytes = s.as_bytes(); + if pos >= bytes.len() { return String::new(); } + return String::from(bytes[pos] as char); + } + s.chars().nth(pos).map(|ch| ch.to_string()).unwrap_or_default() +} + +pub fn char_at(s: &str, pos: i64) -> String { + char_at_ascii_aware(s, s.is_ascii(), pos) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn string_length_ascii_aware(s: &str, is_ascii: bool) -> i64 { + if is_ascii { s.len() as i64 } else { s.chars().count() as i64 } +} + +pub fn string_length(s: &str) -> i64 { + string_length_ascii_aware(s, s.is_ascii()) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn substring_ascii_aware(s: &str, is_ascii: bool, start: i64, end: i64) -> String { + let start = start.max(0) as usize; + let end = end.max(0) as usize; + if end <= start { return String::new(); } + if is_ascii { + let len = s.len(); + if start >= len { return String::new(); } + let out_end = end.min(len); + let take_len = out_end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + return s[start..out_end].to_string(); + } + let take_len = end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + s.chars().skip(start).take(take_len).collect() +} + +pub fn substring(s: &str, start: i64, end: i64) -> String { + substring_ascii_aware(s, s.is_ascii(), start, end) +} + +pub fn string_contains(s: &str, sub: String) -> bool { + s.contains(&*sub) +} + +pub fn contains(s: String, sub: String) -> bool { string_contains(&s, sub) } + +pub fn starts_with(s: String, prefix: String) -> bool { s.starts_with(&*prefix) } + +pub fn ends_with(s: String, suffix: String) -> bool { s.ends_with(&*suffix) } + +pub fn trim(s: String) -> String { s.trim().to_string() } + +pub fn count(items: Rc>) -> i64 { items.len() as i64 } + +pub fn str_eq(a: String, b: String) -> bool { a == b } + +pub fn to_string(value: i64) -> String { value.to_string() } + +/// RFC 3629 UTF-8 decode of a byte vector. Fail-closed on invalid UTF-8. +pub fn utf8_decode_bytes(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_vec()).map_err(|e| format!("invalid UTF-8 in access payload: {}", e)) +} + +pub fn clamp(val: i64, min_val: i64, max_val: i64) -> i64 { + val.clamp(min_val, max_val) +} + +pub fn lookup(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn index_by String>(list: Vec, key_fn: F) -> HashMap { + let mut map = HashMap::new(); + for item in list { let key = key_fn(&item); map.insert(key, item); } + map +} + +pub fn empty_map() -> HashMap { HashMap::new() } + +pub fn map_insert(mut map: HashMap, key: K, value: V) -> HashMap { + map.insert(key, value); map +} + +pub fn map_merge(mut base: HashMap, overlay: HashMap) -> HashMap { + base.extend(overlay); base +} + +pub fn map_get(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn map_keys(m: &HashMap) -> Vec { m.keys().cloned().collect() } + +pub fn sorted_map_keys(m: &HashMap) -> Vec { let mut keys = map_keys(m); keys.sort(); keys } + +pub fn map_is_empty(m: &HashMap) -> bool { m.is_empty() } + +// Sound identity hint (see 04_infer.dag substitute_generics): returns true => +// the two are structurally equal. The compiled realization answers with pointer +// identity (conservative: may say false when equal); never true-when-unequal, so +// callers that return the original on true preserve output structure. Owned Rc +// args (cheap refcount bump) keep the inner element pointers, so ptr_eq on the +// clones equals ptr_eq on the originals -- lets the .dag pass args by value and +// emit through the normal clone path (no all-args-by-ref emit rule needed). +pub fn rc_ptr_eq(a: Rc, b: Rc) -> bool { Rc::ptr_eq(&a, &b) } + +pub fn rc_vec_ptr_eq(a: Rc>>, b: Rc>>) -> bool { + a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| Rc::ptr_eq(x, y)) +} + +pub fn map_values(m: &HashMap) -> Vec { m.values().cloned().collect() } + +pub fn list_concat(mut a: Vec, b: Vec) -> Vec { a.extend(b); a } + +pub fn list_push(mut list: Vec, item: T) -> Vec { list.push_back(item); list } + +pub fn append(list: Rc>, item: T) -> Vec { + let mut v = (*list).clone(); + v.push_back(item); + v +} + +pub fn chars_to_string(chars: &Rc>, start: i64, end: i64) -> String { + let len = chars.len(); + let start = (start.max(0) as usize).min(len); + let end = (end.max(0) as usize).min(len).max(start); + let units = (end.saturating_sub(start)) as u64; + record_source_chars_slice_walked(units); + // Focus caches the current RRB chunk, so per-char access is contiguous-slice + // speed; a plain iter().skip(start) walks O(start) per call, which summed + // quadratically across a tokenize pass (profiled 2026-07-06). + let mut focus = chars.focus(); + let mut out = String::with_capacity(end - start); + for i in start..end { + if let Some(ch) = char::from_u32(*focus.index(i) as u32) { + out.push(ch); + } + } + out +} + +pub fn parse_int(s: String) -> Option { s.parse::().ok() } + +pub fn map_contains_key(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn map_has(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn rc_empty_set() -> Rc> { + Rc::new(BTreeSet::new()) +} + +pub fn rc_set_insert(mut s: Rc>, x: T) -> Rc> { + Rc::make_mut(&mut s).insert(x); + s +} + +pub fn rc_set_union(a: Rc>, b: Rc>) -> Rc> { + let mut out = a; + for x in b.iter().cloned() { + Rc::make_mut(&mut out).insert(x); + } + out +} + +pub fn set_contains>>(s: S, x: T) -> bool { + s.as_ref().contains(&x) +} + +pub fn reverse(list: Rc>) -> Rc> { + Rc::new(list.iter().cloned().rev().collect()) +} + +pub fn replace(s: String, from: String, to: String) -> String { + s.replace(&from, &to) +} + +// -- Rc-wrapped container operations (FF-8) --------------------------------- +// These mirror the bare Vec/HashMap functions above but operate on Rc-wrapped +// containers for O(1) clone cost. Generated code using Rc container templates +// will call these. Read-only functions (map_get, map_keys, map_values, lookup, +// map_contains_key, map_has) work with Rc via auto-deref. + +// take_owned: move out of a uniquely-held Rc; clone when shared. With every +// container realized persistently (im), the shared-arm clone is cheap +// structural sharing — an ordinary designed path, not a degradation arm, so +// no counter and no refusal (the clone-fallback guard class was deleted with +// the Rc carriers it policed). +pub fn take_owned(x: Rc) -> T { + match Rc::try_unwrap(x) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } +} + +pub fn rc_list_push(list: Rc>, item: T) -> Rc> { + let mut v = list; + Rc::make_mut(&mut v).push_back(item); + v +} + +pub fn rc_list_concat(a: Rc>, b: Rc>) -> Rc> { + let mut result = a; + Rc::make_mut(&mut result).extend(b.iter().cloned()); + result +} + +// Every rc_* update here rides a persistent carrier (im HashMap/Vector/ +// OrdSet — one realization with the interpreter's Value::Map/List/Set), so +// make_mut's clone arm is O(1) structural sharing and each update copies an +// O(log n) node path — a designed update, never a degradation arm. +pub fn rc_map_insert(map: Rc>, key: K, value: V) -> Rc> { + let mut m = map; + Rc::make_mut(&mut m).insert(key, value); + m +} + +pub fn rc_map_merge(base: Rc>, overlay: Rc>) -> Rc> { + let mut result = base; + let inner = Rc::make_mut(&mut result); + for (k, v) in overlay.iter() { + inner.insert(k.clone(), v.clone()); + } + result +} + +pub fn rc_index_by String>(list: Rc>, key_fn: F) -> Rc> { + Rc::new(list.iter().map(|v| (key_fn(v), v.clone())).collect()) +} + +pub fn rc_empty_map() -> Rc> { Rc::new(HashMap::new()) } + +impl V2Concat for Rc> { + fn v1_concat(self, other: Rc>) -> Rc> { rc_list_concat(self, other) } +} + +pub fn scan_while(s: &str, start: i64, pred: impl Fn(String) -> bool) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && pred(String::from(bytes[pos] as char)) { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if pred(ch.to_string()) { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn skip_horizontal_ws(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && (bytes[pos] == b' ' || bytes[pos] == b'\t') { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == ' ' || ch == '\t' { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn scan_to_eol(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let start = start.min(bytes.len()); + for i in start..bytes.len() { if bytes[i] == b'\n' { return i as i64; } } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == '\n' { return pos as i64; } + pos += 1; + } + pos as i64 +} + +pub fn scan_string_end(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() { + if bytes[pos] == b'\\' { pos += 2; } + else if bytes[pos] == b'\"' { return (pos + 1) as i64; } + else { pos += 1; } + } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + let mut escaped = false; + for ch in s.chars().skip(start) { + if escaped { + escaped = false; + pos += 1; + } else if ch == '\\' { + escaped = true; + pos += 1; + } else if ch == '\"' { + return (pos + 1) as i64; + } else { + pos += 1; + } + } + pos as i64 +} + +pub fn code_point(c: String) -> i64 { + c.chars().next().map(|ch| ch as i64).unwrap_or(0) +} + +pub fn from_code_point(cp: i64) -> String { + char::from_u32(cp as u32).map(|c| c.to_string()).unwrap_or_default() +} + +pub fn is_xid_start(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_start).unwrap_or(false) +} + +pub fn is_xid_continue(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_continue).unwrap_or(false) +} + +pub fn is_emoji_ident(cp: i64) -> bool { + use unicode_properties::emoji::UnicodeEmoji; + use unicode_properties::emoji::EmojiStatus; + char::from_u32(cp as u32).map(|c| matches!(c.emoji_status(), EmojiStatus::EmojiPresentation | EmojiStatus::EmojiPresentationAndModifierBase | EmojiStatus::EmojiPresentationAndEmojiComponent | EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent) && !unicode_ident::is_xid_continue(c)).unwrap_or(false) +} + +// FreeMonoid host bridge (String = FreeMonoid) — relocated from v2_std_algebra +// so the Char authority (i64 / std.types.Char) is not pinned to v2_std_nat::Nat. +pub fn freemonoid_empty() -> Rc> { + Rc::new(Vec::new()) +} + +pub fn list_snoc_item(xs: Rc>, item: T) -> Rc> { + let mut out = xs.as_ref().clone(); + out.push_back(item); + Rc::new(out) +} + +pub fn fold_list(xs: Rc>, init: A, f: F) -> A +where + F: Fn(A, T) -> A, +{ + let mut acc = init; + for item in xs.iter() { + acc = f(acc, item.clone()); + } + acc +} + +const FNV1A64_OFFSET: u64 = 0xcbf29ce484222325; +const FNV1A64_PRIME: u64 = 0x100000001b3; + +fn fnv1a64(bytes: &[u8]) -> u64 { + let mut hash = FNV1A64_OFFSET; + for b in bytes { + hash ^= *b as u64; + hash = hash.wrapping_mul(FNV1A64_PRIME); + } + hash +} + +pub type Hash = String; + +const HASH_DIGEST_LEN: usize = 16; + +pub fn is_hash_digest(s: &str) -> bool { + s.len() == HASH_DIGEST_LEN && s.bytes().all(|b| b.is_ascii_hexdigit()) +} + +fn expect_hash_digest(s: &str, arg: &str) { + if !is_hash_digest(s) { + panic!("{} must be a 16-char hex Hash digest", arg); + } +} + +/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the +/// raw gantt key=value shape (process-absolute millis and rss-mib fields) dissolves into the observation projection. +#[allow(dead_code)] +pub const GANTT_CENSUS_MARKER: &str = "[gantt]"; + +/// Mirror of `gunbc.observation_ci_render.ci_minute_switch_seconds`. +const OBS_MINUTE_SWITCH_SECONDS: u64 = 90; + +pub fn obs_human_duration(ms: u64) -> String { + if ms < 1_000 { + format!("{ms}ms") + } else if ms < OBS_MINUTE_SWITCH_SECONDS * 1_000 { + format!("{} seconds", ms / 1_000) + } else { + format!("{} minutes", ms / 60_000) + } +} + +/// Mirror of `gunbc.observation_ci_render.ci_human_elapsed`. +pub fn obs_human_elapsed(wall_nanos: u128) -> String { + if wall_nanos < 1_000_000 { + format!("{wall_nanos}ns") + } else { + obs_human_duration((wall_nanos / 1_000_000) as u64) + } +} + +fn obs_phase_emoji() -> bool { + std::env::var("GITHUB_ACTIONS").as_deref() == Ok("true") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_begin_line` — +/// `ci_event_line(Begin) ∘ ci_render_line`. Justified divergence from the +/// interpreter seed boundary used by floor prelude marks: `trace_mark` runs +/// inside compile itself (hand-synced path and interpreter intrinsic), and +/// calling back into the interpreter to render would recurse. Proven +/// byte-equal to the `.dag` oracle by the seed RED. +pub fn render_phase_begin_line_mirror(phase: &str, emoji: bool) -> String { + let glyph = if emoji { "🔄" } else { "◐" }; + format!("{glyph} started {phase}") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_concluded_line` — +/// `ci_event_line(Concluded{Done}) ∘ ci_render_line`. Same justified-divergence +/// note as `render_phase_begin_line_mirror`. +pub fn render_phase_concluded_line_mirror(phase: &str, elapsed_ms: u64, emoji: bool) -> String { + let glyph = if emoji { "✅" } else { "✓" }; + format!("{glyph} {phase} done in {}", obs_human_duration(elapsed_ms)) +} + +/// Stage-boundary trace mark — the v1-seed interim realization of the v2 per-RealizedStep +/// CostAccount (std.realization_measurement). Wired (gantt flip): projects Begin/Concluded +/// on a PhaseSegment via the observation mirrors of `ci_event_line`. Segment wall on +/// Concluded (matched `.begin`→`.done`, else delta since last mark) — never the old +/// process-absolute millis field. RSS stays on heartbeat/measurement (`ci_event_line` does +/// not project `event.rss` — explicit divergence from the deleted rss-mib field). +/// +/// **Dissolution trigger (DESIGN §6):** delete this fn, the `trace_mark` registry row in +/// `04_method.dag` (+ hand-synced twin `v1_compiler_infer_method.rs`), the nine +/// `trace_mark(...)` marks in `compile.dag` (+ hand-synced `v1_compiler_compile.rs`), and +/// the interpreter arm in `v1_interpreter.rs` when realization_measurement_loop **Phase 0** +/// (`docs/plans/realization-measurement-loop.md`) lands a `.dag` `PerformanceReceipt` +/// per-stage carrier that a floor witness consumes by execution (the same retirement event +/// as `phase_profile.rs` / `GUNBC_FLOOR_GANTT`, per `docs/plans/ci-floor-fractal-gantt.md` +/// § dissolution). Receipt = that witness green with these marks deleted and stage walls +/// still attributable from the model path. +pub fn trace_mark(label: String) { + use std::sync::{Mutex, OnceLock}; + use std::time::Instant; + static TRACE_T0: OnceLock = OnceLock::new(); + static LAST_MARK: OnceLock> = OnceLock::new(); + static OPENS: OnceLock>> = OnceLock::new(); + let t0 = TRACE_T0.get_or_init(Instant::now); + let last = LAST_MARK.get_or_init(|| Mutex::new(*t0)); + let opens = OPENS.get_or_init(|| Mutex::new(std::collections::HashMap::new())); + let emoji = obs_phase_emoji(); + let now = Instant::now(); + let _ = GANTT_CENSUS_MARKER; + if let Some(phase) = label.strip_suffix(".begin") { + if let Ok(mut map) = opens.lock() { + map.insert(phase.to_string(), now); + } + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!("{}", render_phase_begin_line_mirror(phase, emoji)); + } else if let Some(phase) = label.strip_suffix(".done") { + let elapsed_ms = { + let started = opens.lock().ok().and_then(|mut m| m.remove(phase)); + match started { + Some(t) => now.saturating_duration_since(t).as_millis() as u64, + None => { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + now.saturating_duration_since(prev).as_millis() as u64 + } + } + }; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(phase, elapsed_ms, emoji) + ); + } else { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + let elapsed_ms = now.saturating_duration_since(prev).as_millis() as u64; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(&label, elapsed_ms, emoji) + ); + } +} + +/// Content hash over raw bytes — the byte-level single authority. `atom_identity_hash` +/// is the `String` projection of this. Use this directly for arbitrary binary content +/// (e.g. an executable or serialized payload): routing bytes through `String`/ +/// `from_utf8_lossy` first collapses every invalid UTF-8 sequence to U+FFFD, so distinct +/// byte sequences would hash equal — a §5 silent-collision fail-open for content-addressing. +pub fn bytes_identity_hash(bytes: &[u8]) -> Hash { + format!("{:016x}", fnv1a64(bytes)) +} + +pub fn atom_identity_hash(s: String) -> Hash { + bytes_identity_hash(s.as_bytes()) +} + +pub fn hash_combine(a: Hash, b: Hash) -> Hash { + expect_hash_digest(&a, "a"); + expect_hash_digest(&b, "b"); + let mut bytes = a.into_bytes(); + bytes.push(0); + bytes.extend_from_slice(b.as_bytes()); + format!("{:016x}", fnv1a64(&bytes)) +} + +#[derive(Debug, Clone)] +pub struct FilesystemReadResult { + pub content: String, +} + +pub fn filesystem_read(path: String) -> FilesystemReadResult { + let content = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("failed to read {}: {}", path, e)); + FilesystemReadResult { content } +} +fn int_relu(x: i64) -> i64 { + if x > 0 { x } else { 0 } +} + +/// Opcode wire authority: `extdeps.languages.simd.kernel.relu_mul_add_wire_op_codes`. +/// Scaffold regen-sync: see `host_kernel_relu_mul_add_op_codes_scaffold_note` until feature:dag-kernel-realization-handler. +const RELU_MUL_ADD_OP_CODES: [i64; 3] = [1, 2, 3]; + +fn assert_relu_mul_add_op_codes(op_codes: &[i64], _handler: &str) { + if op_codes != RELU_MUL_ADD_OP_CODES { + panic!("unsupported op_codes in accelerator demo kernel"); + } +} + +/// Host bridge: `.dag` passes `std.numerical_contract.FmaContractionPolicy`; interpreter maps to 0/1 until target_model emit. +pub fn contiguous_loop_elementwise_float_kernel( + op_codes: &[i64], + fma_contraction_policy: i64, + a: &[f64], + b: &[f64], + c: &[f64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_float_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let elem = match fma_contraction_policy { + 0 => { + let prod = a[i] * b[i]; + prod + c[i] + }, + 1 => a[i].mul_add(b[i], c[i]), + _ => panic!("unknown fma_contraction_policy"), + }; + out.push(if elem > 0.0 { elem } else { 0.0 }); + } + out +} + +/// Integer oracle authority: `gunbc.accelerator_demo_eval` via interpreter `Int` binops (`*`/`+`). +/// Host kernel uses `wrapping_*` to mirror release interpreter overflow semantics; demo fixtures +/// stay in-range under `IntegerExact` — out-of-range inputs are outside the bit-exact bar. +pub fn contiguous_loop_elementwise_kernel( + op_codes: &[i64], + a: &[i64], + b: &[i64], + c: &[i64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let tmp = a[i].wrapping_mul(b[i]).wrapping_add(c[i]); + out.push(int_relu(tmp)); + } + out +} diff --git a/.probe/crec/m.dag b/.probe/crec/m.dag new file mode 100644 index 00000000000..acbb5527357 --- /dev/null +++ b/.probe/crec/m.dag @@ -0,0 +1,19 @@ +module t.crec + +type Acc { n: Int } + +type Fold { + init: fn(Int) -> R + step: fn(R, Int) -> R +} + +fn run(f: Fold, x: Int) -> R { + f.step(f.init(x), x) +} + +fn go(x: Int) -> Acc { + run(f: Fold { + init: fn(i) { Acc { n: i } }, + step: fn(acc, i) { Acc { n: acc.n + i } }, + }, x: x) +} diff --git a/.probe/crec/o2/Cargo.toml b/.probe/crec/o2/Cargo.toml new file mode 100644 index 00000000000..f105b3fd945 --- /dev/null +++ b/.probe/crec/o2/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "v1_compiled" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +im = { version = "15.1", features = ["serde"] } +unicode-ident = "1" +unicode-properties = { version = "0.1", features = ["emoji"] } +serde = { version = "1", features = ["derive", "rc"] } +serde_json = "1" +stacker = "0.1" +clap = { version = "4", features = ["derive"] } +lazy_static = "1" +ureq = { version = "2", features = ["json"] } diff --git a/.probe/crec/o2/src/emitted_population.rs b/.probe/crec/o2/src/emitted_population.rs new file mode 100644 index 00000000000..a946d9cb2b5 --- /dev/null +++ b/.probe/crec/o2/src/emitted_population.rs @@ -0,0 +1,6 @@ +// Cargo.toml +// src/emitted_population.rs +// src/lib.rs +// src/main.rs +// src/t_crec.rs +// src/v1_rt.rs diff --git a/.probe/crec/o2/src/lib.rs b/.probe/crec/o2/src/lib.rs new file mode 100644 index 00000000000..28641effa3d --- /dev/null +++ b/.probe/crec/o2/src/lib.rs @@ -0,0 +1,65 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_imports, unused_variables, unused_mut, unused_parens, dead_code, non_shorthand_field_patterns, suspicious_double_ref_op, clippy::all)] +#![deny(unreachable_patterns)] +#![recursion_limit = "256"] + +use im::{OrdSet as BTreeSet, Vector as Vec}; + +pub mod t_crec; +pub mod v1_rt; + +pub struct NonEmptyVec(Vec); + +impl std::fmt::Debug for NonEmptyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("NonEmptyVec").field(&self.0).finish() + } +} + +impl Clone for NonEmptyVec { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl PartialEq for NonEmptyVec { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl NonEmptyVec { + pub fn new(items: Vec) -> Result { + if items.is_empty() { + Err("NonEmptyVec requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct NonEmptyBTreeSet(std::collections::BTreeSet); + +impl NonEmptyBTreeSet { + pub fn new(items: std::collections::BTreeSet) -> Result { + if items.is_empty() { + Err("NonEmptyBTreeSet requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn as_set(&self) -> &std::collections::BTreeSet { + &self.0 + } + + pub fn into_set(self) -> std::collections::BTreeSet { + self.0 + } +} diff --git a/.probe/crec/o2/src/main.rs b/.probe/crec/o2/src/main.rs new file mode 100644 index 00000000000..63177e5007e --- /dev/null +++ b/.probe/crec/o2/src/main.rs @@ -0,0 +1,5 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_parens, clippy::all, clippy::disallowed_macros)] + +fn main() {} diff --git a/.probe/crec/o2/src/t_crec.rs b/.probe/crec/o2/src/t_crec.rs new file mode 100644 index 00000000000..86eadfc7344 --- /dev/null +++ b/.probe/crec/o2/src/t_crec.rs @@ -0,0 +1,37 @@ +// Generated by v1 compiler -- do not edit. +// Source module: t.crec + +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use crate::v1_rt::{VecCompat, VecJoin}; +use std::rc::Rc; +use crate::v1_rt; +use crate::NonEmptyVec; +use crate::NonEmptyBTreeSet; + +#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Acc { + pub n: i64, +} + +#[derive(Clone)] +pub struct Fold { + pub init: Rc R>, + pub step: Rc R>, + pub _phantom: std::marker::PhantomData, +} + +pub fn run(f: Rc>, x: i64) -> R { + (f.step)((f.init)(x.clone()), x.clone()) +} + +pub fn go(x: i64) -> Acc { + run(Rc::new(Fold { + init: { Rc::new(move |i| Acc { + n: i.clone(), +}) }, + step: { Rc::new(move |acc, i| Acc { + n: (acc.n.clone() + i.clone()), +}) }, + _phantom: std::marker::PhantomData, +}), x.clone()) +} diff --git a/.probe/crec/o2/src/v1_rt.rs b/.probe/crec/o2/src/v1_rt.rs new file mode 100644 index 00000000000..fb7794c32ce --- /dev/null +++ b/.probe/crec/o2/src/v1_rt.rs @@ -0,0 +1,864 @@ +//! Runtime shims for v2 compiler intrinsic operations. +//! Generated by the v2 compiler -- do not edit. + +#![allow(unused_variables, dead_code)] + +use im::{HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +#[cfg(feature = "text_lookup_work_counter")] +thread_local! { + static TEXT_LOOKUP_CHARS_WALKED: Cell = Cell::new(0); +} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn reset_text_lookup_chars_walked() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(0)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn reset_text_lookup_chars_walked() {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn take_text_lookup_chars_walked() -> u64 { + TEXT_LOOKUP_CHARS_WALKED.with(|c| { + let walked = c.get(); + c.set(0); + walked + }) +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn take_text_lookup_chars_walked() -> u64 { 0 } + +#[cfg(feature = "text_lookup_work_counter")] +fn record_substring_chars_walked(s: &str, start: usize, take_len: usize) { + let walked = if s.is_ascii() { + take_len as u64 + } else { + (start + take_len) as u64 + }; + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + walked)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_substring_chars_walked(_s: &str, _start: usize, _take_len: usize) {} + +#[cfg(feature = "text_lookup_work_counter")] +fn record_source_chars_slice_walked(units: u64) { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + units)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_source_chars_slice_walked(_units: u64) {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn record_source_chars_index_lookup() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + 1)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn record_source_chars_index_lookup() {} + +/// Read-only silent-pick telemetry for resolution divergence census slice 2. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpPickSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, + pub chosen_module_path: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpTieSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct FnParentFirstHitSite { + pub env_module_path: String, + pub name: String, + pub parent_match_count: usize, + pub chosen_parent_module: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct SilentPickTelemetry { + pub global_bare_lcp_picks: std::vec::Vec, + pub global_bare_lcp_ties: std::vec::Vec, + pub fn_parent_first_hits: std::vec::Vec, +} + +thread_local! { + static RESOLUTION_SILENT_PICK_ENABLED: Cell = const { Cell::new(false) }; + static RESOLUTION_SILENT_PICK: RefCell = RefCell::new(SilentPickTelemetry::default()); +} + +pub fn resolution_silent_pick_enable() { + RESOLUTION_SILENT_PICK.with(|t| *t.borrow_mut() = SilentPickTelemetry::default()); + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(true)); +} + +pub fn resolution_silent_pick_disable() -> SilentPickTelemetry { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(false)); + RESOLUTION_SILENT_PICK.with(|t| std::mem::take(&mut *t.borrow_mut())) +} + +pub fn resolution_silent_pick_is_enabled() -> bool { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.get()) +} + +pub fn resolution_silent_pick_record_global_bare_lcp_pick( + env_module_path: String, + name: String, + candidate_count: i64, + chosen_module_path: String, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_picks.push(GlobalBareLcpPickSite { + env_module_path, + name, + candidate_count, + chosen_module_path, + }); + }); +} + +pub fn resolution_silent_pick_record_global_bare_lcp_tie( + env_module_path: String, + name: String, + candidate_count: i64, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_ties.push(GlobalBareLcpTieSite { + env_module_path, + name, + candidate_count, + }); + }); +} + +// NameResolutionPolicy gate (namespace-resolution-design.md 13, 8 step 4): default +// true = NamespaceOnlyY — strict unique-on-chain in the type/value path and +// exactly-one across the fn parent closure, with typed Ambiguous refusals. +// false = ImportScoped (legacy resolver, byte-for-byte). Host-side setter only; +// no .dag surface can flip it (no escape hatch — a flip is an explicit host decision). +thread_local! { + static NAME_RESOLUTION_POLICY_NAMESPACE_ONLY: Cell = const { Cell::new(true) }; +} + +pub fn name_resolution_policy_set_namespace_only(enabled: bool) { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.set(enabled)); +} + +pub fn name_resolution_policy_is_namespace_only() -> bool { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.get()) +} + +// N1a measurement arm (type-ref hit≠bind discriminator): default false = production +// fail-open path. Host-side setter only — compile_dag_diagnostic_census arms for the +// nested synthetic compile; no .dag surface can flip it (same shape as +// name_resolution_policy — no escape hatch). +thread_local! { + static TYPE_REF_HIT_NE_BIND_MEASURE: Cell = const { Cell::new(false) }; +} + +pub fn type_ref_hit_ne_bind_measure_set(enabled: bool) { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.set(enabled)); +} + +pub fn type_ref_hit_ne_bind_measure_active() -> bool { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.get()) +} + +pub fn with_type_ref_hit_ne_bind_measure(f: impl FnOnce() -> T) -> T { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|c| { + let prev = c.get(); + c.set(true); + let out = f(); + c.set(prev); + out + }) +} + +pub fn resolution_silent_pick_record_fn_parent_first_hit( + env_module_path: String, + name: String, + parent_match_count: i64, + chosen_parent_module: String, +) { + let parent_match_count = parent_match_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || parent_match_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().fn_parent_first_hits.push(FnParentFirstHitSite { + env_module_path, + name, + parent_match_count, + chosen_parent_module, + }); + }); +} + +// Vec here is im's persistent Vector (one realization with the +// interpreter's Value::List). VecCompat papers the std-Vec API deltas the +// emitter's method rows rely on (first/push/with_capacity; join via VecJoin) +// so emitted call sites stay identical across carriers. +pub trait VecCompat { + fn first(&self) -> Option<&T>; + fn push(&mut self, item: T); + fn with_capacity(capacity: usize) -> Self; +} + +impl VecCompat for Vec { + fn first(&self) -> Option<&T> { self.front() } + fn push(&mut self, item: T) { self.push_back(item); } + fn with_capacity(_capacity: usize) -> Self { Vec::new() } +} + +pub trait VecJoin { + fn join(&self, sep: &str) -> String; +} + +impl VecJoin for Vec { + fn join(&self, sep: &str) -> String { + self.iter().cloned().collect::>().join(sep) + } +} + +pub trait V2Concat { + fn v1_concat(self, other: Self) -> Self; +} + +impl V2Concat for String { + fn v1_concat(mut self, other: String) -> String { self.push_str(&other); self } +} + +impl V2Concat for Vec { + fn v1_concat(mut self, other: Vec) -> Vec { self.extend(other); self } +} + +pub fn concat(a: T, b: T) -> T { a.v1_concat(b) } + +/// Ascii-aware variant taking a precomputed `is_ascii` flag (the `RcStr` carrier fact) +/// instead of rescanning the whole string on every call -- the per-call `s.is_ascii()` +/// scan is what made repeated indexing over a large string O(n^2) (STRING-INDEX-0). +pub fn char_at_ascii_aware(s: &str, is_ascii: bool, pos: i64) -> String { + let pos = pos.max(0) as usize; + if is_ascii { + let bytes = s.as_bytes(); + if pos >= bytes.len() { return String::new(); } + return String::from(bytes[pos] as char); + } + s.chars().nth(pos).map(|ch| ch.to_string()).unwrap_or_default() +} + +pub fn char_at(s: &str, pos: i64) -> String { + char_at_ascii_aware(s, s.is_ascii(), pos) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn string_length_ascii_aware(s: &str, is_ascii: bool) -> i64 { + if is_ascii { s.len() as i64 } else { s.chars().count() as i64 } +} + +pub fn string_length(s: &str) -> i64 { + string_length_ascii_aware(s, s.is_ascii()) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn substring_ascii_aware(s: &str, is_ascii: bool, start: i64, end: i64) -> String { + let start = start.max(0) as usize; + let end = end.max(0) as usize; + if end <= start { return String::new(); } + if is_ascii { + let len = s.len(); + if start >= len { return String::new(); } + let out_end = end.min(len); + let take_len = out_end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + return s[start..out_end].to_string(); + } + let take_len = end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + s.chars().skip(start).take(take_len).collect() +} + +pub fn substring(s: &str, start: i64, end: i64) -> String { + substring_ascii_aware(s, s.is_ascii(), start, end) +} + +pub fn string_contains(s: &str, sub: String) -> bool { + s.contains(&*sub) +} + +pub fn contains(s: String, sub: String) -> bool { string_contains(&s, sub) } + +pub fn starts_with(s: String, prefix: String) -> bool { s.starts_with(&*prefix) } + +pub fn ends_with(s: String, suffix: String) -> bool { s.ends_with(&*suffix) } + +pub fn trim(s: String) -> String { s.trim().to_string() } + +pub fn count(items: Rc>) -> i64 { items.len() as i64 } + +pub fn str_eq(a: String, b: String) -> bool { a == b } + +pub fn to_string(value: i64) -> String { value.to_string() } + +/// RFC 3629 UTF-8 decode of a byte vector. Fail-closed on invalid UTF-8. +pub fn utf8_decode_bytes(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_vec()).map_err(|e| format!("invalid UTF-8 in access payload: {}", e)) +} + +pub fn clamp(val: i64, min_val: i64, max_val: i64) -> i64 { + val.clamp(min_val, max_val) +} + +pub fn lookup(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn index_by String>(list: Vec, key_fn: F) -> HashMap { + let mut map = HashMap::new(); + for item in list { let key = key_fn(&item); map.insert(key, item); } + map +} + +pub fn empty_map() -> HashMap { HashMap::new() } + +pub fn map_insert(mut map: HashMap, key: K, value: V) -> HashMap { + map.insert(key, value); map +} + +pub fn map_merge(mut base: HashMap, overlay: HashMap) -> HashMap { + base.extend(overlay); base +} + +pub fn map_get(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn map_keys(m: &HashMap) -> Vec { m.keys().cloned().collect() } + +pub fn sorted_map_keys(m: &HashMap) -> Vec { let mut keys = map_keys(m); keys.sort(); keys } + +pub fn map_is_empty(m: &HashMap) -> bool { m.is_empty() } + +// Sound identity hint (see 04_infer.dag substitute_generics): returns true => +// the two are structurally equal. The compiled realization answers with pointer +// identity (conservative: may say false when equal); never true-when-unequal, so +// callers that return the original on true preserve output structure. Owned Rc +// args (cheap refcount bump) keep the inner element pointers, so ptr_eq on the +// clones equals ptr_eq on the originals -- lets the .dag pass args by value and +// emit through the normal clone path (no all-args-by-ref emit rule needed). +pub fn rc_ptr_eq(a: Rc, b: Rc) -> bool { Rc::ptr_eq(&a, &b) } + +pub fn rc_vec_ptr_eq(a: Rc>>, b: Rc>>) -> bool { + a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| Rc::ptr_eq(x, y)) +} + +pub fn map_values(m: &HashMap) -> Vec { m.values().cloned().collect() } + +pub fn list_concat(mut a: Vec, b: Vec) -> Vec { a.extend(b); a } + +pub fn list_push(mut list: Vec, item: T) -> Vec { list.push_back(item); list } + +pub fn append(list: Rc>, item: T) -> Vec { + let mut v = (*list).clone(); + v.push_back(item); + v +} + +pub fn chars_to_string(chars: &Rc>, start: i64, end: i64) -> String { + let len = chars.len(); + let start = (start.max(0) as usize).min(len); + let end = (end.max(0) as usize).min(len).max(start); + let units = (end.saturating_sub(start)) as u64; + record_source_chars_slice_walked(units); + // Focus caches the current RRB chunk, so per-char access is contiguous-slice + // speed; a plain iter().skip(start) walks O(start) per call, which summed + // quadratically across a tokenize pass (profiled 2026-07-06). + let mut focus = chars.focus(); + let mut out = String::with_capacity(end - start); + for i in start..end { + if let Some(ch) = char::from_u32(*focus.index(i) as u32) { + out.push(ch); + } + } + out +} + +pub fn parse_int(s: String) -> Option { s.parse::().ok() } + +pub fn map_contains_key(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn map_has(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn rc_empty_set() -> Rc> { + Rc::new(BTreeSet::new()) +} + +pub fn rc_set_insert(mut s: Rc>, x: T) -> Rc> { + Rc::make_mut(&mut s).insert(x); + s +} + +pub fn rc_set_union(a: Rc>, b: Rc>) -> Rc> { + let mut out = a; + for x in b.iter().cloned() { + Rc::make_mut(&mut out).insert(x); + } + out +} + +pub fn set_contains>>(s: S, x: T) -> bool { + s.as_ref().contains(&x) +} + +pub fn reverse(list: Rc>) -> Rc> { + Rc::new(list.iter().cloned().rev().collect()) +} + +pub fn replace(s: String, from: String, to: String) -> String { + s.replace(&from, &to) +} + +// -- Rc-wrapped container operations (FF-8) --------------------------------- +// These mirror the bare Vec/HashMap functions above but operate on Rc-wrapped +// containers for O(1) clone cost. Generated code using Rc container templates +// will call these. Read-only functions (map_get, map_keys, map_values, lookup, +// map_contains_key, map_has) work with Rc via auto-deref. + +// take_owned: move out of a uniquely-held Rc; clone when shared. With every +// container realized persistently (im), the shared-arm clone is cheap +// structural sharing — an ordinary designed path, not a degradation arm, so +// no counter and no refusal (the clone-fallback guard class was deleted with +// the Rc carriers it policed). +pub fn take_owned(x: Rc) -> T { + match Rc::try_unwrap(x) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } +} + +pub fn rc_list_push(list: Rc>, item: T) -> Rc> { + let mut v = list; + Rc::make_mut(&mut v).push_back(item); + v +} + +pub fn rc_list_concat(a: Rc>, b: Rc>) -> Rc> { + let mut result = a; + Rc::make_mut(&mut result).extend(b.iter().cloned()); + result +} + +// Every rc_* update here rides a persistent carrier (im HashMap/Vector/ +// OrdSet — one realization with the interpreter's Value::Map/List/Set), so +// make_mut's clone arm is O(1) structural sharing and each update copies an +// O(log n) node path — a designed update, never a degradation arm. +pub fn rc_map_insert(map: Rc>, key: K, value: V) -> Rc> { + let mut m = map; + Rc::make_mut(&mut m).insert(key, value); + m +} + +pub fn rc_map_merge(base: Rc>, overlay: Rc>) -> Rc> { + let mut result = base; + let inner = Rc::make_mut(&mut result); + for (k, v) in overlay.iter() { + inner.insert(k.clone(), v.clone()); + } + result +} + +pub fn rc_index_by String>(list: Rc>, key_fn: F) -> Rc> { + Rc::new(list.iter().map(|v| (key_fn(v), v.clone())).collect()) +} + +pub fn rc_empty_map() -> Rc> { Rc::new(HashMap::new()) } + +impl V2Concat for Rc> { + fn v1_concat(self, other: Rc>) -> Rc> { rc_list_concat(self, other) } +} + +pub fn scan_while(s: &str, start: i64, pred: impl Fn(String) -> bool) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && pred(String::from(bytes[pos] as char)) { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if pred(ch.to_string()) { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn skip_horizontal_ws(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && (bytes[pos] == b' ' || bytes[pos] == b'\t') { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == ' ' || ch == '\t' { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn scan_to_eol(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let start = start.min(bytes.len()); + for i in start..bytes.len() { if bytes[i] == b'\n' { return i as i64; } } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == '\n' { return pos as i64; } + pos += 1; + } + pos as i64 +} + +pub fn scan_string_end(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() { + if bytes[pos] == b'\\' { pos += 2; } + else if bytes[pos] == b'\"' { return (pos + 1) as i64; } + else { pos += 1; } + } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + let mut escaped = false; + for ch in s.chars().skip(start) { + if escaped { + escaped = false; + pos += 1; + } else if ch == '\\' { + escaped = true; + pos += 1; + } else if ch == '\"' { + return (pos + 1) as i64; + } else { + pos += 1; + } + } + pos as i64 +} + +pub fn code_point(c: String) -> i64 { + c.chars().next().map(|ch| ch as i64).unwrap_or(0) +} + +pub fn from_code_point(cp: i64) -> String { + char::from_u32(cp as u32).map(|c| c.to_string()).unwrap_or_default() +} + +pub fn is_xid_start(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_start).unwrap_or(false) +} + +pub fn is_xid_continue(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_continue).unwrap_or(false) +} + +pub fn is_emoji_ident(cp: i64) -> bool { + use unicode_properties::emoji::UnicodeEmoji; + use unicode_properties::emoji::EmojiStatus; + char::from_u32(cp as u32).map(|c| matches!(c.emoji_status(), EmojiStatus::EmojiPresentation | EmojiStatus::EmojiPresentationAndModifierBase | EmojiStatus::EmojiPresentationAndEmojiComponent | EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent) && !unicode_ident::is_xid_continue(c)).unwrap_or(false) +} + +// FreeMonoid host bridge (String = FreeMonoid) — relocated from v2_std_algebra +// so the Char authority (i64 / std.types.Char) is not pinned to v2_std_nat::Nat. +pub fn freemonoid_empty() -> Rc> { + Rc::new(Vec::new()) +} + +pub fn list_snoc_item(xs: Rc>, item: T) -> Rc> { + let mut out = xs.as_ref().clone(); + out.push_back(item); + Rc::new(out) +} + +pub fn fold_list(xs: Rc>, init: A, f: F) -> A +where + F: Fn(A, T) -> A, +{ + let mut acc = init; + for item in xs.iter() { + acc = f(acc, item.clone()); + } + acc +} + +const FNV1A64_OFFSET: u64 = 0xcbf29ce484222325; +const FNV1A64_PRIME: u64 = 0x100000001b3; + +fn fnv1a64(bytes: &[u8]) -> u64 { + let mut hash = FNV1A64_OFFSET; + for b in bytes { + hash ^= *b as u64; + hash = hash.wrapping_mul(FNV1A64_PRIME); + } + hash +} + +pub type Hash = String; + +const HASH_DIGEST_LEN: usize = 16; + +pub fn is_hash_digest(s: &str) -> bool { + s.len() == HASH_DIGEST_LEN && s.bytes().all(|b| b.is_ascii_hexdigit()) +} + +fn expect_hash_digest(s: &str, arg: &str) { + if !is_hash_digest(s) { + panic!("{} must be a 16-char hex Hash digest", arg); + } +} + +/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the +/// raw gantt key=value shape (process-absolute millis and rss-mib fields) dissolves into the observation projection. +#[allow(dead_code)] +pub const GANTT_CENSUS_MARKER: &str = "[gantt]"; + +/// Mirror of `gunbc.observation_ci_render.ci_minute_switch_seconds`. +const OBS_MINUTE_SWITCH_SECONDS: u64 = 90; + +pub fn obs_human_duration(ms: u64) -> String { + if ms < 1_000 { + format!("{ms}ms") + } else if ms < OBS_MINUTE_SWITCH_SECONDS * 1_000 { + format!("{} seconds", ms / 1_000) + } else { + format!("{} minutes", ms / 60_000) + } +} + +/// Mirror of `gunbc.observation_ci_render.ci_human_elapsed`. +pub fn obs_human_elapsed(wall_nanos: u128) -> String { + if wall_nanos < 1_000_000 { + format!("{wall_nanos}ns") + } else { + obs_human_duration((wall_nanos / 1_000_000) as u64) + } +} + +fn obs_phase_emoji() -> bool { + std::env::var("GITHUB_ACTIONS").as_deref() == Ok("true") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_begin_line` — +/// `ci_event_line(Begin) ∘ ci_render_line`. Justified divergence from the +/// interpreter seed boundary used by floor prelude marks: `trace_mark` runs +/// inside compile itself (hand-synced path and interpreter intrinsic), and +/// calling back into the interpreter to render would recurse. Proven +/// byte-equal to the `.dag` oracle by the seed RED. +pub fn render_phase_begin_line_mirror(phase: &str, emoji: bool) -> String { + let glyph = if emoji { "🔄" } else { "◐" }; + format!("{glyph} started {phase}") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_concluded_line` — +/// `ci_event_line(Concluded{Done}) ∘ ci_render_line`. Same justified-divergence +/// note as `render_phase_begin_line_mirror`. +pub fn render_phase_concluded_line_mirror(phase: &str, elapsed_ms: u64, emoji: bool) -> String { + let glyph = if emoji { "✅" } else { "✓" }; + format!("{glyph} {phase} done in {}", obs_human_duration(elapsed_ms)) +} + +/// Stage-boundary trace mark — the v1-seed interim realization of the v2 per-RealizedStep +/// CostAccount (std.realization_measurement). Wired (gantt flip): projects Begin/Concluded +/// on a PhaseSegment via the observation mirrors of `ci_event_line`. Segment wall on +/// Concluded (matched `.begin`→`.done`, else delta since last mark) — never the old +/// process-absolute millis field. RSS stays on heartbeat/measurement (`ci_event_line` does +/// not project `event.rss` — explicit divergence from the deleted rss-mib field). +/// +/// **Dissolution trigger (DESIGN §6):** delete this fn, the `trace_mark` registry row in +/// `04_method.dag` (+ hand-synced twin `v1_compiler_infer_method.rs`), the nine +/// `trace_mark(...)` marks in `compile.dag` (+ hand-synced `v1_compiler_compile.rs`), and +/// the interpreter arm in `v1_interpreter.rs` when realization_measurement_loop **Phase 0** +/// (`docs/plans/realization-measurement-loop.md`) lands a `.dag` `PerformanceReceipt` +/// per-stage carrier that a floor witness consumes by execution (the same retirement event +/// as `phase_profile.rs` / `GUNBC_FLOOR_GANTT`, per `docs/plans/ci-floor-fractal-gantt.md` +/// § dissolution). Receipt = that witness green with these marks deleted and stage walls +/// still attributable from the model path. +pub fn trace_mark(label: String) { + use std::sync::{Mutex, OnceLock}; + use std::time::Instant; + static TRACE_T0: OnceLock = OnceLock::new(); + static LAST_MARK: OnceLock> = OnceLock::new(); + static OPENS: OnceLock>> = OnceLock::new(); + let t0 = TRACE_T0.get_or_init(Instant::now); + let last = LAST_MARK.get_or_init(|| Mutex::new(*t0)); + let opens = OPENS.get_or_init(|| Mutex::new(std::collections::HashMap::new())); + let emoji = obs_phase_emoji(); + let now = Instant::now(); + let _ = GANTT_CENSUS_MARKER; + if let Some(phase) = label.strip_suffix(".begin") { + if let Ok(mut map) = opens.lock() { + map.insert(phase.to_string(), now); + } + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!("{}", render_phase_begin_line_mirror(phase, emoji)); + } else if let Some(phase) = label.strip_suffix(".done") { + let elapsed_ms = { + let started = opens.lock().ok().and_then(|mut m| m.remove(phase)); + match started { + Some(t) => now.saturating_duration_since(t).as_millis() as u64, + None => { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + now.saturating_duration_since(prev).as_millis() as u64 + } + } + }; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(phase, elapsed_ms, emoji) + ); + } else { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + let elapsed_ms = now.saturating_duration_since(prev).as_millis() as u64; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(&label, elapsed_ms, emoji) + ); + } +} + +/// Content hash over raw bytes — the byte-level single authority. `atom_identity_hash` +/// is the `String` projection of this. Use this directly for arbitrary binary content +/// (e.g. an executable or serialized payload): routing bytes through `String`/ +/// `from_utf8_lossy` first collapses every invalid UTF-8 sequence to U+FFFD, so distinct +/// byte sequences would hash equal — a §5 silent-collision fail-open for content-addressing. +pub fn bytes_identity_hash(bytes: &[u8]) -> Hash { + format!("{:016x}", fnv1a64(bytes)) +} + +pub fn atom_identity_hash(s: String) -> Hash { + bytes_identity_hash(s.as_bytes()) +} + +pub fn hash_combine(a: Hash, b: Hash) -> Hash { + expect_hash_digest(&a, "a"); + expect_hash_digest(&b, "b"); + let mut bytes = a.into_bytes(); + bytes.push(0); + bytes.extend_from_slice(b.as_bytes()); + format!("{:016x}", fnv1a64(&bytes)) +} + +#[derive(Debug, Clone)] +pub struct FilesystemReadResult { + pub content: String, +} + +pub fn filesystem_read(path: String) -> FilesystemReadResult { + let content = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("failed to read {}: {}", path, e)); + FilesystemReadResult { content } +} +fn int_relu(x: i64) -> i64 { + if x > 0 { x } else { 0 } +} + +/// Opcode wire authority: `extdeps.languages.simd.kernel.relu_mul_add_wire_op_codes`. +/// Scaffold regen-sync: see `host_kernel_relu_mul_add_op_codes_scaffold_note` until feature:dag-kernel-realization-handler. +const RELU_MUL_ADD_OP_CODES: [i64; 3] = [1, 2, 3]; + +fn assert_relu_mul_add_op_codes(op_codes: &[i64], _handler: &str) { + if op_codes != RELU_MUL_ADD_OP_CODES { + panic!("unsupported op_codes in accelerator demo kernel"); + } +} + +/// Host bridge: `.dag` passes `std.numerical_contract.FmaContractionPolicy`; interpreter maps to 0/1 until target_model emit. +pub fn contiguous_loop_elementwise_float_kernel( + op_codes: &[i64], + fma_contraction_policy: i64, + a: &[f64], + b: &[f64], + c: &[f64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_float_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let elem = match fma_contraction_policy { + 0 => { + let prod = a[i] * b[i]; + prod + c[i] + }, + 1 => a[i].mul_add(b[i], c[i]), + _ => panic!("unknown fma_contraction_policy"), + }; + out.push(if elem > 0.0 { elem } else { 0.0 }); + } + out +} + +/// Integer oracle authority: `gunbc.accelerator_demo_eval` via interpreter `Int` binops (`*`/`+`). +/// Host kernel uses `wrapping_*` to mirror release interpreter overflow semantics; demo fixtures +/// stay in-range under `IntegerExact` — out-of-range inputs are outside the bit-exact bar. +pub fn contiguous_loop_elementwise_kernel( + op_codes: &[i64], + a: &[i64], + b: &[i64], + c: &[i64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let tmp = a[i].wrapping_mul(b[i]).wrapping_add(c[i]); + out.push(int_relu(tmp)); + } + out +} diff --git a/.probe/crec/out/Cargo.toml b/.probe/crec/out/Cargo.toml new file mode 100644 index 00000000000..f105b3fd945 --- /dev/null +++ b/.probe/crec/out/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "v1_compiled" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +im = { version = "15.1", features = ["serde"] } +unicode-ident = "1" +unicode-properties = { version = "0.1", features = ["emoji"] } +serde = { version = "1", features = ["derive", "rc"] } +serde_json = "1" +stacker = "0.1" +clap = { version = "4", features = ["derive"] } +lazy_static = "1" +ureq = { version = "2", features = ["json"] } diff --git a/.probe/crec/out/src/emitted_population.rs b/.probe/crec/out/src/emitted_population.rs new file mode 100644 index 00000000000..a946d9cb2b5 --- /dev/null +++ b/.probe/crec/out/src/emitted_population.rs @@ -0,0 +1,6 @@ +// Cargo.toml +// src/emitted_population.rs +// src/lib.rs +// src/main.rs +// src/t_crec.rs +// src/v1_rt.rs diff --git a/.probe/crec/out/src/lib.rs b/.probe/crec/out/src/lib.rs new file mode 100644 index 00000000000..28641effa3d --- /dev/null +++ b/.probe/crec/out/src/lib.rs @@ -0,0 +1,65 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_imports, unused_variables, unused_mut, unused_parens, dead_code, non_shorthand_field_patterns, suspicious_double_ref_op, clippy::all)] +#![deny(unreachable_patterns)] +#![recursion_limit = "256"] + +use im::{OrdSet as BTreeSet, Vector as Vec}; + +pub mod t_crec; +pub mod v1_rt; + +pub struct NonEmptyVec(Vec); + +impl std::fmt::Debug for NonEmptyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("NonEmptyVec").field(&self.0).finish() + } +} + +impl Clone for NonEmptyVec { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl PartialEq for NonEmptyVec { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl NonEmptyVec { + pub fn new(items: Vec) -> Result { + if items.is_empty() { + Err("NonEmptyVec requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct NonEmptyBTreeSet(std::collections::BTreeSet); + +impl NonEmptyBTreeSet { + pub fn new(items: std::collections::BTreeSet) -> Result { + if items.is_empty() { + Err("NonEmptyBTreeSet requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn as_set(&self) -> &std::collections::BTreeSet { + &self.0 + } + + pub fn into_set(self) -> std::collections::BTreeSet { + self.0 + } +} diff --git a/.probe/crec/out/src/main.rs b/.probe/crec/out/src/main.rs new file mode 100644 index 00000000000..63177e5007e --- /dev/null +++ b/.probe/crec/out/src/main.rs @@ -0,0 +1,5 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_parens, clippy::all, clippy::disallowed_macros)] + +fn main() {} diff --git a/.probe/crec/out/src/t_crec.rs b/.probe/crec/out/src/t_crec.rs new file mode 100644 index 00000000000..270227dbda3 --- /dev/null +++ b/.probe/crec/out/src/t_crec.rs @@ -0,0 +1,37 @@ +// Generated by v1 compiler -- do not edit. +// Source module: t.crec + +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use crate::v1_rt::{VecCompat, VecJoin}; +use std::rc::Rc; +use crate::v1_rt; +use crate::NonEmptyVec; +use crate::NonEmptyBTreeSet; + +#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Acc { + pub n: i64, +} + +#[derive(Clone)] +pub struct Fold { + pub init: Rc R>, + pub step: Rc R>, + pub _phantom: std::marker::PhantomData, +} + +pub fn run(f: Rc>, x: i64) -> R { + (f.step)((f.init)(x.clone()), x.clone()) +} + +pub fn go(x: i64) -> Acc { + run(Rc::new(Fold { + init: { Rc::new(move |i| Acc { + n: i.clone(), +}) }, + step: { Rc::new(move |acc, i| Acc { + n: (panic!("error type cascade") + i.clone()), +}) }, + _phantom: std::marker::PhantomData, +}), x.clone()) +} diff --git a/.probe/crec/out/src/v1_rt.rs b/.probe/crec/out/src/v1_rt.rs new file mode 100644 index 00000000000..fb7794c32ce --- /dev/null +++ b/.probe/crec/out/src/v1_rt.rs @@ -0,0 +1,864 @@ +//! Runtime shims for v2 compiler intrinsic operations. +//! Generated by the v2 compiler -- do not edit. + +#![allow(unused_variables, dead_code)] + +use im::{HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +#[cfg(feature = "text_lookup_work_counter")] +thread_local! { + static TEXT_LOOKUP_CHARS_WALKED: Cell = Cell::new(0); +} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn reset_text_lookup_chars_walked() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(0)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn reset_text_lookup_chars_walked() {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn take_text_lookup_chars_walked() -> u64 { + TEXT_LOOKUP_CHARS_WALKED.with(|c| { + let walked = c.get(); + c.set(0); + walked + }) +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn take_text_lookup_chars_walked() -> u64 { 0 } + +#[cfg(feature = "text_lookup_work_counter")] +fn record_substring_chars_walked(s: &str, start: usize, take_len: usize) { + let walked = if s.is_ascii() { + take_len as u64 + } else { + (start + take_len) as u64 + }; + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + walked)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_substring_chars_walked(_s: &str, _start: usize, _take_len: usize) {} + +#[cfg(feature = "text_lookup_work_counter")] +fn record_source_chars_slice_walked(units: u64) { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + units)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_source_chars_slice_walked(_units: u64) {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn record_source_chars_index_lookup() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + 1)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn record_source_chars_index_lookup() {} + +/// Read-only silent-pick telemetry for resolution divergence census slice 2. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpPickSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, + pub chosen_module_path: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpTieSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct FnParentFirstHitSite { + pub env_module_path: String, + pub name: String, + pub parent_match_count: usize, + pub chosen_parent_module: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct SilentPickTelemetry { + pub global_bare_lcp_picks: std::vec::Vec, + pub global_bare_lcp_ties: std::vec::Vec, + pub fn_parent_first_hits: std::vec::Vec, +} + +thread_local! { + static RESOLUTION_SILENT_PICK_ENABLED: Cell = const { Cell::new(false) }; + static RESOLUTION_SILENT_PICK: RefCell = RefCell::new(SilentPickTelemetry::default()); +} + +pub fn resolution_silent_pick_enable() { + RESOLUTION_SILENT_PICK.with(|t| *t.borrow_mut() = SilentPickTelemetry::default()); + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(true)); +} + +pub fn resolution_silent_pick_disable() -> SilentPickTelemetry { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(false)); + RESOLUTION_SILENT_PICK.with(|t| std::mem::take(&mut *t.borrow_mut())) +} + +pub fn resolution_silent_pick_is_enabled() -> bool { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.get()) +} + +pub fn resolution_silent_pick_record_global_bare_lcp_pick( + env_module_path: String, + name: String, + candidate_count: i64, + chosen_module_path: String, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_picks.push(GlobalBareLcpPickSite { + env_module_path, + name, + candidate_count, + chosen_module_path, + }); + }); +} + +pub fn resolution_silent_pick_record_global_bare_lcp_tie( + env_module_path: String, + name: String, + candidate_count: i64, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_ties.push(GlobalBareLcpTieSite { + env_module_path, + name, + candidate_count, + }); + }); +} + +// NameResolutionPolicy gate (namespace-resolution-design.md 13, 8 step 4): default +// true = NamespaceOnlyY — strict unique-on-chain in the type/value path and +// exactly-one across the fn parent closure, with typed Ambiguous refusals. +// false = ImportScoped (legacy resolver, byte-for-byte). Host-side setter only; +// no .dag surface can flip it (no escape hatch — a flip is an explicit host decision). +thread_local! { + static NAME_RESOLUTION_POLICY_NAMESPACE_ONLY: Cell = const { Cell::new(true) }; +} + +pub fn name_resolution_policy_set_namespace_only(enabled: bool) { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.set(enabled)); +} + +pub fn name_resolution_policy_is_namespace_only() -> bool { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.get()) +} + +// N1a measurement arm (type-ref hit≠bind discriminator): default false = production +// fail-open path. Host-side setter only — compile_dag_diagnostic_census arms for the +// nested synthetic compile; no .dag surface can flip it (same shape as +// name_resolution_policy — no escape hatch). +thread_local! { + static TYPE_REF_HIT_NE_BIND_MEASURE: Cell = const { Cell::new(false) }; +} + +pub fn type_ref_hit_ne_bind_measure_set(enabled: bool) { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.set(enabled)); +} + +pub fn type_ref_hit_ne_bind_measure_active() -> bool { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.get()) +} + +pub fn with_type_ref_hit_ne_bind_measure(f: impl FnOnce() -> T) -> T { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|c| { + let prev = c.get(); + c.set(true); + let out = f(); + c.set(prev); + out + }) +} + +pub fn resolution_silent_pick_record_fn_parent_first_hit( + env_module_path: String, + name: String, + parent_match_count: i64, + chosen_parent_module: String, +) { + let parent_match_count = parent_match_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || parent_match_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().fn_parent_first_hits.push(FnParentFirstHitSite { + env_module_path, + name, + parent_match_count, + chosen_parent_module, + }); + }); +} + +// Vec here is im's persistent Vector (one realization with the +// interpreter's Value::List). VecCompat papers the std-Vec API deltas the +// emitter's method rows rely on (first/push/with_capacity; join via VecJoin) +// so emitted call sites stay identical across carriers. +pub trait VecCompat { + fn first(&self) -> Option<&T>; + fn push(&mut self, item: T); + fn with_capacity(capacity: usize) -> Self; +} + +impl VecCompat for Vec { + fn first(&self) -> Option<&T> { self.front() } + fn push(&mut self, item: T) { self.push_back(item); } + fn with_capacity(_capacity: usize) -> Self { Vec::new() } +} + +pub trait VecJoin { + fn join(&self, sep: &str) -> String; +} + +impl VecJoin for Vec { + fn join(&self, sep: &str) -> String { + self.iter().cloned().collect::>().join(sep) + } +} + +pub trait V2Concat { + fn v1_concat(self, other: Self) -> Self; +} + +impl V2Concat for String { + fn v1_concat(mut self, other: String) -> String { self.push_str(&other); self } +} + +impl V2Concat for Vec { + fn v1_concat(mut self, other: Vec) -> Vec { self.extend(other); self } +} + +pub fn concat(a: T, b: T) -> T { a.v1_concat(b) } + +/// Ascii-aware variant taking a precomputed `is_ascii` flag (the `RcStr` carrier fact) +/// instead of rescanning the whole string on every call -- the per-call `s.is_ascii()` +/// scan is what made repeated indexing over a large string O(n^2) (STRING-INDEX-0). +pub fn char_at_ascii_aware(s: &str, is_ascii: bool, pos: i64) -> String { + let pos = pos.max(0) as usize; + if is_ascii { + let bytes = s.as_bytes(); + if pos >= bytes.len() { return String::new(); } + return String::from(bytes[pos] as char); + } + s.chars().nth(pos).map(|ch| ch.to_string()).unwrap_or_default() +} + +pub fn char_at(s: &str, pos: i64) -> String { + char_at_ascii_aware(s, s.is_ascii(), pos) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn string_length_ascii_aware(s: &str, is_ascii: bool) -> i64 { + if is_ascii { s.len() as i64 } else { s.chars().count() as i64 } +} + +pub fn string_length(s: &str) -> i64 { + string_length_ascii_aware(s, s.is_ascii()) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn substring_ascii_aware(s: &str, is_ascii: bool, start: i64, end: i64) -> String { + let start = start.max(0) as usize; + let end = end.max(0) as usize; + if end <= start { return String::new(); } + if is_ascii { + let len = s.len(); + if start >= len { return String::new(); } + let out_end = end.min(len); + let take_len = out_end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + return s[start..out_end].to_string(); + } + let take_len = end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + s.chars().skip(start).take(take_len).collect() +} + +pub fn substring(s: &str, start: i64, end: i64) -> String { + substring_ascii_aware(s, s.is_ascii(), start, end) +} + +pub fn string_contains(s: &str, sub: String) -> bool { + s.contains(&*sub) +} + +pub fn contains(s: String, sub: String) -> bool { string_contains(&s, sub) } + +pub fn starts_with(s: String, prefix: String) -> bool { s.starts_with(&*prefix) } + +pub fn ends_with(s: String, suffix: String) -> bool { s.ends_with(&*suffix) } + +pub fn trim(s: String) -> String { s.trim().to_string() } + +pub fn count(items: Rc>) -> i64 { items.len() as i64 } + +pub fn str_eq(a: String, b: String) -> bool { a == b } + +pub fn to_string(value: i64) -> String { value.to_string() } + +/// RFC 3629 UTF-8 decode of a byte vector. Fail-closed on invalid UTF-8. +pub fn utf8_decode_bytes(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_vec()).map_err(|e| format!("invalid UTF-8 in access payload: {}", e)) +} + +pub fn clamp(val: i64, min_val: i64, max_val: i64) -> i64 { + val.clamp(min_val, max_val) +} + +pub fn lookup(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn index_by String>(list: Vec, key_fn: F) -> HashMap { + let mut map = HashMap::new(); + for item in list { let key = key_fn(&item); map.insert(key, item); } + map +} + +pub fn empty_map() -> HashMap { HashMap::new() } + +pub fn map_insert(mut map: HashMap, key: K, value: V) -> HashMap { + map.insert(key, value); map +} + +pub fn map_merge(mut base: HashMap, overlay: HashMap) -> HashMap { + base.extend(overlay); base +} + +pub fn map_get(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn map_keys(m: &HashMap) -> Vec { m.keys().cloned().collect() } + +pub fn sorted_map_keys(m: &HashMap) -> Vec { let mut keys = map_keys(m); keys.sort(); keys } + +pub fn map_is_empty(m: &HashMap) -> bool { m.is_empty() } + +// Sound identity hint (see 04_infer.dag substitute_generics): returns true => +// the two are structurally equal. The compiled realization answers with pointer +// identity (conservative: may say false when equal); never true-when-unequal, so +// callers that return the original on true preserve output structure. Owned Rc +// args (cheap refcount bump) keep the inner element pointers, so ptr_eq on the +// clones equals ptr_eq on the originals -- lets the .dag pass args by value and +// emit through the normal clone path (no all-args-by-ref emit rule needed). +pub fn rc_ptr_eq(a: Rc, b: Rc) -> bool { Rc::ptr_eq(&a, &b) } + +pub fn rc_vec_ptr_eq(a: Rc>>, b: Rc>>) -> bool { + a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| Rc::ptr_eq(x, y)) +} + +pub fn map_values(m: &HashMap) -> Vec { m.values().cloned().collect() } + +pub fn list_concat(mut a: Vec, b: Vec) -> Vec { a.extend(b); a } + +pub fn list_push(mut list: Vec, item: T) -> Vec { list.push_back(item); list } + +pub fn append(list: Rc>, item: T) -> Vec { + let mut v = (*list).clone(); + v.push_back(item); + v +} + +pub fn chars_to_string(chars: &Rc>, start: i64, end: i64) -> String { + let len = chars.len(); + let start = (start.max(0) as usize).min(len); + let end = (end.max(0) as usize).min(len).max(start); + let units = (end.saturating_sub(start)) as u64; + record_source_chars_slice_walked(units); + // Focus caches the current RRB chunk, so per-char access is contiguous-slice + // speed; a plain iter().skip(start) walks O(start) per call, which summed + // quadratically across a tokenize pass (profiled 2026-07-06). + let mut focus = chars.focus(); + let mut out = String::with_capacity(end - start); + for i in start..end { + if let Some(ch) = char::from_u32(*focus.index(i) as u32) { + out.push(ch); + } + } + out +} + +pub fn parse_int(s: String) -> Option { s.parse::().ok() } + +pub fn map_contains_key(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn map_has(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn rc_empty_set() -> Rc> { + Rc::new(BTreeSet::new()) +} + +pub fn rc_set_insert(mut s: Rc>, x: T) -> Rc> { + Rc::make_mut(&mut s).insert(x); + s +} + +pub fn rc_set_union(a: Rc>, b: Rc>) -> Rc> { + let mut out = a; + for x in b.iter().cloned() { + Rc::make_mut(&mut out).insert(x); + } + out +} + +pub fn set_contains>>(s: S, x: T) -> bool { + s.as_ref().contains(&x) +} + +pub fn reverse(list: Rc>) -> Rc> { + Rc::new(list.iter().cloned().rev().collect()) +} + +pub fn replace(s: String, from: String, to: String) -> String { + s.replace(&from, &to) +} + +// -- Rc-wrapped container operations (FF-8) --------------------------------- +// These mirror the bare Vec/HashMap functions above but operate on Rc-wrapped +// containers for O(1) clone cost. Generated code using Rc container templates +// will call these. Read-only functions (map_get, map_keys, map_values, lookup, +// map_contains_key, map_has) work with Rc via auto-deref. + +// take_owned: move out of a uniquely-held Rc; clone when shared. With every +// container realized persistently (im), the shared-arm clone is cheap +// structural sharing — an ordinary designed path, not a degradation arm, so +// no counter and no refusal (the clone-fallback guard class was deleted with +// the Rc carriers it policed). +pub fn take_owned(x: Rc) -> T { + match Rc::try_unwrap(x) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } +} + +pub fn rc_list_push(list: Rc>, item: T) -> Rc> { + let mut v = list; + Rc::make_mut(&mut v).push_back(item); + v +} + +pub fn rc_list_concat(a: Rc>, b: Rc>) -> Rc> { + let mut result = a; + Rc::make_mut(&mut result).extend(b.iter().cloned()); + result +} + +// Every rc_* update here rides a persistent carrier (im HashMap/Vector/ +// OrdSet — one realization with the interpreter's Value::Map/List/Set), so +// make_mut's clone arm is O(1) structural sharing and each update copies an +// O(log n) node path — a designed update, never a degradation arm. +pub fn rc_map_insert(map: Rc>, key: K, value: V) -> Rc> { + let mut m = map; + Rc::make_mut(&mut m).insert(key, value); + m +} + +pub fn rc_map_merge(base: Rc>, overlay: Rc>) -> Rc> { + let mut result = base; + let inner = Rc::make_mut(&mut result); + for (k, v) in overlay.iter() { + inner.insert(k.clone(), v.clone()); + } + result +} + +pub fn rc_index_by String>(list: Rc>, key_fn: F) -> Rc> { + Rc::new(list.iter().map(|v| (key_fn(v), v.clone())).collect()) +} + +pub fn rc_empty_map() -> Rc> { Rc::new(HashMap::new()) } + +impl V2Concat for Rc> { + fn v1_concat(self, other: Rc>) -> Rc> { rc_list_concat(self, other) } +} + +pub fn scan_while(s: &str, start: i64, pred: impl Fn(String) -> bool) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && pred(String::from(bytes[pos] as char)) { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if pred(ch.to_string()) { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn skip_horizontal_ws(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && (bytes[pos] == b' ' || bytes[pos] == b'\t') { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == ' ' || ch == '\t' { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn scan_to_eol(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let start = start.min(bytes.len()); + for i in start..bytes.len() { if bytes[i] == b'\n' { return i as i64; } } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == '\n' { return pos as i64; } + pos += 1; + } + pos as i64 +} + +pub fn scan_string_end(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() { + if bytes[pos] == b'\\' { pos += 2; } + else if bytes[pos] == b'\"' { return (pos + 1) as i64; } + else { pos += 1; } + } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + let mut escaped = false; + for ch in s.chars().skip(start) { + if escaped { + escaped = false; + pos += 1; + } else if ch == '\\' { + escaped = true; + pos += 1; + } else if ch == '\"' { + return (pos + 1) as i64; + } else { + pos += 1; + } + } + pos as i64 +} + +pub fn code_point(c: String) -> i64 { + c.chars().next().map(|ch| ch as i64).unwrap_or(0) +} + +pub fn from_code_point(cp: i64) -> String { + char::from_u32(cp as u32).map(|c| c.to_string()).unwrap_or_default() +} + +pub fn is_xid_start(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_start).unwrap_or(false) +} + +pub fn is_xid_continue(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_continue).unwrap_or(false) +} + +pub fn is_emoji_ident(cp: i64) -> bool { + use unicode_properties::emoji::UnicodeEmoji; + use unicode_properties::emoji::EmojiStatus; + char::from_u32(cp as u32).map(|c| matches!(c.emoji_status(), EmojiStatus::EmojiPresentation | EmojiStatus::EmojiPresentationAndModifierBase | EmojiStatus::EmojiPresentationAndEmojiComponent | EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent) && !unicode_ident::is_xid_continue(c)).unwrap_or(false) +} + +// FreeMonoid host bridge (String = FreeMonoid) — relocated from v2_std_algebra +// so the Char authority (i64 / std.types.Char) is not pinned to v2_std_nat::Nat. +pub fn freemonoid_empty() -> Rc> { + Rc::new(Vec::new()) +} + +pub fn list_snoc_item(xs: Rc>, item: T) -> Rc> { + let mut out = xs.as_ref().clone(); + out.push_back(item); + Rc::new(out) +} + +pub fn fold_list(xs: Rc>, init: A, f: F) -> A +where + F: Fn(A, T) -> A, +{ + let mut acc = init; + for item in xs.iter() { + acc = f(acc, item.clone()); + } + acc +} + +const FNV1A64_OFFSET: u64 = 0xcbf29ce484222325; +const FNV1A64_PRIME: u64 = 0x100000001b3; + +fn fnv1a64(bytes: &[u8]) -> u64 { + let mut hash = FNV1A64_OFFSET; + for b in bytes { + hash ^= *b as u64; + hash = hash.wrapping_mul(FNV1A64_PRIME); + } + hash +} + +pub type Hash = String; + +const HASH_DIGEST_LEN: usize = 16; + +pub fn is_hash_digest(s: &str) -> bool { + s.len() == HASH_DIGEST_LEN && s.bytes().all(|b| b.is_ascii_hexdigit()) +} + +fn expect_hash_digest(s: &str, arg: &str) { + if !is_hash_digest(s) { + panic!("{} must be a 16-char hex Hash digest", arg); + } +} + +/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the +/// raw gantt key=value shape (process-absolute millis and rss-mib fields) dissolves into the observation projection. +#[allow(dead_code)] +pub const GANTT_CENSUS_MARKER: &str = "[gantt]"; + +/// Mirror of `gunbc.observation_ci_render.ci_minute_switch_seconds`. +const OBS_MINUTE_SWITCH_SECONDS: u64 = 90; + +pub fn obs_human_duration(ms: u64) -> String { + if ms < 1_000 { + format!("{ms}ms") + } else if ms < OBS_MINUTE_SWITCH_SECONDS * 1_000 { + format!("{} seconds", ms / 1_000) + } else { + format!("{} minutes", ms / 60_000) + } +} + +/// Mirror of `gunbc.observation_ci_render.ci_human_elapsed`. +pub fn obs_human_elapsed(wall_nanos: u128) -> String { + if wall_nanos < 1_000_000 { + format!("{wall_nanos}ns") + } else { + obs_human_duration((wall_nanos / 1_000_000) as u64) + } +} + +fn obs_phase_emoji() -> bool { + std::env::var("GITHUB_ACTIONS").as_deref() == Ok("true") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_begin_line` — +/// `ci_event_line(Begin) ∘ ci_render_line`. Justified divergence from the +/// interpreter seed boundary used by floor prelude marks: `trace_mark` runs +/// inside compile itself (hand-synced path and interpreter intrinsic), and +/// calling back into the interpreter to render would recurse. Proven +/// byte-equal to the `.dag` oracle by the seed RED. +pub fn render_phase_begin_line_mirror(phase: &str, emoji: bool) -> String { + let glyph = if emoji { "🔄" } else { "◐" }; + format!("{glyph} started {phase}") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_concluded_line` — +/// `ci_event_line(Concluded{Done}) ∘ ci_render_line`. Same justified-divergence +/// note as `render_phase_begin_line_mirror`. +pub fn render_phase_concluded_line_mirror(phase: &str, elapsed_ms: u64, emoji: bool) -> String { + let glyph = if emoji { "✅" } else { "✓" }; + format!("{glyph} {phase} done in {}", obs_human_duration(elapsed_ms)) +} + +/// Stage-boundary trace mark — the v1-seed interim realization of the v2 per-RealizedStep +/// CostAccount (std.realization_measurement). Wired (gantt flip): projects Begin/Concluded +/// on a PhaseSegment via the observation mirrors of `ci_event_line`. Segment wall on +/// Concluded (matched `.begin`→`.done`, else delta since last mark) — never the old +/// process-absolute millis field. RSS stays on heartbeat/measurement (`ci_event_line` does +/// not project `event.rss` — explicit divergence from the deleted rss-mib field). +/// +/// **Dissolution trigger (DESIGN §6):** delete this fn, the `trace_mark` registry row in +/// `04_method.dag` (+ hand-synced twin `v1_compiler_infer_method.rs`), the nine +/// `trace_mark(...)` marks in `compile.dag` (+ hand-synced `v1_compiler_compile.rs`), and +/// the interpreter arm in `v1_interpreter.rs` when realization_measurement_loop **Phase 0** +/// (`docs/plans/realization-measurement-loop.md`) lands a `.dag` `PerformanceReceipt` +/// per-stage carrier that a floor witness consumes by execution (the same retirement event +/// as `phase_profile.rs` / `GUNBC_FLOOR_GANTT`, per `docs/plans/ci-floor-fractal-gantt.md` +/// § dissolution). Receipt = that witness green with these marks deleted and stage walls +/// still attributable from the model path. +pub fn trace_mark(label: String) { + use std::sync::{Mutex, OnceLock}; + use std::time::Instant; + static TRACE_T0: OnceLock = OnceLock::new(); + static LAST_MARK: OnceLock> = OnceLock::new(); + static OPENS: OnceLock>> = OnceLock::new(); + let t0 = TRACE_T0.get_or_init(Instant::now); + let last = LAST_MARK.get_or_init(|| Mutex::new(*t0)); + let opens = OPENS.get_or_init(|| Mutex::new(std::collections::HashMap::new())); + let emoji = obs_phase_emoji(); + let now = Instant::now(); + let _ = GANTT_CENSUS_MARKER; + if let Some(phase) = label.strip_suffix(".begin") { + if let Ok(mut map) = opens.lock() { + map.insert(phase.to_string(), now); + } + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!("{}", render_phase_begin_line_mirror(phase, emoji)); + } else if let Some(phase) = label.strip_suffix(".done") { + let elapsed_ms = { + let started = opens.lock().ok().and_then(|mut m| m.remove(phase)); + match started { + Some(t) => now.saturating_duration_since(t).as_millis() as u64, + None => { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + now.saturating_duration_since(prev).as_millis() as u64 + } + } + }; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(phase, elapsed_ms, emoji) + ); + } else { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + let elapsed_ms = now.saturating_duration_since(prev).as_millis() as u64; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(&label, elapsed_ms, emoji) + ); + } +} + +/// Content hash over raw bytes — the byte-level single authority. `atom_identity_hash` +/// is the `String` projection of this. Use this directly for arbitrary binary content +/// (e.g. an executable or serialized payload): routing bytes through `String`/ +/// `from_utf8_lossy` first collapses every invalid UTF-8 sequence to U+FFFD, so distinct +/// byte sequences would hash equal — a §5 silent-collision fail-open for content-addressing. +pub fn bytes_identity_hash(bytes: &[u8]) -> Hash { + format!("{:016x}", fnv1a64(bytes)) +} + +pub fn atom_identity_hash(s: String) -> Hash { + bytes_identity_hash(s.as_bytes()) +} + +pub fn hash_combine(a: Hash, b: Hash) -> Hash { + expect_hash_digest(&a, "a"); + expect_hash_digest(&b, "b"); + let mut bytes = a.into_bytes(); + bytes.push(0); + bytes.extend_from_slice(b.as_bytes()); + format!("{:016x}", fnv1a64(&bytes)) +} + +#[derive(Debug, Clone)] +pub struct FilesystemReadResult { + pub content: String, +} + +pub fn filesystem_read(path: String) -> FilesystemReadResult { + let content = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("failed to read {}: {}", path, e)); + FilesystemReadResult { content } +} +fn int_relu(x: i64) -> i64 { + if x > 0 { x } else { 0 } +} + +/// Opcode wire authority: `extdeps.languages.simd.kernel.relu_mul_add_wire_op_codes`. +/// Scaffold regen-sync: see `host_kernel_relu_mul_add_op_codes_scaffold_note` until feature:dag-kernel-realization-handler. +const RELU_MUL_ADD_OP_CODES: [i64; 3] = [1, 2, 3]; + +fn assert_relu_mul_add_op_codes(op_codes: &[i64], _handler: &str) { + if op_codes != RELU_MUL_ADD_OP_CODES { + panic!("unsupported op_codes in accelerator demo kernel"); + } +} + +/// Host bridge: `.dag` passes `std.numerical_contract.FmaContractionPolicy`; interpreter maps to 0/1 until target_model emit. +pub fn contiguous_loop_elementwise_float_kernel( + op_codes: &[i64], + fma_contraction_policy: i64, + a: &[f64], + b: &[f64], + c: &[f64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_float_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let elem = match fma_contraction_policy { + 0 => { + let prod = a[i] * b[i]; + prod + c[i] + }, + 1 => a[i].mul_add(b[i], c[i]), + _ => panic!("unknown fma_contraction_policy"), + }; + out.push(if elem > 0.0 { elem } else { 0.0 }); + } + out +} + +/// Integer oracle authority: `gunbc.accelerator_demo_eval` via interpreter `Int` binops (`*`/`+`). +/// Host kernel uses `wrapping_*` to mirror release interpreter overflow semantics; demo fixtures +/// stay in-range under `IntegerExact` — out-of-range inputs are outside the bit-exact bar. +pub fn contiguous_loop_elementwise_kernel( + op_codes: &[i64], + a: &[i64], + b: &[i64], + c: &[i64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let tmp = a[i].wrapping_mul(b[i]).wrapping_add(c[i]); + out.push(int_relu(tmp)); + } + out +} diff --git a/.probe/ka/m.dag b/.probe/ka/m.dag new file mode 100644 index 00000000000..70963fb5e00 --- /dev/null +++ b/.probe/ka/m.dag @@ -0,0 +1,7 @@ +module probe.m +type BoxI { + v: Int +} +fn mk() -> BoxI { + BoxI { v: 1 } +} diff --git a/.probe/ka/o2/Cargo.toml b/.probe/ka/o2/Cargo.toml new file mode 100644 index 00000000000..f105b3fd945 --- /dev/null +++ b/.probe/ka/o2/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "v1_compiled" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +im = { version = "15.1", features = ["serde"] } +unicode-ident = "1" +unicode-properties = { version = "0.1", features = ["emoji"] } +serde = { version = "1", features = ["derive", "rc"] } +serde_json = "1" +stacker = "0.1" +clap = { version = "4", features = ["derive"] } +lazy_static = "1" +ureq = { version = "2", features = ["json"] } diff --git a/.probe/ka/o2/src/emitted_population.rs b/.probe/ka/o2/src/emitted_population.rs new file mode 100644 index 00000000000..645ce64d583 --- /dev/null +++ b/.probe/ka/o2/src/emitted_population.rs @@ -0,0 +1,6 @@ +// Cargo.toml +// src/emitted_population.rs +// src/lib.rs +// src/main.rs +// src/probe_m.rs +// src/v1_rt.rs diff --git a/.probe/ka/o2/src/lib.rs b/.probe/ka/o2/src/lib.rs new file mode 100644 index 00000000000..beb97479f01 --- /dev/null +++ b/.probe/ka/o2/src/lib.rs @@ -0,0 +1,65 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_imports, unused_variables, unused_mut, unused_parens, dead_code, non_shorthand_field_patterns, suspicious_double_ref_op, clippy::all)] +#![deny(unreachable_patterns)] +#![recursion_limit = "256"] + +use im::{OrdSet as BTreeSet, Vector as Vec}; + +pub mod probe_m; +pub mod v1_rt; + +pub struct NonEmptyVec(Vec); + +impl std::fmt::Debug for NonEmptyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("NonEmptyVec").field(&self.0).finish() + } +} + +impl Clone for NonEmptyVec { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl PartialEq for NonEmptyVec { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl NonEmptyVec { + pub fn new(items: Vec) -> Result { + if items.is_empty() { + Err("NonEmptyVec requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct NonEmptyBTreeSet(std::collections::BTreeSet); + +impl NonEmptyBTreeSet { + pub fn new(items: std::collections::BTreeSet) -> Result { + if items.is_empty() { + Err("NonEmptyBTreeSet requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn as_set(&self) -> &std::collections::BTreeSet { + &self.0 + } + + pub fn into_set(self) -> std::collections::BTreeSet { + self.0 + } +} diff --git a/.probe/ka/o2/src/main.rs b/.probe/ka/o2/src/main.rs new file mode 100644 index 00000000000..63177e5007e --- /dev/null +++ b/.probe/ka/o2/src/main.rs @@ -0,0 +1,5 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_parens, clippy::all, clippy::disallowed_macros)] + +fn main() {} diff --git a/.probe/ka/o2/src/probe_m.rs b/.probe/ka/o2/src/probe_m.rs new file mode 100644 index 00000000000..380c546b5a1 --- /dev/null +++ b/.probe/ka/o2/src/probe_m.rs @@ -0,0 +1,22 @@ +// Generated by v1 compiler -- do not edit. +// Source module: probe.m + +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use crate::v1_rt::{VecCompat, VecJoin}; +use std::rc::Rc; +use crate::v1_rt; +use crate::NonEmptyVec; +use crate::NonEmptyBTreeSet; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BoxI { + pub v: i64, + pub _phantom: std::marker::PhantomData, +} + +pub fn mk() -> Rc> { + Rc::new(BoxI { + v: 1, + _phantom: std::marker::PhantomData, +}) +} diff --git a/.probe/ka/o2/src/v1_rt.rs b/.probe/ka/o2/src/v1_rt.rs new file mode 100644 index 00000000000..fb7794c32ce --- /dev/null +++ b/.probe/ka/o2/src/v1_rt.rs @@ -0,0 +1,864 @@ +//! Runtime shims for v2 compiler intrinsic operations. +//! Generated by the v2 compiler -- do not edit. + +#![allow(unused_variables, dead_code)] + +use im::{HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +#[cfg(feature = "text_lookup_work_counter")] +thread_local! { + static TEXT_LOOKUP_CHARS_WALKED: Cell = Cell::new(0); +} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn reset_text_lookup_chars_walked() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(0)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn reset_text_lookup_chars_walked() {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn take_text_lookup_chars_walked() -> u64 { + TEXT_LOOKUP_CHARS_WALKED.with(|c| { + let walked = c.get(); + c.set(0); + walked + }) +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn take_text_lookup_chars_walked() -> u64 { 0 } + +#[cfg(feature = "text_lookup_work_counter")] +fn record_substring_chars_walked(s: &str, start: usize, take_len: usize) { + let walked = if s.is_ascii() { + take_len as u64 + } else { + (start + take_len) as u64 + }; + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + walked)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_substring_chars_walked(_s: &str, _start: usize, _take_len: usize) {} + +#[cfg(feature = "text_lookup_work_counter")] +fn record_source_chars_slice_walked(units: u64) { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + units)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_source_chars_slice_walked(_units: u64) {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn record_source_chars_index_lookup() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + 1)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn record_source_chars_index_lookup() {} + +/// Read-only silent-pick telemetry for resolution divergence census slice 2. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpPickSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, + pub chosen_module_path: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpTieSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct FnParentFirstHitSite { + pub env_module_path: String, + pub name: String, + pub parent_match_count: usize, + pub chosen_parent_module: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct SilentPickTelemetry { + pub global_bare_lcp_picks: std::vec::Vec, + pub global_bare_lcp_ties: std::vec::Vec, + pub fn_parent_first_hits: std::vec::Vec, +} + +thread_local! { + static RESOLUTION_SILENT_PICK_ENABLED: Cell = const { Cell::new(false) }; + static RESOLUTION_SILENT_PICK: RefCell = RefCell::new(SilentPickTelemetry::default()); +} + +pub fn resolution_silent_pick_enable() { + RESOLUTION_SILENT_PICK.with(|t| *t.borrow_mut() = SilentPickTelemetry::default()); + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(true)); +} + +pub fn resolution_silent_pick_disable() -> SilentPickTelemetry { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(false)); + RESOLUTION_SILENT_PICK.with(|t| std::mem::take(&mut *t.borrow_mut())) +} + +pub fn resolution_silent_pick_is_enabled() -> bool { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.get()) +} + +pub fn resolution_silent_pick_record_global_bare_lcp_pick( + env_module_path: String, + name: String, + candidate_count: i64, + chosen_module_path: String, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_picks.push(GlobalBareLcpPickSite { + env_module_path, + name, + candidate_count, + chosen_module_path, + }); + }); +} + +pub fn resolution_silent_pick_record_global_bare_lcp_tie( + env_module_path: String, + name: String, + candidate_count: i64, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_ties.push(GlobalBareLcpTieSite { + env_module_path, + name, + candidate_count, + }); + }); +} + +// NameResolutionPolicy gate (namespace-resolution-design.md 13, 8 step 4): default +// true = NamespaceOnlyY — strict unique-on-chain in the type/value path and +// exactly-one across the fn parent closure, with typed Ambiguous refusals. +// false = ImportScoped (legacy resolver, byte-for-byte). Host-side setter only; +// no .dag surface can flip it (no escape hatch — a flip is an explicit host decision). +thread_local! { + static NAME_RESOLUTION_POLICY_NAMESPACE_ONLY: Cell = const { Cell::new(true) }; +} + +pub fn name_resolution_policy_set_namespace_only(enabled: bool) { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.set(enabled)); +} + +pub fn name_resolution_policy_is_namespace_only() -> bool { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.get()) +} + +// N1a measurement arm (type-ref hit≠bind discriminator): default false = production +// fail-open path. Host-side setter only — compile_dag_diagnostic_census arms for the +// nested synthetic compile; no .dag surface can flip it (same shape as +// name_resolution_policy — no escape hatch). +thread_local! { + static TYPE_REF_HIT_NE_BIND_MEASURE: Cell = const { Cell::new(false) }; +} + +pub fn type_ref_hit_ne_bind_measure_set(enabled: bool) { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.set(enabled)); +} + +pub fn type_ref_hit_ne_bind_measure_active() -> bool { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.get()) +} + +pub fn with_type_ref_hit_ne_bind_measure(f: impl FnOnce() -> T) -> T { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|c| { + let prev = c.get(); + c.set(true); + let out = f(); + c.set(prev); + out + }) +} + +pub fn resolution_silent_pick_record_fn_parent_first_hit( + env_module_path: String, + name: String, + parent_match_count: i64, + chosen_parent_module: String, +) { + let parent_match_count = parent_match_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || parent_match_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().fn_parent_first_hits.push(FnParentFirstHitSite { + env_module_path, + name, + parent_match_count, + chosen_parent_module, + }); + }); +} + +// Vec here is im's persistent Vector (one realization with the +// interpreter's Value::List). VecCompat papers the std-Vec API deltas the +// emitter's method rows rely on (first/push/with_capacity; join via VecJoin) +// so emitted call sites stay identical across carriers. +pub trait VecCompat { + fn first(&self) -> Option<&T>; + fn push(&mut self, item: T); + fn with_capacity(capacity: usize) -> Self; +} + +impl VecCompat for Vec { + fn first(&self) -> Option<&T> { self.front() } + fn push(&mut self, item: T) { self.push_back(item); } + fn with_capacity(_capacity: usize) -> Self { Vec::new() } +} + +pub trait VecJoin { + fn join(&self, sep: &str) -> String; +} + +impl VecJoin for Vec { + fn join(&self, sep: &str) -> String { + self.iter().cloned().collect::>().join(sep) + } +} + +pub trait V2Concat { + fn v1_concat(self, other: Self) -> Self; +} + +impl V2Concat for String { + fn v1_concat(mut self, other: String) -> String { self.push_str(&other); self } +} + +impl V2Concat for Vec { + fn v1_concat(mut self, other: Vec) -> Vec { self.extend(other); self } +} + +pub fn concat(a: T, b: T) -> T { a.v1_concat(b) } + +/// Ascii-aware variant taking a precomputed `is_ascii` flag (the `RcStr` carrier fact) +/// instead of rescanning the whole string on every call -- the per-call `s.is_ascii()` +/// scan is what made repeated indexing over a large string O(n^2) (STRING-INDEX-0). +pub fn char_at_ascii_aware(s: &str, is_ascii: bool, pos: i64) -> String { + let pos = pos.max(0) as usize; + if is_ascii { + let bytes = s.as_bytes(); + if pos >= bytes.len() { return String::new(); } + return String::from(bytes[pos] as char); + } + s.chars().nth(pos).map(|ch| ch.to_string()).unwrap_or_default() +} + +pub fn char_at(s: &str, pos: i64) -> String { + char_at_ascii_aware(s, s.is_ascii(), pos) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn string_length_ascii_aware(s: &str, is_ascii: bool) -> i64 { + if is_ascii { s.len() as i64 } else { s.chars().count() as i64 } +} + +pub fn string_length(s: &str) -> i64 { + string_length_ascii_aware(s, s.is_ascii()) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn substring_ascii_aware(s: &str, is_ascii: bool, start: i64, end: i64) -> String { + let start = start.max(0) as usize; + let end = end.max(0) as usize; + if end <= start { return String::new(); } + if is_ascii { + let len = s.len(); + if start >= len { return String::new(); } + let out_end = end.min(len); + let take_len = out_end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + return s[start..out_end].to_string(); + } + let take_len = end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + s.chars().skip(start).take(take_len).collect() +} + +pub fn substring(s: &str, start: i64, end: i64) -> String { + substring_ascii_aware(s, s.is_ascii(), start, end) +} + +pub fn string_contains(s: &str, sub: String) -> bool { + s.contains(&*sub) +} + +pub fn contains(s: String, sub: String) -> bool { string_contains(&s, sub) } + +pub fn starts_with(s: String, prefix: String) -> bool { s.starts_with(&*prefix) } + +pub fn ends_with(s: String, suffix: String) -> bool { s.ends_with(&*suffix) } + +pub fn trim(s: String) -> String { s.trim().to_string() } + +pub fn count(items: Rc>) -> i64 { items.len() as i64 } + +pub fn str_eq(a: String, b: String) -> bool { a == b } + +pub fn to_string(value: i64) -> String { value.to_string() } + +/// RFC 3629 UTF-8 decode of a byte vector. Fail-closed on invalid UTF-8. +pub fn utf8_decode_bytes(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_vec()).map_err(|e| format!("invalid UTF-8 in access payload: {}", e)) +} + +pub fn clamp(val: i64, min_val: i64, max_val: i64) -> i64 { + val.clamp(min_val, max_val) +} + +pub fn lookup(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn index_by String>(list: Vec, key_fn: F) -> HashMap { + let mut map = HashMap::new(); + for item in list { let key = key_fn(&item); map.insert(key, item); } + map +} + +pub fn empty_map() -> HashMap { HashMap::new() } + +pub fn map_insert(mut map: HashMap, key: K, value: V) -> HashMap { + map.insert(key, value); map +} + +pub fn map_merge(mut base: HashMap, overlay: HashMap) -> HashMap { + base.extend(overlay); base +} + +pub fn map_get(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn map_keys(m: &HashMap) -> Vec { m.keys().cloned().collect() } + +pub fn sorted_map_keys(m: &HashMap) -> Vec { let mut keys = map_keys(m); keys.sort(); keys } + +pub fn map_is_empty(m: &HashMap) -> bool { m.is_empty() } + +// Sound identity hint (see 04_infer.dag substitute_generics): returns true => +// the two are structurally equal. The compiled realization answers with pointer +// identity (conservative: may say false when equal); never true-when-unequal, so +// callers that return the original on true preserve output structure. Owned Rc +// args (cheap refcount bump) keep the inner element pointers, so ptr_eq on the +// clones equals ptr_eq on the originals -- lets the .dag pass args by value and +// emit through the normal clone path (no all-args-by-ref emit rule needed). +pub fn rc_ptr_eq(a: Rc, b: Rc) -> bool { Rc::ptr_eq(&a, &b) } + +pub fn rc_vec_ptr_eq(a: Rc>>, b: Rc>>) -> bool { + a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| Rc::ptr_eq(x, y)) +} + +pub fn map_values(m: &HashMap) -> Vec { m.values().cloned().collect() } + +pub fn list_concat(mut a: Vec, b: Vec) -> Vec { a.extend(b); a } + +pub fn list_push(mut list: Vec, item: T) -> Vec { list.push_back(item); list } + +pub fn append(list: Rc>, item: T) -> Vec { + let mut v = (*list).clone(); + v.push_back(item); + v +} + +pub fn chars_to_string(chars: &Rc>, start: i64, end: i64) -> String { + let len = chars.len(); + let start = (start.max(0) as usize).min(len); + let end = (end.max(0) as usize).min(len).max(start); + let units = (end.saturating_sub(start)) as u64; + record_source_chars_slice_walked(units); + // Focus caches the current RRB chunk, so per-char access is contiguous-slice + // speed; a plain iter().skip(start) walks O(start) per call, which summed + // quadratically across a tokenize pass (profiled 2026-07-06). + let mut focus = chars.focus(); + let mut out = String::with_capacity(end - start); + for i in start..end { + if let Some(ch) = char::from_u32(*focus.index(i) as u32) { + out.push(ch); + } + } + out +} + +pub fn parse_int(s: String) -> Option { s.parse::().ok() } + +pub fn map_contains_key(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn map_has(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn rc_empty_set() -> Rc> { + Rc::new(BTreeSet::new()) +} + +pub fn rc_set_insert(mut s: Rc>, x: T) -> Rc> { + Rc::make_mut(&mut s).insert(x); + s +} + +pub fn rc_set_union(a: Rc>, b: Rc>) -> Rc> { + let mut out = a; + for x in b.iter().cloned() { + Rc::make_mut(&mut out).insert(x); + } + out +} + +pub fn set_contains>>(s: S, x: T) -> bool { + s.as_ref().contains(&x) +} + +pub fn reverse(list: Rc>) -> Rc> { + Rc::new(list.iter().cloned().rev().collect()) +} + +pub fn replace(s: String, from: String, to: String) -> String { + s.replace(&from, &to) +} + +// -- Rc-wrapped container operations (FF-8) --------------------------------- +// These mirror the bare Vec/HashMap functions above but operate on Rc-wrapped +// containers for O(1) clone cost. Generated code using Rc container templates +// will call these. Read-only functions (map_get, map_keys, map_values, lookup, +// map_contains_key, map_has) work with Rc via auto-deref. + +// take_owned: move out of a uniquely-held Rc; clone when shared. With every +// container realized persistently (im), the shared-arm clone is cheap +// structural sharing — an ordinary designed path, not a degradation arm, so +// no counter and no refusal (the clone-fallback guard class was deleted with +// the Rc carriers it policed). +pub fn take_owned(x: Rc) -> T { + match Rc::try_unwrap(x) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } +} + +pub fn rc_list_push(list: Rc>, item: T) -> Rc> { + let mut v = list; + Rc::make_mut(&mut v).push_back(item); + v +} + +pub fn rc_list_concat(a: Rc>, b: Rc>) -> Rc> { + let mut result = a; + Rc::make_mut(&mut result).extend(b.iter().cloned()); + result +} + +// Every rc_* update here rides a persistent carrier (im HashMap/Vector/ +// OrdSet — one realization with the interpreter's Value::Map/List/Set), so +// make_mut's clone arm is O(1) structural sharing and each update copies an +// O(log n) node path — a designed update, never a degradation arm. +pub fn rc_map_insert(map: Rc>, key: K, value: V) -> Rc> { + let mut m = map; + Rc::make_mut(&mut m).insert(key, value); + m +} + +pub fn rc_map_merge(base: Rc>, overlay: Rc>) -> Rc> { + let mut result = base; + let inner = Rc::make_mut(&mut result); + for (k, v) in overlay.iter() { + inner.insert(k.clone(), v.clone()); + } + result +} + +pub fn rc_index_by String>(list: Rc>, key_fn: F) -> Rc> { + Rc::new(list.iter().map(|v| (key_fn(v), v.clone())).collect()) +} + +pub fn rc_empty_map() -> Rc> { Rc::new(HashMap::new()) } + +impl V2Concat for Rc> { + fn v1_concat(self, other: Rc>) -> Rc> { rc_list_concat(self, other) } +} + +pub fn scan_while(s: &str, start: i64, pred: impl Fn(String) -> bool) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && pred(String::from(bytes[pos] as char)) { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if pred(ch.to_string()) { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn skip_horizontal_ws(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && (bytes[pos] == b' ' || bytes[pos] == b'\t') { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == ' ' || ch == '\t' { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn scan_to_eol(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let start = start.min(bytes.len()); + for i in start..bytes.len() { if bytes[i] == b'\n' { return i as i64; } } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == '\n' { return pos as i64; } + pos += 1; + } + pos as i64 +} + +pub fn scan_string_end(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() { + if bytes[pos] == b'\\' { pos += 2; } + else if bytes[pos] == b'\"' { return (pos + 1) as i64; } + else { pos += 1; } + } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + let mut escaped = false; + for ch in s.chars().skip(start) { + if escaped { + escaped = false; + pos += 1; + } else if ch == '\\' { + escaped = true; + pos += 1; + } else if ch == '\"' { + return (pos + 1) as i64; + } else { + pos += 1; + } + } + pos as i64 +} + +pub fn code_point(c: String) -> i64 { + c.chars().next().map(|ch| ch as i64).unwrap_or(0) +} + +pub fn from_code_point(cp: i64) -> String { + char::from_u32(cp as u32).map(|c| c.to_string()).unwrap_or_default() +} + +pub fn is_xid_start(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_start).unwrap_or(false) +} + +pub fn is_xid_continue(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_continue).unwrap_or(false) +} + +pub fn is_emoji_ident(cp: i64) -> bool { + use unicode_properties::emoji::UnicodeEmoji; + use unicode_properties::emoji::EmojiStatus; + char::from_u32(cp as u32).map(|c| matches!(c.emoji_status(), EmojiStatus::EmojiPresentation | EmojiStatus::EmojiPresentationAndModifierBase | EmojiStatus::EmojiPresentationAndEmojiComponent | EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent) && !unicode_ident::is_xid_continue(c)).unwrap_or(false) +} + +// FreeMonoid host bridge (String = FreeMonoid) — relocated from v2_std_algebra +// so the Char authority (i64 / std.types.Char) is not pinned to v2_std_nat::Nat. +pub fn freemonoid_empty() -> Rc> { + Rc::new(Vec::new()) +} + +pub fn list_snoc_item(xs: Rc>, item: T) -> Rc> { + let mut out = xs.as_ref().clone(); + out.push_back(item); + Rc::new(out) +} + +pub fn fold_list(xs: Rc>, init: A, f: F) -> A +where + F: Fn(A, T) -> A, +{ + let mut acc = init; + for item in xs.iter() { + acc = f(acc, item.clone()); + } + acc +} + +const FNV1A64_OFFSET: u64 = 0xcbf29ce484222325; +const FNV1A64_PRIME: u64 = 0x100000001b3; + +fn fnv1a64(bytes: &[u8]) -> u64 { + let mut hash = FNV1A64_OFFSET; + for b in bytes { + hash ^= *b as u64; + hash = hash.wrapping_mul(FNV1A64_PRIME); + } + hash +} + +pub type Hash = String; + +const HASH_DIGEST_LEN: usize = 16; + +pub fn is_hash_digest(s: &str) -> bool { + s.len() == HASH_DIGEST_LEN && s.bytes().all(|b| b.is_ascii_hexdigit()) +} + +fn expect_hash_digest(s: &str, arg: &str) { + if !is_hash_digest(s) { + panic!("{} must be a 16-char hex Hash digest", arg); + } +} + +/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the +/// raw gantt key=value shape (process-absolute millis and rss-mib fields) dissolves into the observation projection. +#[allow(dead_code)] +pub const GANTT_CENSUS_MARKER: &str = "[gantt]"; + +/// Mirror of `gunbc.observation_ci_render.ci_minute_switch_seconds`. +const OBS_MINUTE_SWITCH_SECONDS: u64 = 90; + +pub fn obs_human_duration(ms: u64) -> String { + if ms < 1_000 { + format!("{ms}ms") + } else if ms < OBS_MINUTE_SWITCH_SECONDS * 1_000 { + format!("{} seconds", ms / 1_000) + } else { + format!("{} minutes", ms / 60_000) + } +} + +/// Mirror of `gunbc.observation_ci_render.ci_human_elapsed`. +pub fn obs_human_elapsed(wall_nanos: u128) -> String { + if wall_nanos < 1_000_000 { + format!("{wall_nanos}ns") + } else { + obs_human_duration((wall_nanos / 1_000_000) as u64) + } +} + +fn obs_phase_emoji() -> bool { + std::env::var("GITHUB_ACTIONS").as_deref() == Ok("true") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_begin_line` — +/// `ci_event_line(Begin) ∘ ci_render_line`. Justified divergence from the +/// interpreter seed boundary used by floor prelude marks: `trace_mark` runs +/// inside compile itself (hand-synced path and interpreter intrinsic), and +/// calling back into the interpreter to render would recurse. Proven +/// byte-equal to the `.dag` oracle by the seed RED. +pub fn render_phase_begin_line_mirror(phase: &str, emoji: bool) -> String { + let glyph = if emoji { "🔄" } else { "◐" }; + format!("{glyph} started {phase}") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_concluded_line` — +/// `ci_event_line(Concluded{Done}) ∘ ci_render_line`. Same justified-divergence +/// note as `render_phase_begin_line_mirror`. +pub fn render_phase_concluded_line_mirror(phase: &str, elapsed_ms: u64, emoji: bool) -> String { + let glyph = if emoji { "✅" } else { "✓" }; + format!("{glyph} {phase} done in {}", obs_human_duration(elapsed_ms)) +} + +/// Stage-boundary trace mark — the v1-seed interim realization of the v2 per-RealizedStep +/// CostAccount (std.realization_measurement). Wired (gantt flip): projects Begin/Concluded +/// on a PhaseSegment via the observation mirrors of `ci_event_line`. Segment wall on +/// Concluded (matched `.begin`→`.done`, else delta since last mark) — never the old +/// process-absolute millis field. RSS stays on heartbeat/measurement (`ci_event_line` does +/// not project `event.rss` — explicit divergence from the deleted rss-mib field). +/// +/// **Dissolution trigger (DESIGN §6):** delete this fn, the `trace_mark` registry row in +/// `04_method.dag` (+ hand-synced twin `v1_compiler_infer_method.rs`), the nine +/// `trace_mark(...)` marks in `compile.dag` (+ hand-synced `v1_compiler_compile.rs`), and +/// the interpreter arm in `v1_interpreter.rs` when realization_measurement_loop **Phase 0** +/// (`docs/plans/realization-measurement-loop.md`) lands a `.dag` `PerformanceReceipt` +/// per-stage carrier that a floor witness consumes by execution (the same retirement event +/// as `phase_profile.rs` / `GUNBC_FLOOR_GANTT`, per `docs/plans/ci-floor-fractal-gantt.md` +/// § dissolution). Receipt = that witness green with these marks deleted and stage walls +/// still attributable from the model path. +pub fn trace_mark(label: String) { + use std::sync::{Mutex, OnceLock}; + use std::time::Instant; + static TRACE_T0: OnceLock = OnceLock::new(); + static LAST_MARK: OnceLock> = OnceLock::new(); + static OPENS: OnceLock>> = OnceLock::new(); + let t0 = TRACE_T0.get_or_init(Instant::now); + let last = LAST_MARK.get_or_init(|| Mutex::new(*t0)); + let opens = OPENS.get_or_init(|| Mutex::new(std::collections::HashMap::new())); + let emoji = obs_phase_emoji(); + let now = Instant::now(); + let _ = GANTT_CENSUS_MARKER; + if let Some(phase) = label.strip_suffix(".begin") { + if let Ok(mut map) = opens.lock() { + map.insert(phase.to_string(), now); + } + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!("{}", render_phase_begin_line_mirror(phase, emoji)); + } else if let Some(phase) = label.strip_suffix(".done") { + let elapsed_ms = { + let started = opens.lock().ok().and_then(|mut m| m.remove(phase)); + match started { + Some(t) => now.saturating_duration_since(t).as_millis() as u64, + None => { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + now.saturating_duration_since(prev).as_millis() as u64 + } + } + }; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(phase, elapsed_ms, emoji) + ); + } else { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + let elapsed_ms = now.saturating_duration_since(prev).as_millis() as u64; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(&label, elapsed_ms, emoji) + ); + } +} + +/// Content hash over raw bytes — the byte-level single authority. `atom_identity_hash` +/// is the `String` projection of this. Use this directly for arbitrary binary content +/// (e.g. an executable or serialized payload): routing bytes through `String`/ +/// `from_utf8_lossy` first collapses every invalid UTF-8 sequence to U+FFFD, so distinct +/// byte sequences would hash equal — a §5 silent-collision fail-open for content-addressing. +pub fn bytes_identity_hash(bytes: &[u8]) -> Hash { + format!("{:016x}", fnv1a64(bytes)) +} + +pub fn atom_identity_hash(s: String) -> Hash { + bytes_identity_hash(s.as_bytes()) +} + +pub fn hash_combine(a: Hash, b: Hash) -> Hash { + expect_hash_digest(&a, "a"); + expect_hash_digest(&b, "b"); + let mut bytes = a.into_bytes(); + bytes.push(0); + bytes.extend_from_slice(b.as_bytes()); + format!("{:016x}", fnv1a64(&bytes)) +} + +#[derive(Debug, Clone)] +pub struct FilesystemReadResult { + pub content: String, +} + +pub fn filesystem_read(path: String) -> FilesystemReadResult { + let content = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("failed to read {}: {}", path, e)); + FilesystemReadResult { content } +} +fn int_relu(x: i64) -> i64 { + if x > 0 { x } else { 0 } +} + +/// Opcode wire authority: `extdeps.languages.simd.kernel.relu_mul_add_wire_op_codes`. +/// Scaffold regen-sync: see `host_kernel_relu_mul_add_op_codes_scaffold_note` until feature:dag-kernel-realization-handler. +const RELU_MUL_ADD_OP_CODES: [i64; 3] = [1, 2, 3]; + +fn assert_relu_mul_add_op_codes(op_codes: &[i64], _handler: &str) { + if op_codes != RELU_MUL_ADD_OP_CODES { + panic!("unsupported op_codes in accelerator demo kernel"); + } +} + +/// Host bridge: `.dag` passes `std.numerical_contract.FmaContractionPolicy`; interpreter maps to 0/1 until target_model emit. +pub fn contiguous_loop_elementwise_float_kernel( + op_codes: &[i64], + fma_contraction_policy: i64, + a: &[f64], + b: &[f64], + c: &[f64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_float_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let elem = match fma_contraction_policy { + 0 => { + let prod = a[i] * b[i]; + prod + c[i] + }, + 1 => a[i].mul_add(b[i], c[i]), + _ => panic!("unknown fma_contraction_policy"), + }; + out.push(if elem > 0.0 { elem } else { 0.0 }); + } + out +} + +/// Integer oracle authority: `gunbc.accelerator_demo_eval` via interpreter `Int` binops (`*`/`+`). +/// Host kernel uses `wrapping_*` to mirror release interpreter overflow semantics; demo fixtures +/// stay in-range under `IntegerExact` — out-of-range inputs are outside the bit-exact bar. +pub fn contiguous_loop_elementwise_kernel( + op_codes: &[i64], + a: &[i64], + b: &[i64], + c: &[i64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let tmp = a[i].wrapping_mul(b[i]).wrapping_add(c[i]); + out.push(int_relu(tmp)); + } + out +} diff --git a/.probe/ka/out/Cargo.toml b/.probe/ka/out/Cargo.toml new file mode 100644 index 00000000000..f105b3fd945 --- /dev/null +++ b/.probe/ka/out/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "v1_compiled" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +im = { version = "15.1", features = ["serde"] } +unicode-ident = "1" +unicode-properties = { version = "0.1", features = ["emoji"] } +serde = { version = "1", features = ["derive", "rc"] } +serde_json = "1" +stacker = "0.1" +clap = { version = "4", features = ["derive"] } +lazy_static = "1" +ureq = { version = "2", features = ["json"] } diff --git a/.probe/ka/out/src/emitted_population.rs b/.probe/ka/out/src/emitted_population.rs new file mode 100644 index 00000000000..645ce64d583 --- /dev/null +++ b/.probe/ka/out/src/emitted_population.rs @@ -0,0 +1,6 @@ +// Cargo.toml +// src/emitted_population.rs +// src/lib.rs +// src/main.rs +// src/probe_m.rs +// src/v1_rt.rs diff --git a/.probe/ka/out/src/lib.rs b/.probe/ka/out/src/lib.rs new file mode 100644 index 00000000000..beb97479f01 --- /dev/null +++ b/.probe/ka/out/src/lib.rs @@ -0,0 +1,65 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_imports, unused_variables, unused_mut, unused_parens, dead_code, non_shorthand_field_patterns, suspicious_double_ref_op, clippy::all)] +#![deny(unreachable_patterns)] +#![recursion_limit = "256"] + +use im::{OrdSet as BTreeSet, Vector as Vec}; + +pub mod probe_m; +pub mod v1_rt; + +pub struct NonEmptyVec(Vec); + +impl std::fmt::Debug for NonEmptyVec { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("NonEmptyVec").field(&self.0).finish() + } +} + +impl Clone for NonEmptyVec { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl PartialEq for NonEmptyVec { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl NonEmptyVec { + pub fn new(items: Vec) -> Result { + if items.is_empty() { + Err("NonEmptyVec requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn into_vec(self) -> Vec { + self.0 + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct NonEmptyBTreeSet(std::collections::BTreeSet); + +impl NonEmptyBTreeSet { + pub fn new(items: std::collections::BTreeSet) -> Result { + if items.is_empty() { + Err("NonEmptyBTreeSet requires at least one element") + } else { + Ok(Self(items)) + } + } + + pub fn as_set(&self) -> &std::collections::BTreeSet { + &self.0 + } + + pub fn into_set(self) -> std::collections::BTreeSet { + self.0 + } +} diff --git a/.probe/ka/out/src/main.rs b/.probe/ka/out/src/main.rs new file mode 100644 index 00000000000..63177e5007e --- /dev/null +++ b/.probe/ka/out/src/main.rs @@ -0,0 +1,5 @@ +// Generated by v1 compiler -- do not edit. + +#![allow(unused_parens, clippy::all, clippy::disallowed_macros)] + +fn main() {} diff --git a/.probe/ka/out/src/probe_m.rs b/.probe/ka/out/src/probe_m.rs new file mode 100644 index 00000000000..380c546b5a1 --- /dev/null +++ b/.probe/ka/out/src/probe_m.rs @@ -0,0 +1,22 @@ +// Generated by v1 compiler -- do not edit. +// Source module: probe.m + +use im::{vector as vec, HashMap, OrdSet as BTreeSet, Vector as Vec}; +use crate::v1_rt::{VecCompat, VecJoin}; +use std::rc::Rc; +use crate::v1_rt; +use crate::NonEmptyVec; +use crate::NonEmptyBTreeSet; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BoxI { + pub v: i64, + pub _phantom: std::marker::PhantomData, +} + +pub fn mk() -> Rc> { + Rc::new(BoxI { + v: 1, + _phantom: std::marker::PhantomData, +}) +} diff --git a/.probe/ka/out/src/v1_rt.rs b/.probe/ka/out/src/v1_rt.rs new file mode 100644 index 00000000000..fb7794c32ce --- /dev/null +++ b/.probe/ka/out/src/v1_rt.rs @@ -0,0 +1,864 @@ +//! Runtime shims for v2 compiler intrinsic operations. +//! Generated by the v2 compiler -- do not edit. + +#![allow(unused_variables, dead_code)] + +use im::{HashMap, OrdSet as BTreeSet, Vector as Vec}; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; + +#[cfg(feature = "text_lookup_work_counter")] +thread_local! { + static TEXT_LOOKUP_CHARS_WALKED: Cell = Cell::new(0); +} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn reset_text_lookup_chars_walked() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(0)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn reset_text_lookup_chars_walked() {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn take_text_lookup_chars_walked() -> u64 { + TEXT_LOOKUP_CHARS_WALKED.with(|c| { + let walked = c.get(); + c.set(0); + walked + }) +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn take_text_lookup_chars_walked() -> u64 { 0 } + +#[cfg(feature = "text_lookup_work_counter")] +fn record_substring_chars_walked(s: &str, start: usize, take_len: usize) { + let walked = if s.is_ascii() { + take_len as u64 + } else { + (start + take_len) as u64 + }; + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + walked)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_substring_chars_walked(_s: &str, _start: usize, _take_len: usize) {} + +#[cfg(feature = "text_lookup_work_counter")] +fn record_source_chars_slice_walked(units: u64) { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + units)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +fn record_source_chars_slice_walked(_units: u64) {} + +#[cfg(feature = "text_lookup_work_counter")] +pub fn record_source_chars_index_lookup() { + TEXT_LOOKUP_CHARS_WALKED.with(|c| c.set(c.get() + 1)); +} + +#[cfg(not(feature = "text_lookup_work_counter"))] +pub fn record_source_chars_index_lookup() {} + +/// Read-only silent-pick telemetry for resolution divergence census slice 2. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpPickSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, + pub chosen_module_path: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct GlobalBareLcpTieSite { + pub env_module_path: String, + pub name: String, + pub candidate_count: usize, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct FnParentFirstHitSite { + pub env_module_path: String, + pub name: String, + pub parent_match_count: usize, + pub chosen_parent_module: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct SilentPickTelemetry { + pub global_bare_lcp_picks: std::vec::Vec, + pub global_bare_lcp_ties: std::vec::Vec, + pub fn_parent_first_hits: std::vec::Vec, +} + +thread_local! { + static RESOLUTION_SILENT_PICK_ENABLED: Cell = const { Cell::new(false) }; + static RESOLUTION_SILENT_PICK: RefCell = RefCell::new(SilentPickTelemetry::default()); +} + +pub fn resolution_silent_pick_enable() { + RESOLUTION_SILENT_PICK.with(|t| *t.borrow_mut() = SilentPickTelemetry::default()); + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(true)); +} + +pub fn resolution_silent_pick_disable() -> SilentPickTelemetry { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.set(false)); + RESOLUTION_SILENT_PICK.with(|t| std::mem::take(&mut *t.borrow_mut())) +} + +pub fn resolution_silent_pick_is_enabled() -> bool { + RESOLUTION_SILENT_PICK_ENABLED.with(|e| e.get()) +} + +pub fn resolution_silent_pick_record_global_bare_lcp_pick( + env_module_path: String, + name: String, + candidate_count: i64, + chosen_module_path: String, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_picks.push(GlobalBareLcpPickSite { + env_module_path, + name, + candidate_count, + chosen_module_path, + }); + }); +} + +pub fn resolution_silent_pick_record_global_bare_lcp_tie( + env_module_path: String, + name: String, + candidate_count: i64, +) { + let candidate_count = candidate_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || candidate_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().global_bare_lcp_ties.push(GlobalBareLcpTieSite { + env_module_path, + name, + candidate_count, + }); + }); +} + +// NameResolutionPolicy gate (namespace-resolution-design.md 13, 8 step 4): default +// true = NamespaceOnlyY — strict unique-on-chain in the type/value path and +// exactly-one across the fn parent closure, with typed Ambiguous refusals. +// false = ImportScoped (legacy resolver, byte-for-byte). Host-side setter only; +// no .dag surface can flip it (no escape hatch — a flip is an explicit host decision). +thread_local! { + static NAME_RESOLUTION_POLICY_NAMESPACE_ONLY: Cell = const { Cell::new(true) }; +} + +pub fn name_resolution_policy_set_namespace_only(enabled: bool) { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.set(enabled)); +} + +pub fn name_resolution_policy_is_namespace_only() -> bool { + NAME_RESOLUTION_POLICY_NAMESPACE_ONLY.with(|e| e.get()) +} + +// N1a measurement arm (type-ref hit≠bind discriminator): default false = production +// fail-open path. Host-side setter only — compile_dag_diagnostic_census arms for the +// nested synthetic compile; no .dag surface can flip it (same shape as +// name_resolution_policy — no escape hatch). +thread_local! { + static TYPE_REF_HIT_NE_BIND_MEASURE: Cell = const { Cell::new(false) }; +} + +pub fn type_ref_hit_ne_bind_measure_set(enabled: bool) { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.set(enabled)); +} + +pub fn type_ref_hit_ne_bind_measure_active() -> bool { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|e| e.get()) +} + +pub fn with_type_ref_hit_ne_bind_measure(f: impl FnOnce() -> T) -> T { + TYPE_REF_HIT_NE_BIND_MEASURE.with(|c| { + let prev = c.get(); + c.set(true); + let out = f(); + c.set(prev); + out + }) +} + +pub fn resolution_silent_pick_record_fn_parent_first_hit( + env_module_path: String, + name: String, + parent_match_count: i64, + chosen_parent_module: String, +) { + let parent_match_count = parent_match_count.max(0) as usize; + if !resolution_silent_pick_is_enabled() || parent_match_count < 2 { + return; + } + RESOLUTION_SILENT_PICK.with(|t| { + t.borrow_mut().fn_parent_first_hits.push(FnParentFirstHitSite { + env_module_path, + name, + parent_match_count, + chosen_parent_module, + }); + }); +} + +// Vec here is im's persistent Vector (one realization with the +// interpreter's Value::List). VecCompat papers the std-Vec API deltas the +// emitter's method rows rely on (first/push/with_capacity; join via VecJoin) +// so emitted call sites stay identical across carriers. +pub trait VecCompat { + fn first(&self) -> Option<&T>; + fn push(&mut self, item: T); + fn with_capacity(capacity: usize) -> Self; +} + +impl VecCompat for Vec { + fn first(&self) -> Option<&T> { self.front() } + fn push(&mut self, item: T) { self.push_back(item); } + fn with_capacity(_capacity: usize) -> Self { Vec::new() } +} + +pub trait VecJoin { + fn join(&self, sep: &str) -> String; +} + +impl VecJoin for Vec { + fn join(&self, sep: &str) -> String { + self.iter().cloned().collect::>().join(sep) + } +} + +pub trait V2Concat { + fn v1_concat(self, other: Self) -> Self; +} + +impl V2Concat for String { + fn v1_concat(mut self, other: String) -> String { self.push_str(&other); self } +} + +impl V2Concat for Vec { + fn v1_concat(mut self, other: Vec) -> Vec { self.extend(other); self } +} + +pub fn concat(a: T, b: T) -> T { a.v1_concat(b) } + +/// Ascii-aware variant taking a precomputed `is_ascii` flag (the `RcStr` carrier fact) +/// instead of rescanning the whole string on every call -- the per-call `s.is_ascii()` +/// scan is what made repeated indexing over a large string O(n^2) (STRING-INDEX-0). +pub fn char_at_ascii_aware(s: &str, is_ascii: bool, pos: i64) -> String { + let pos = pos.max(0) as usize; + if is_ascii { + let bytes = s.as_bytes(); + if pos >= bytes.len() { return String::new(); } + return String::from(bytes[pos] as char); + } + s.chars().nth(pos).map(|ch| ch.to_string()).unwrap_or_default() +} + +pub fn char_at(s: &str, pos: i64) -> String { + char_at_ascii_aware(s, s.is_ascii(), pos) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn string_length_ascii_aware(s: &str, is_ascii: bool) -> i64 { + if is_ascii { s.len() as i64 } else { s.chars().count() as i64 } +} + +pub fn string_length(s: &str) -> i64 { + string_length_ascii_aware(s, s.is_ascii()) +} + +/// Ascii-aware variant taking a precomputed `is_ascii` flag; see `char_at_ascii_aware`. +pub fn substring_ascii_aware(s: &str, is_ascii: bool, start: i64, end: i64) -> String { + let start = start.max(0) as usize; + let end = end.max(0) as usize; + if end <= start { return String::new(); } + if is_ascii { + let len = s.len(); + if start >= len { return String::new(); } + let out_end = end.min(len); + let take_len = out_end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + return s[start..out_end].to_string(); + } + let take_len = end.saturating_sub(start); + record_substring_chars_walked(s, start, take_len); + s.chars().skip(start).take(take_len).collect() +} + +pub fn substring(s: &str, start: i64, end: i64) -> String { + substring_ascii_aware(s, s.is_ascii(), start, end) +} + +pub fn string_contains(s: &str, sub: String) -> bool { + s.contains(&*sub) +} + +pub fn contains(s: String, sub: String) -> bool { string_contains(&s, sub) } + +pub fn starts_with(s: String, prefix: String) -> bool { s.starts_with(&*prefix) } + +pub fn ends_with(s: String, suffix: String) -> bool { s.ends_with(&*suffix) } + +pub fn trim(s: String) -> String { s.trim().to_string() } + +pub fn count(items: Rc>) -> i64 { items.len() as i64 } + +pub fn str_eq(a: String, b: String) -> bool { a == b } + +pub fn to_string(value: i64) -> String { value.to_string() } + +/// RFC 3629 UTF-8 decode of a byte vector. Fail-closed on invalid UTF-8. +pub fn utf8_decode_bytes(bytes: &[u8]) -> Result { + String::from_utf8(bytes.to_vec()).map_err(|e| format!("invalid UTF-8 in access payload: {}", e)) +} + +pub fn clamp(val: i64, min_val: i64, max_val: i64) -> i64 { + val.clamp(min_val, max_val) +} + +pub fn lookup(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn index_by String>(list: Vec, key_fn: F) -> HashMap { + let mut map = HashMap::new(); + for item in list { let key = key_fn(&item); map.insert(key, item); } + map +} + +pub fn empty_map() -> HashMap { HashMap::new() } + +pub fn map_insert(mut map: HashMap, key: K, value: V) -> HashMap { + map.insert(key, value); map +} + +pub fn map_merge(mut base: HashMap, overlay: HashMap) -> HashMap { + base.extend(overlay); base +} + +pub fn map_get(m: &HashMap, key: K) -> Option { + m.get(&key).cloned() +} + +pub fn map_keys(m: &HashMap) -> Vec { m.keys().cloned().collect() } + +pub fn sorted_map_keys(m: &HashMap) -> Vec { let mut keys = map_keys(m); keys.sort(); keys } + +pub fn map_is_empty(m: &HashMap) -> bool { m.is_empty() } + +// Sound identity hint (see 04_infer.dag substitute_generics): returns true => +// the two are structurally equal. The compiled realization answers with pointer +// identity (conservative: may say false when equal); never true-when-unequal, so +// callers that return the original on true preserve output structure. Owned Rc +// args (cheap refcount bump) keep the inner element pointers, so ptr_eq on the +// clones equals ptr_eq on the originals -- lets the .dag pass args by value and +// emit through the normal clone path (no all-args-by-ref emit rule needed). +pub fn rc_ptr_eq(a: Rc, b: Rc) -> bool { Rc::ptr_eq(&a, &b) } + +pub fn rc_vec_ptr_eq(a: Rc>>, b: Rc>>) -> bool { + a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| Rc::ptr_eq(x, y)) +} + +pub fn map_values(m: &HashMap) -> Vec { m.values().cloned().collect() } + +pub fn list_concat(mut a: Vec, b: Vec) -> Vec { a.extend(b); a } + +pub fn list_push(mut list: Vec, item: T) -> Vec { list.push_back(item); list } + +pub fn append(list: Rc>, item: T) -> Vec { + let mut v = (*list).clone(); + v.push_back(item); + v +} + +pub fn chars_to_string(chars: &Rc>, start: i64, end: i64) -> String { + let len = chars.len(); + let start = (start.max(0) as usize).min(len); + let end = (end.max(0) as usize).min(len).max(start); + let units = (end.saturating_sub(start)) as u64; + record_source_chars_slice_walked(units); + // Focus caches the current RRB chunk, so per-char access is contiguous-slice + // speed; a plain iter().skip(start) walks O(start) per call, which summed + // quadratically across a tokenize pass (profiled 2026-07-06). + let mut focus = chars.focus(); + let mut out = String::with_capacity(end - start); + for i in start..end { + if let Some(ch) = char::from_u32(*focus.index(i) as u32) { + out.push(ch); + } + } + out +} + +pub fn parse_int(s: String) -> Option { s.parse::().ok() } + +pub fn map_contains_key(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn map_has(m: &HashMap, key: K) -> bool { + m.contains_key(&key) +} + +pub fn rc_empty_set() -> Rc> { + Rc::new(BTreeSet::new()) +} + +pub fn rc_set_insert(mut s: Rc>, x: T) -> Rc> { + Rc::make_mut(&mut s).insert(x); + s +} + +pub fn rc_set_union(a: Rc>, b: Rc>) -> Rc> { + let mut out = a; + for x in b.iter().cloned() { + Rc::make_mut(&mut out).insert(x); + } + out +} + +pub fn set_contains>>(s: S, x: T) -> bool { + s.as_ref().contains(&x) +} + +pub fn reverse(list: Rc>) -> Rc> { + Rc::new(list.iter().cloned().rev().collect()) +} + +pub fn replace(s: String, from: String, to: String) -> String { + s.replace(&from, &to) +} + +// -- Rc-wrapped container operations (FF-8) --------------------------------- +// These mirror the bare Vec/HashMap functions above but operate on Rc-wrapped +// containers for O(1) clone cost. Generated code using Rc container templates +// will call these. Read-only functions (map_get, map_keys, map_values, lookup, +// map_contains_key, map_has) work with Rc via auto-deref. + +// take_owned: move out of a uniquely-held Rc; clone when shared. With every +// container realized persistently (im), the shared-arm clone is cheap +// structural sharing — an ordinary designed path, not a degradation arm, so +// no counter and no refusal (the clone-fallback guard class was deleted with +// the Rc carriers it policed). +pub fn take_owned(x: Rc) -> T { + match Rc::try_unwrap(x) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } +} + +pub fn rc_list_push(list: Rc>, item: T) -> Rc> { + let mut v = list; + Rc::make_mut(&mut v).push_back(item); + v +} + +pub fn rc_list_concat(a: Rc>, b: Rc>) -> Rc> { + let mut result = a; + Rc::make_mut(&mut result).extend(b.iter().cloned()); + result +} + +// Every rc_* update here rides a persistent carrier (im HashMap/Vector/ +// OrdSet — one realization with the interpreter's Value::Map/List/Set), so +// make_mut's clone arm is O(1) structural sharing and each update copies an +// O(log n) node path — a designed update, never a degradation arm. +pub fn rc_map_insert(map: Rc>, key: K, value: V) -> Rc> { + let mut m = map; + Rc::make_mut(&mut m).insert(key, value); + m +} + +pub fn rc_map_merge(base: Rc>, overlay: Rc>) -> Rc> { + let mut result = base; + let inner = Rc::make_mut(&mut result); + for (k, v) in overlay.iter() { + inner.insert(k.clone(), v.clone()); + } + result +} + +pub fn rc_index_by String>(list: Rc>, key_fn: F) -> Rc> { + Rc::new(list.iter().map(|v| (key_fn(v), v.clone())).collect()) +} + +pub fn rc_empty_map() -> Rc> { Rc::new(HashMap::new()) } + +impl V2Concat for Rc> { + fn v1_concat(self, other: Rc>) -> Rc> { rc_list_concat(self, other) } +} + +pub fn scan_while(s: &str, start: i64, pred: impl Fn(String) -> bool) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && pred(String::from(bytes[pos] as char)) { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if pred(ch.to_string()) { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn skip_horizontal_ws(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() && (bytes[pos] == b' ' || bytes[pos] == b'\t') { pos += 1; } + return pos as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == ' ' || ch == '\t' { pos += 1; } else { break; } + } + pos as i64 +} + +pub fn scan_to_eol(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let start = start.min(bytes.len()); + for i in start..bytes.len() { if bytes[i] == b'\n' { return i as i64; } } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + for ch in s.chars().skip(start) { + if ch == '\n' { return pos as i64; } + pos += 1; + } + pos as i64 +} + +pub fn scan_string_end(s: &str, start: i64) -> i64 { + let start = start.max(0) as usize; + if s.is_ascii() { + let bytes = s.as_bytes(); + let mut pos = start.min(bytes.len()); + while pos < bytes.len() { + if bytes[pos] == b'\\' { pos += 2; } + else if bytes[pos] == b'\"' { return (pos + 1) as i64; } + else { pos += 1; } + } + return bytes.len() as i64; + } + let char_len = s.chars().count(); + let start = start.min(char_len); + let mut pos = start; + let mut escaped = false; + for ch in s.chars().skip(start) { + if escaped { + escaped = false; + pos += 1; + } else if ch == '\\' { + escaped = true; + pos += 1; + } else if ch == '\"' { + return (pos + 1) as i64; + } else { + pos += 1; + } + } + pos as i64 +} + +pub fn code_point(c: String) -> i64 { + c.chars().next().map(|ch| ch as i64).unwrap_or(0) +} + +pub fn from_code_point(cp: i64) -> String { + char::from_u32(cp as u32).map(|c| c.to_string()).unwrap_or_default() +} + +pub fn is_xid_start(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_start).unwrap_or(false) +} + +pub fn is_xid_continue(cp: i64) -> bool { + char::from_u32(cp as u32).map(unicode_ident::is_xid_continue).unwrap_or(false) +} + +pub fn is_emoji_ident(cp: i64) -> bool { + use unicode_properties::emoji::UnicodeEmoji; + use unicode_properties::emoji::EmojiStatus; + char::from_u32(cp as u32).map(|c| matches!(c.emoji_status(), EmojiStatus::EmojiPresentation | EmojiStatus::EmojiPresentationAndModifierBase | EmojiStatus::EmojiPresentationAndEmojiComponent | EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent) && !unicode_ident::is_xid_continue(c)).unwrap_or(false) +} + +// FreeMonoid host bridge (String = FreeMonoid) — relocated from v2_std_algebra +// so the Char authority (i64 / std.types.Char) is not pinned to v2_std_nat::Nat. +pub fn freemonoid_empty() -> Rc> { + Rc::new(Vec::new()) +} + +pub fn list_snoc_item(xs: Rc>, item: T) -> Rc> { + let mut out = xs.as_ref().clone(); + out.push_back(item); + Rc::new(out) +} + +pub fn fold_list(xs: Rc>, init: A, f: F) -> A +where + F: Fn(A, T) -> A, +{ + let mut acc = init; + for item in xs.iter() { + acc = f(acc, item.clone()); + } + acc +} + +const FNV1A64_OFFSET: u64 = 0xcbf29ce484222325; +const FNV1A64_PRIME: u64 = 0x100000001b3; + +fn fnv1a64(bytes: &[u8]) -> u64 { + let mut hash = FNV1A64_OFFSET; + for b in bytes { + hash ^= *b as u64; + hash = hash.wrapping_mul(FNV1A64_PRIME); + } + hash +} + +pub type Hash = String; + +const HASH_DIGEST_LEN: usize = 16; + +pub fn is_hash_digest(s: &str) -> bool { + s.len() == HASH_DIGEST_LEN && s.bytes().all(|b| b.is_ascii_hexdigit()) +} + +fn expect_hash_digest(s: &str, arg: &str) { + if !is_hash_digest(s) { + panic!("{} must be a 16-char hex Hash digest", arg); + } +} + +/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the +/// raw gantt key=value shape (process-absolute millis and rss-mib fields) dissolves into the observation projection. +#[allow(dead_code)] +pub const GANTT_CENSUS_MARKER: &str = "[gantt]"; + +/// Mirror of `gunbc.observation_ci_render.ci_minute_switch_seconds`. +const OBS_MINUTE_SWITCH_SECONDS: u64 = 90; + +pub fn obs_human_duration(ms: u64) -> String { + if ms < 1_000 { + format!("{ms}ms") + } else if ms < OBS_MINUTE_SWITCH_SECONDS * 1_000 { + format!("{} seconds", ms / 1_000) + } else { + format!("{} minutes", ms / 60_000) + } +} + +/// Mirror of `gunbc.observation_ci_render.ci_human_elapsed`. +pub fn obs_human_elapsed(wall_nanos: u128) -> String { + if wall_nanos < 1_000_000 { + format!("{wall_nanos}ns") + } else { + obs_human_duration((wall_nanos / 1_000_000) as u64) + } +} + +fn obs_phase_emoji() -> bool { + std::env::var("GITHUB_ACTIONS").as_deref() == Ok("true") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_begin_line` — +/// `ci_event_line(Begin) ∘ ci_render_line`. Justified divergence from the +/// interpreter seed boundary used by floor prelude marks: `trace_mark` runs +/// inside compile itself (hand-synced path and interpreter intrinsic), and +/// calling back into the interpreter to render would recurse. Proven +/// byte-equal to the `.dag` oracle by the seed RED. +pub fn render_phase_begin_line_mirror(phase: &str, emoji: bool) -> String { + let glyph = if emoji { "🔄" } else { "◐" }; + format!("{glyph} started {phase}") +} + +/// Pure Rust mirror of `gunbc.observation_seed_render.phase_concluded_line` — +/// `ci_event_line(Concluded{Done}) ∘ ci_render_line`. Same justified-divergence +/// note as `render_phase_begin_line_mirror`. +pub fn render_phase_concluded_line_mirror(phase: &str, elapsed_ms: u64, emoji: bool) -> String { + let glyph = if emoji { "✅" } else { "✓" }; + format!("{glyph} {phase} done in {}", obs_human_duration(elapsed_ms)) +} + +/// Stage-boundary trace mark — the v1-seed interim realization of the v2 per-RealizedStep +/// CostAccount (std.realization_measurement). Wired (gantt flip): projects Begin/Concluded +/// on a PhaseSegment via the observation mirrors of `ci_event_line`. Segment wall on +/// Concluded (matched `.begin`→`.done`, else delta since last mark) — never the old +/// process-absolute millis field. RSS stays on heartbeat/measurement (`ci_event_line` does +/// not project `event.rss` — explicit divergence from the deleted rss-mib field). +/// +/// **Dissolution trigger (DESIGN §6):** delete this fn, the `trace_mark` registry row in +/// `04_method.dag` (+ hand-synced twin `v1_compiler_infer_method.rs`), the nine +/// `trace_mark(...)` marks in `compile.dag` (+ hand-synced `v1_compiler_compile.rs`), and +/// the interpreter arm in `v1_interpreter.rs` when realization_measurement_loop **Phase 0** +/// (`docs/plans/realization-measurement-loop.md`) lands a `.dag` `PerformanceReceipt` +/// per-stage carrier that a floor witness consumes by execution (the same retirement event +/// as `phase_profile.rs` / `GUNBC_FLOOR_GANTT`, per `docs/plans/ci-floor-fractal-gantt.md` +/// § dissolution). Receipt = that witness green with these marks deleted and stage walls +/// still attributable from the model path. +pub fn trace_mark(label: String) { + use std::sync::{Mutex, OnceLock}; + use std::time::Instant; + static TRACE_T0: OnceLock = OnceLock::new(); + static LAST_MARK: OnceLock> = OnceLock::new(); + static OPENS: OnceLock>> = OnceLock::new(); + let t0 = TRACE_T0.get_or_init(Instant::now); + let last = LAST_MARK.get_or_init(|| Mutex::new(*t0)); + let opens = OPENS.get_or_init(|| Mutex::new(std::collections::HashMap::new())); + let emoji = obs_phase_emoji(); + let now = Instant::now(); + let _ = GANTT_CENSUS_MARKER; + if let Some(phase) = label.strip_suffix(".begin") { + if let Ok(mut map) = opens.lock() { + map.insert(phase.to_string(), now); + } + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!("{}", render_phase_begin_line_mirror(phase, emoji)); + } else if let Some(phase) = label.strip_suffix(".done") { + let elapsed_ms = { + let started = opens.lock().ok().and_then(|mut m| m.remove(phase)); + match started { + Some(t) => now.saturating_duration_since(t).as_millis() as u64, + None => { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + now.saturating_duration_since(prev).as_millis() as u64 + } + } + }; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(phase, elapsed_ms, emoji) + ); + } else { + let prev = last.lock().map(|l| *l).unwrap_or(*t0); + let elapsed_ms = now.saturating_duration_since(prev).as_millis() as u64; + if let Ok(mut l) = last.lock() { + *l = now; + } + eprintln!( + "{}", + render_phase_concluded_line_mirror(&label, elapsed_ms, emoji) + ); + } +} + +/// Content hash over raw bytes — the byte-level single authority. `atom_identity_hash` +/// is the `String` projection of this. Use this directly for arbitrary binary content +/// (e.g. an executable or serialized payload): routing bytes through `String`/ +/// `from_utf8_lossy` first collapses every invalid UTF-8 sequence to U+FFFD, so distinct +/// byte sequences would hash equal — a §5 silent-collision fail-open for content-addressing. +pub fn bytes_identity_hash(bytes: &[u8]) -> Hash { + format!("{:016x}", fnv1a64(bytes)) +} + +pub fn atom_identity_hash(s: String) -> Hash { + bytes_identity_hash(s.as_bytes()) +} + +pub fn hash_combine(a: Hash, b: Hash) -> Hash { + expect_hash_digest(&a, "a"); + expect_hash_digest(&b, "b"); + let mut bytes = a.into_bytes(); + bytes.push(0); + bytes.extend_from_slice(b.as_bytes()); + format!("{:016x}", fnv1a64(&bytes)) +} + +#[derive(Debug, Clone)] +pub struct FilesystemReadResult { + pub content: String, +} + +pub fn filesystem_read(path: String) -> FilesystemReadResult { + let content = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("failed to read {}: {}", path, e)); + FilesystemReadResult { content } +} +fn int_relu(x: i64) -> i64 { + if x > 0 { x } else { 0 } +} + +/// Opcode wire authority: `extdeps.languages.simd.kernel.relu_mul_add_wire_op_codes`. +/// Scaffold regen-sync: see `host_kernel_relu_mul_add_op_codes_scaffold_note` until feature:dag-kernel-realization-handler. +const RELU_MUL_ADD_OP_CODES: [i64; 3] = [1, 2, 3]; + +fn assert_relu_mul_add_op_codes(op_codes: &[i64], _handler: &str) { + if op_codes != RELU_MUL_ADD_OP_CODES { + panic!("unsupported op_codes in accelerator demo kernel"); + } +} + +/// Host bridge: `.dag` passes `std.numerical_contract.FmaContractionPolicy`; interpreter maps to 0/1 until target_model emit. +pub fn contiguous_loop_elementwise_float_kernel( + op_codes: &[i64], + fma_contraction_policy: i64, + a: &[f64], + b: &[f64], + c: &[f64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_float_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let elem = match fma_contraction_policy { + 0 => { + let prod = a[i] * b[i]; + prod + c[i] + }, + 1 => a[i].mul_add(b[i], c[i]), + _ => panic!("unknown fma_contraction_policy"), + }; + out.push(if elem > 0.0 { elem } else { 0.0 }); + } + out +} + +/// Integer oracle authority: `gunbc.accelerator_demo_eval` via interpreter `Int` binops (`*`/`+`). +/// Host kernel uses `wrapping_*` to mirror release interpreter overflow semantics; demo fixtures +/// stay in-range under `IntegerExact` — out-of-range inputs are outside the bit-exact bar. +pub fn contiguous_loop_elementwise_kernel( + op_codes: &[i64], + a: &[i64], + b: &[i64], + c: &[i64], +) -> Vec { + assert_relu_mul_add_op_codes(op_codes, "contiguous_loop_elementwise_kernel"); + assert_eq!(a.len(), b.len()); + assert_eq!(b.len(), c.len()); + let mut out = Vec::with_capacity(a.len()); + for i in 0..a.len() { + let tmp = a[i].wrapping_mul(b[i]).wrapping_add(c[i]); + out.push(int_relu(tmp)); + } + out +} diff --git a/.probe/kb2/m.dag b/.probe/kb2/m.dag new file mode 100644 index 00000000000..b774bd364a3 --- /dev/null +++ b/.probe/kb2/m.dag @@ -0,0 +1,7 @@ +module probe.m +type BoxI { + v: Int +} +fn mk() -> BoxI { + BoxI { v: "s" } +} diff --git a/.probe/pair/m.dag b/.probe/pair/m.dag new file mode 100644 index 00000000000..e0392565619 --- /dev/null +++ b/.probe/pair/m.dag @@ -0,0 +1,35 @@ +module t.arms + +type LexResult + = Rejected + | Accepted { remaining: String } + +type Thunk { + apply: fn(String) -> LexResult +} + +type PlainFold { + delimited: fn(Thunk, Thunk, Thunk) -> Thunk +} + +type GenericFold { + empty: R + delimited: fn(R, R, R) -> R +} + +fn arm_a_non_generic_algebra() -> PlainFold { + PlainFold { + delimited: fn(open_r, body_r, close_r) { + Thunk { apply: fn(s) { open_r.apply(s) } } + } + } +} + +fn arm_b_generic_algebra_concrete_thunk() -> GenericFold { + GenericFold { + empty: Thunk { apply: fn(s) { Rejected } }, + delimited: fn(open_r, body_r, close_r) { + Thunk { apply: fn(s) { open_r.apply(s) } } + } + } +} diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index 15d42165261..1fd250e2921 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -4550,7 +4550,13 @@ fn infer_expr_body(texpr: Node, scope: InferScope, expected: Node?) -> InferResu fold(lam_params |> enumerate, init: scope, f: (acc, pair) => let param_prov = if pair.first == (lam_params |> count) - 1 { elem_prov } else { SubValueUnknown } match exp.params |> skip(pair.first) |> first { - Present { value: cp } => extend_scope(scope: acc, name: pair.second, resolved: param_node_type_expr(n: cp), provenance: param_prov) + Present { value: cp } => + let cpt = param_node_type_expr(n: cp) + if type_node_is_established(n: cpt, source_indices: scope.type_env.source_indices) { + extend_scope(scope: acc, name: pair.second, resolved: cpt, provenance: param_prov) + } else { + extend_scope(scope: acc, name: pair.second, resolved: type_variable_node(id: "callable_param"), provenance: param_prov) + } Absent => extend_scope(scope: acc, name: pair.second, resolved: type_variable_node(id: "callable_param"), provenance: param_prov) } ) diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index a61fc525b19..98ef8d6b515 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -8212,12 +8212,27 @@ if ((call_ambiguity_cands.clone().len() as i64) > 0) { .skip(pair.0.clone() as usize) .next() { - Some(cp) => extend_scope( - acc.clone(), - pair.1.clone(), - param_node_type_expr(cp.clone()), - param_prov.clone(), - ), + Some(cp) => { + let cpt = param_node_type_expr(cp.clone()); + if type_node_is_established( + cpt.clone(), + scope.type_env.clone().source_indices.clone(), + ) { + extend_scope( + acc.clone(), + pair.1.clone(), + cpt.clone(), + param_prov.clone(), + ) + } else { + extend_scope( + acc.clone(), + pair.1.clone(), + type_variable_node("callable_param".to_string()), + param_prov.clone(), + ) + } + } None => extend_scope( acc.clone(), pair.1.clone(), From df90bc85415f087ed8d590e9a68bb46b3e711514 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 23 Aug 2026 01:17:43 +0000 Subject: [PATCH 15/17] Install emitted mirror for v1_compiler_emit_rust.rs (clone elision from the established-type fix) --- src/v1/stage0/src/v1_compiler_emit_rust.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 218d8463569..fc7fab7cfdc 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -30826,7 +30826,7 @@ pub fn emit_file_path_line( }); let fmt_str = Rc::new({ let mut __result = Vec::new(); - for p in parts.clone().iter().cloned() { + for p in parts.iter().cloned() { __result.push(match (*p.clone()).clone() { StringPart::Text { value: v, .. } => escape_rust_interp_text(v.clone()), StringPart::Interpolation { expr: _, .. } => "{}".to_string(), @@ -30837,7 +30837,7 @@ pub fn emit_file_path_line( .join(&"".to_string()); let args = Rc::new({ let mut __result = Vec::new(); - for p in parts.clone().iter().cloned() { + for p in parts.iter().cloned() { __result.extend( (*match (*p.clone()).clone() { StringPart::Text { value: _, .. } => Rc::new(vec![]), @@ -31043,7 +31043,7 @@ pub fn emit_file_return( let fields = file_output_channel_fields(op_node.clone()); let field_exprs = Rc::new({ let mut __result = Vec::new(); - for ch in fields.clone().iter().cloned() { + for ch in fields.iter().cloned() { __result.push(emit_file_channel_expr( file_output_channel_of_field(ch.clone(), source_indices.clone()), (ch.return_cardinality.clone() == Cardinality::CardOptional), From 18b5ddc6261acd3c5398a5fc5429fd9ea2e48f63 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 23 Aug 2026 03:41:25 +0000 Subject: [PATCH 16/17] BISECT ARM (not a landing state): revert (a) field_substitution_carrier, keep (c) Diagnostic push on a draft PR to separate (a) from (c) by execution. The floor caught 9 claims that pass on main and fail on this branch, every one of them against an independently authored oracle, so main's pass was not vacuous and this branch computes wrong values. Local floor OOMs (137) in a session container, so CI is the only instrument at whole-corpus scope. This arm reverts (a) only. It deliberately re-opens the row-(a) defect -- the kb2 RED will stop refusing -- and is NOT proposed for merge. Read the floor line, not the arms. Predicts: if (a) is the culprit, failed goes 9 -> 0 and the 6 samsung_dram stale-quarantine rows stay unmasked. If (c) is, failed stays 9. --- src/v1/04_infer.dag | 18 +------------ src/v1/stage0/src/v1_compiler_infer.rs | 37 +------------------------- 2 files changed, 2 insertions(+), 53 deletions(-) diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index d7d2b734b80..475a0c96c77 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -1112,22 +1112,6 @@ fn record_lit_fields_from_expected(type_name: String?, expected: Node?, scope: I } } -fn field_type_expr_is_stripped_placeholder(te: Node, source_indices: Map) -> Bool { - authored_name_at(source_indices: source_indices, node: te) == "" - && te.children |> count == 0 - && te.params |> count == 0 -} - -fn field_substitution_carrier(sf: Node, source_indices: Map) -> Node { - let te = field_node_type_expr(n: sf) - if field_type_expr_is_stripped_placeholder(te: te, source_indices: source_indices) { - match sf.inferred { - Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) - _ => te - } - } else { te } -} - fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: InferScope) -> List? { match type_name { Present { value: tn } => @@ -1155,7 +1139,7 @@ fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: In Node { name: sf.name, span: sf.span, ident_span: sf.ident_span, children: sf.children, connective: sf.connective, params: sf.params, - inferred: Present { value: Resolved { node: substitute_generics(n: field_substitution_carrier(sf: sf, source_indices: scope.type_env.source_indices), subst: subst, source_indices: scope.type_env.source_indices) } }, + inferred: Present { value: Resolved { node: substitute_generics(n: field_node_type_expr(n: sf), subst: subst, source_indices: scope.type_env.source_indices) } }, return_cardinality: sf.return_cardinality, uses: sf.uses, body: sf.body, transport: sf.transport, properties: sf.properties, type_annotation: sf.type_annotation, is_self_recursive: sf.is_self_recursive, diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index 36c0c3e4b6f..f1c63b96fd0 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -1715,34 +1715,6 @@ pub fn record_lit_fields_from_expected( } } -pub fn field_type_expr_is_stripped_placeholder( - te: Rc, - source_indices: Rc>>, -) -> bool { - (((authored_name_at(source_indices.clone(), te.clone()) == "".to_string()) - && ((te.children.clone().len() as i64) == 0)) - && ((te.params.clone().len() as i64) == 0)) -} - -pub fn field_substitution_carrier( - sf: Rc, - source_indices: Rc>>, -) -> Rc { - { - let te = field_node_type_expr(sf.clone()); - if field_type_expr_is_stripped_placeholder(te.clone(), source_indices.clone()) { - match sf.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => { - preserve_outer_optional_cardinality(sf.clone(), rt.clone()) - } - _ => te.clone(), - } - } else { - te.clone() - } - } -} - pub fn record_lit_instantiated_fields( type_name: Option, expected: Option>, @@ -1790,14 +1762,7 @@ match exp.children.clone().iter().cloned().skip(pair.0.clone() as usize).next() inferred: Some(Rc::new( InferredNode::Resolved { node: substitute_generics( - field_substitution_carrier( - sf.clone(), - scope - .type_env - .clone() - .source_indices - .clone(), - ), + field_node_type_expr(sf.clone()), subst.clone(), scope .type_env From 1626a9e91947e804a7316e9d502f8d46cdf88065 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 23 Aug 2026 04:23:44 +0000 Subject: [PATCH 17/17] Revert "BISECT ARM (not a landing state): revert (a) field_substitution_carrier, keep (c)" This reverts commit 18b5ddc6261acd3c5398a5fc5429fd9ea2e48f63. --- src/v1/04_infer.dag | 18 ++++++++++++- src/v1/stage0/src/v1_compiler_infer.rs | 37 +++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index 475a0c96c77..d7d2b734b80 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -1112,6 +1112,22 @@ fn record_lit_fields_from_expected(type_name: String?, expected: Node?, scope: I } } +fn field_type_expr_is_stripped_placeholder(te: Node, source_indices: Map) -> Bool { + authored_name_at(source_indices: source_indices, node: te) == "" + && te.children |> count == 0 + && te.params |> count == 0 +} + +fn field_substitution_carrier(sf: Node, source_indices: Map) -> Node { + let te = field_node_type_expr(n: sf) + if field_type_expr_is_stripped_placeholder(te: te, source_indices: source_indices) { + match sf.inferred { + Present { value: Resolved { node: rt } } => preserve_outer_optional_cardinality(outer: sf, inner: rt) + _ => te + } + } else { te } +} + fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: InferScope) -> List? { match type_name { Present { value: tn } => @@ -1139,7 +1155,7 @@ fn record_lit_instantiated_fields(type_name: String?, expected: Node?, scope: In Node { name: sf.name, span: sf.span, ident_span: sf.ident_span, children: sf.children, connective: sf.connective, params: sf.params, - inferred: Present { value: Resolved { node: substitute_generics(n: field_node_type_expr(n: sf), subst: subst, source_indices: scope.type_env.source_indices) } }, + inferred: Present { value: Resolved { node: substitute_generics(n: field_substitution_carrier(sf: sf, source_indices: scope.type_env.source_indices), subst: subst, source_indices: scope.type_env.source_indices) } }, return_cardinality: sf.return_cardinality, uses: sf.uses, body: sf.body, transport: sf.transport, properties: sf.properties, type_annotation: sf.type_annotation, is_self_recursive: sf.is_self_recursive, diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index f1c63b96fd0..36c0c3e4b6f 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -1715,6 +1715,34 @@ pub fn record_lit_fields_from_expected( } } +pub fn field_type_expr_is_stripped_placeholder( + te: Rc, + source_indices: Rc>>, +) -> bool { + (((authored_name_at(source_indices.clone(), te.clone()) == "".to_string()) + && ((te.children.clone().len() as i64) == 0)) + && ((te.params.clone().len() as i64) == 0)) +} + +pub fn field_substitution_carrier( + sf: Rc, + source_indices: Rc>>, +) -> Rc { + { + let te = field_node_type_expr(sf.clone()); + if field_type_expr_is_stripped_placeholder(te.clone(), source_indices.clone()) { + match sf.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + preserve_outer_optional_cardinality(sf.clone(), rt.clone()) + } + _ => te.clone(), + } + } else { + te.clone() + } + } +} + pub fn record_lit_instantiated_fields( type_name: Option, expected: Option>, @@ -1762,7 +1790,14 @@ match exp.children.clone().iter().cloned().skip(pair.0.clone() as usize).next() inferred: Some(Rc::new( InferredNode::Resolved { node: substitute_generics( - field_node_type_expr(sf.clone()), + field_substitution_carrier( + sf.clone(), + scope + .type_env + .clone() + .source_indices + .clone(), + ), subst.clone(), scope .type_env