From 9b5f3d1cc7e1883f04299af26aacd4bb7ad490de Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 20:44:09 +0000 Subject: [PATCH 1/5] Add scratch strict-preparation profiling harness (measurement only) Runs the floor's prepare_repository_once alone so compile.reconcile's interior can be stack-sampled without the witness fold around it. Investigation harness for the reconcile cost attribution; to be removed or replaced by a modeled instrument after discussion. --- src/v1/stage0/examples/prep_profile.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/v1/stage0/examples/prep_profile.rs diff --git a/src/v1/stage0/examples/prep_profile.rs b/src/v1/stage0/examples/prep_profile.rs new file mode 100644 index 00000000000..a86f17bfe8a --- /dev/null +++ b/src/v1/stage0/examples/prep_profile.rs @@ -0,0 +1,18 @@ +// Scratch measurement harness (NOT for commit): runs the floor's strict +// preparation alone so reconcile's interior can be stack-sampled. +use v1_compiler::cli_run; + +fn main() { + let roots = vec!["dag".to_string(), "src/v2".to_string()]; + let t = std::time::Instant::now(); + let r = cli_run::prepare_repository_once(&roots, &cli_run::floor_prepared_subject_exclusions()); + match r { + Ok((prepared, _inv)) => eprintln!( + "prep ok in {:?}: modules_resolved={} excluded={}", + t.elapsed(), + prepared.modules_resolved, + prepared.modules_excluded + ), + Err(e) => eprintln!("prep refused in {:?}: {}", t.elapsed(), &e[..e.len().min(2000)]), + } +} From 6d746a81a8545c278712066bb6d6b6cddc5cdd8e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 22:47:59 +0000 Subject: [PATCH 2/5] reconcile: precompute per-env unit-variant index (WIP, mirror regen pending) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit collect_unit_variant_phantom_matches re-merged every parent's str_bindings and re-scanned every visible binding once per bare-variant reference — measured at ~66% of the whole-corpus compile.reconcile wall (92/148 gdb stack samples over strict preparation, 2026-08-28). TypeEnv now carries visible_str_bindings (the merged one-level visibility map, built once per env) and unit_variant_index (variant name -> per-binding contribution), maintained at every binding insert and rebuilt where an env's parent set is replaced; the phantom lookup is a map hit with the same exactly-one-else-refuse contract. Stage0 mirror regen + behavioral validation to follow before this is complete. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01XBEhjFZhdjJ1eyRdu15MNQ --- src/v1/04_env.dag | 142 +++++++++++++++++++++++++++++++++++++++++- src/v1/04_infer.dag | 91 ++++++++++++++++++--------- src/v1/04_resolve.dag | 71 +++++++-------------- src/v1/05_emit.dag | 2 +- 4 files changed, 225 insertions(+), 81 deletions(-) diff --git a/src/v1/04_env.dag b/src/v1/04_env.dag index eac4c75c6ac..1c051d3f28b 100644 --- a/src/v1/04_env.dag +++ b/src/v1/04_env.dag @@ -31,6 +31,8 @@ type TypeEnv { authored_import_names: Map symbol_index: SymbolIndex module_path: String + visible_str_bindings: Map + unit_variant_index: Map> } type TypeBinding { @@ -39,6 +41,137 @@ type TypeBinding { provenance: SubValueRelation } +// Precomputed phantom-variant relation over the env's VISIBLE bindings (locals shadowing +// direct parents, one level — the exact set collect_unit_variant_phantom_matches used to +// re-merge and re-scan per lookup; measured 2026-08-28 at ~66% of the whole-corpus +// compile.reconcile wall, 92 of 148 stack samples, before this index existed). +// visible_str_bindings is that merged map, built once per env and maintained on insert; +// unit_variant_index is its inversion: variant name -> (visible binding name -> that +// binding's unit variants with this name). Shadowing removal is by KEY (the contributing +// binding's name), never by count decrement, so a replaced binding's contribution cannot +// leave residue; a coproduct declaring the same unit-variant name twice keeps count > 1 and +// still refuses at lookup exactly as the scan's two appended matches did. +type UnitVariantContribution { + count: Int + variant: Node +} + +fn is_unit_variant_node(variant: Node) -> Bool { + (variant.children |> count) == 0 +} + +fn variant_lookup_structural(ty: Node) -> Node { + if ty.connective == NoConnective && ty.inferred != none { + match ty.inferred { + Present { value: Resolved { node: target } } => target + _ => ty + } + } else { ty } +} + +fn binding_unit_variant_contributions(binding: TypeBinding, source_indices: Map) -> Map { + let ty = variant_lookup_structural(ty: binding.resolved) + match ty.connective { + Disj => + fold(ty.children, init: empty_map(), f: (acc, v) => + if is_unit_variant_node(variant: v) { + let vname = authored_name_at(source_indices: source_indices, node: v) + match map_get(acc, vname) { + Present { value: prev } => map_insert(acc, vname, UnitVariantContribution { count: prev.count + 1, variant: prev.variant }) + Absent => map_insert(acc, vname, UnitVariantContribution { count: 1, variant: v }) + } + } else { acc } + ) + _ => empty_map() + } +} + +fn contributions_without_key(contribs: Map, key: String) -> Map { + fold(contribs |> map_keys, init: empty_map(), f: (acc, k) => + if k == key { acc } + else { + match map_get(contribs, k) { + Present { value: c } => map_insert(acc, k, c) + Absent => acc + } + } + ) +} + +fn unit_variant_index_remove_binding( + index: Map>, + binding: TypeBinding, + source_indices: Map +) -> Map> { + fold(binding_unit_variant_contributions(binding: binding, source_indices: source_indices) |> map_keys, init: index, f: (acc, vname) => + match map_get(acc, vname) { + Present { value: contribs } => map_insert(acc, vname, contributions_without_key(contribs: contribs, key: binding.name)) + Absent => acc + } + ) +} + +fn unit_variant_index_add_binding( + index: Map>, + binding: TypeBinding, + source_indices: Map +) -> Map> { + let contributions = binding_unit_variant_contributions(binding: binding, source_indices: source_indices) + fold(contributions |> map_keys, init: index, f: (acc, vname) => + match map_get(contributions, vname) { + Present { value: contribution } => + let contribs = match map_get(acc, vname) { + Present { value: existing } => existing + Absent => empty_map() + } + map_insert(acc, vname, map_insert(contribs, binding.name, contribution)) + Absent => acc + } + ) +} + +type VisibleBindingsUpdate { + visible_str_bindings: Map + unit_variant_index: Map> +} + +// The one write path: inserting a binding shadows whatever was visible under that name, so +// the shadowed binding's contribution leaves the index with it — exact under locals-over- +// parents precedence because visible_str_bindings IS the post-shadowing map. +fn visible_bindings_insert( + visible_str_bindings: Map, + unit_variant_index: Map>, + binding: TypeBinding, + source_indices: Map +) -> VisibleBindingsUpdate { + let cleared = match map_get(visible_str_bindings, binding.name) { + Present { value: shadowed } => unit_variant_index_remove_binding(index: unit_variant_index, binding: shadowed, source_indices: source_indices) + Absent => unit_variant_index + } + VisibleBindingsUpdate { + visible_str_bindings: map_insert(visible_str_bindings, binding.name, binding), + unit_variant_index: unit_variant_index_add_binding(index: cleared, binding: binding, source_indices: source_indices) + } +} + +fn build_visible_str_bindings(str_bindings: Map, parents: List) -> Map { + fold(parents, init: str_bindings, f: (acc, parent) => map_merge(parent.str_bindings, acc)) +} + +fn build_unit_variant_index(visible_str_bindings: Map, source_indices: Map) -> Map> { + fold(visible_str_bindings |> map_values, init: empty_map(), f: (acc, binding) => + unit_variant_index_add_binding(index: acc, binding: binding, source_indices: source_indices) + ) +} + +fn build_visible_bindings_update(str_bindings: Map, parents: List, source_indices: Map) -> VisibleBindingsUpdate { + let visible = build_visible_str_bindings(str_bindings: str_bindings, parents: parents) + VisibleBindingsUpdate { + visible_str_bindings: visible, + unit_variant_index: build_unit_variant_index(visible_str_bindings: visible, source_indices: source_indices) + } +} + data global_bare_fallback_invariant: String = "Corpus-wide bare-name census, resolved by ONE uniform containment walk (operator ruling 2026-07-18: global uniqueness is NOT a special tier — it is the shallowest level of the same walk; filepaths are irrelevant, the declared module path is the containment tree). SymbolIndex.global_bare is keyed on the bare declared name and built once by build_symbol_index_census over graph.modules before any module typechecks (order-independent). Tracking is decl-only via symbol_index_insert_decl / local_binding_for_item (type/fn/data names) plus corpus-globally-unique Disj variant aliases (unique across the WHOLE bare-name space: a variant whose name any type/fn/data decl claims stays qualified-only, never a global_bare candidate — else a type-vs-variant tie, e.g. actions.Job vs ExpressionContext.Job, refuses every far use of the TYPE); every homonym keeps its FULL candidate list (module_path + binding), never a candidate-free Ambiguous tombstone. Resolution (global_bare_lookup): a single candidate resolves from anywhere (the one-candidate degenerate case of the walk); multiple candidates resolve by nearest-ancestor containment under ImportScoped, while NamespaceOnlyY filters to the referencing module's containment chain and routes 0/1/many through module_path_owner_binding_decide. The production flip that removes the corpus fallback is downstream of reference-derived closure. lookup_binding_by_name consults global_bare only after str_bindings/ancestry_str_bindings/intern+bindings all miss. Variant arms additionally merge into per-module variant_locals via merge_global_bare_variant_locals (constructor_binding_authority — owner is the coproduct node)." data qualified_module_projection_invariant: String = "Grammar lane G1/G1b: container.member module projection in value/type/pattern and fn/data/let type-annotation positions resolves via symbol_index_lookup on the full qualified path (module projection), not value field-access — v2 resolve: TypeNode Conj QN spines; v1 typecheck: lookup_binding_by_name after global_bare; v1 patterns: lookup_variant_in_type routes dotted variant names through symbol_index_lookup. build_symbol_index_census materializes declared-module item paths plus module-unique Disj variant aliases (qualified path always; corpus-unique variants also enter global_bare — mirrors v2 symbol_index_fill_unique_variant_aliases); lookup_qualified_module_projection runs only when the reference carries a dot (fail-closed on miss — never widens to field-access semantics)." @@ -102,7 +235,9 @@ fn empty_type_env() -> TypeEnv { source_indices: empty_map(), intern_table: empty_intern_table(), source_visible_names: empty_map(), authored_import_names: empty_map(), - symbol_index: empty_symbol_index() + symbol_index: empty_symbol_index(), + visible_str_bindings: empty_map(), + unit_variant_index: empty_map() } } @@ -1071,6 +1206,7 @@ fn env_with_type_variable_bindings(env: TypeEnv, tp_names: List) -> Type resolved: Node { name: tp_name, span: kernel_span(name: tp_name), ident_span: Present { value: kernel_span(name: tp_name) }, children: [], connective: NoConnective, params: [], inferred: Present { value: TypeVariable { id: tp_name } }, return_cardinality: Required, uses: [], body: none, transport: none, properties: [], type_annotation: none, is_self_recursive: false, has_non_tail_self_call: false, match_pattern: none, expr_data: NoExprData }, provenance: SubValueUnknown } + let visible_update = visible_bindings_insert(visible_str_bindings: e.visible_str_bindings, unit_variant_index: e.unit_variant_index, binding: tp_binding, source_indices: e.source_indices) TypeEnv { module_path: e.module_path, bindings: map_insert(e.bindings, intern(table: e.intern_table, s: tp_name).id, tp_binding), str_bindings: map_insert(e.str_bindings, tp_name, tp_binding), @@ -1083,7 +1219,9 @@ fn env_with_type_variable_bindings(env: TypeEnv, tp_names: List) -> Type intern_table: e.intern_table, source_visible_names: map_insert(e.source_visible_names, tp_name, true), authored_import_names: e.authored_import_names, - symbol_index: e.symbol_index + symbol_index: e.symbol_index, + visible_str_bindings: visible_update.visible_str_bindings, + unit_variant_index: visible_update.unit_variant_index } ) } diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index 4342dcd3810..f62f52fcb2e 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -113,7 +113,9 @@ import v1.compiler.infer_env { env_with_type_variable_bindings, GlobalBareCandidate, node_with_inferred, node_with_children, ServiceCensusEntry, qualify_decl_reference_positions, lookup_binding_by_name, binding_declares_name, - listed_import_required_bare_call_blocked + listed_import_required_bare_call_blocked, + VisibleBindingsUpdate, visible_bindings_insert, build_visible_str_bindings, + build_unit_variant_index, build_visible_bindings_update, UnitVariantContribution } import std.node { compiler_inductive_fields, compiler_recursive_types } import std.content_hash { content_hash_atom, content_hash_tagged_structural, content_hash_combine_structural } @@ -9665,6 +9667,7 @@ fn type_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv { } } ) + let visible_update = build_visible_bindings_update(str_bindings: filtered_str, parents: parent_env.parents, source_indices: parent_env.source_indices) TypeEnv { module_path: module_path, bindings: filtered, str_bindings: filtered_str, @@ -9676,7 +9679,9 @@ fn type_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv { source_indices: parent_env.source_indices, intern_table: parent_env.intern_table, source_visible_names: parent_env.source_visible_names, authored_import_names: parent_env.authored_import_names, - symbol_index: parent_env.symbol_index + symbol_index: parent_env.symbol_index, + visible_str_bindings: visible_update.visible_str_bindings, + unit_variant_index: visible_update.unit_variant_index } } else { parent_env } } @@ -9685,6 +9690,7 @@ data interface_env_for_import_note: String = "Interface-grain scope parent (S2a fn interface_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv { let filtered = type_env_for_import(module_path: module_path, parent_env: parent_env) + let visible_update = build_visible_bindings_update(str_bindings: filtered.str_bindings, parents: [], source_indices: filtered.source_indices) TypeEnv { module_path: module_path, bindings: filtered.bindings, str_bindings: filtered.str_bindings, @@ -9696,7 +9702,9 @@ fn interface_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv source_indices: filtered.source_indices, intern_table: filtered.intern_table, source_visible_names: filtered.source_visible_names, authored_import_names: filtered.authored_import_names, - symbol_index: filtered.symbol_index + symbol_index: filtered.symbol_index, + visible_str_bindings: visible_update.visible_str_bindings, + unit_variant_index: visible_update.unit_variant_index } } @@ -9705,6 +9713,7 @@ data interface_summary_consumer_note: String = "S2a move 2 increment B (resolver data interface_signature_fingerprint_v0_note: 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." fn interface_env_surface(env: TypeEnv) -> TypeEnv { + let visible_update = build_visible_bindings_update(str_bindings: env.str_bindings, parents: [], source_indices: env.source_indices) TypeEnv { module_path: env.module_path, bindings: env.bindings, str_bindings: env.str_bindings, @@ -9716,7 +9725,9 @@ fn interface_env_surface(env: TypeEnv) -> TypeEnv { source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, - symbol_index: env.symbol_index + symbol_index: env.symbol_index, + visible_str_bindings: visible_update.visible_str_bindings, + unit_variant_index: visible_update.unit_variant_index } } @@ -10366,7 +10377,9 @@ fn census_fn_sig_env(census: SymbolIndex, module_path: String, tp_names: List let node_fields = inductive_fields_list_to_map(fields: compiler_inductive_fields) let kernel_recursive_types = map_keys(compiler_recursive_types) |> map(name => intern(table: intern_table, s: name).id) let kernel_recursive_type_set = fold(map_keys(compiler_recursive_types), init: empty_map(), f: (acc, name) => map_insert(acc, intern(table: intern_table, s: name).id, true)) - let kernel = TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: str_bindings_from_bindings(bindings: kernel_bindings), ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index() } + let kernel_str_bindings = str_bindings_from_bindings(bindings: kernel_bindings) + let kernel = TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: kernel_str_bindings, ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), visible_str_bindings: kernel_str_bindings, unit_variant_index: build_unit_variant_index(visible_str_bindings: kernel_str_bindings, source_indices: source_indices) } let module_name_str = authored_name_at(source_indices: source_indices, node: module.module) let import_parents = flat_map(module.resolved_imports, imp => @@ -10830,7 +10844,8 @@ fn build_type_env(module: ResolvedModule, parent_index: Map fold(imp.specific_names, init: acc, f: (x, n) => map_insert(x, n, true)) } ) - let unresolved_env = TypeEnv { module_path: module_name_str, bindings: all_local_bindings, str_bindings: local_str_bindings, ancestry_str_bindings: ancestry_str_bindings, parents: scope_parents, recursive_types: cycle_set, recursive_type_set: cross_type_set, inductive_fields: merged_inductive_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: source_visible_names, authored_import_names: authored_import_names, symbol_index: symbol_index } + let module_visible = build_visible_bindings_update(str_bindings: local_str_bindings, parents: scope_parents, source_indices: source_indices) + let unresolved_env = TypeEnv { module_path: module_name_str, bindings: all_local_bindings, str_bindings: local_str_bindings, ancestry_str_bindings: ancestry_str_bindings, parents: scope_parents, recursive_types: cycle_set, recursive_type_set: cross_type_set, inductive_fields: merged_inductive_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: source_visible_names, authored_import_names: authored_import_names, symbol_index: symbol_index, visible_str_bindings: module_visible.visible_str_bindings, unit_variant_index: module_visible.unit_variant_index } let resolved = resolve_env_bindings(env: unresolved_env, module_name: module_name_str, local_names: local_name_set, deps_map: all_deps_map) let resolved_env_out = resolved.env let resolved_diags = resolved.diagnostics @@ -10846,6 +10861,8 @@ fn build_type_env(module: ResolvedModule, parent_index: Map intern_table: intern_table, source_visible_names: source_visible_names, authored_import_names: authored_import_names, symbol_index: resolved_env_out.symbol_index, + visible_str_bindings: resolved_env_out.visible_str_bindings, + unit_variant_index: resolved_env_out.unit_variant_index, } let cache_str_bindings = map_merge(final_env.ancestry_str_bindings, final_env.str_bindings) let type_env_cache = TypeEnvCache { @@ -10876,7 +10893,8 @@ fn build_type_env_unresolved(module: ResolvedModule, parent_index: Map @@ -10945,7 +10963,8 @@ fn build_type_env_unresolved(module: ResolvedModule, parent_index: Map str_bindings: Map + visible_str_bindings: Map + unit_variant_index: Map> diagnostics: List } +fn bindings_accum_insert(acc: BindingsAccum, ident: Int, updated_binding: TypeBinding, source_indices: Map, result_diagnostics: List) -> BindingsAccum { + let visible_update = visible_bindings_insert(visible_str_bindings: acc.visible_str_bindings, unit_variant_index: acc.unit_variant_index, binding: updated_binding, source_indices: source_indices) + BindingsAccum { + bindings: map_insert(acc.bindings, ident, updated_binding), + str_bindings: map_insert(acc.str_bindings, updated_binding.name, updated_binding), + visible_str_bindings: visible_update.visible_str_bindings, + unit_variant_index: visible_update.unit_variant_index, + diagnostics: concat(acc.diagnostics, result_diagnostics) + } +} + fn resolve_env_bindings(env: TypeEnv, module_name: String, local_names: Map, deps_map: Map>) -> EnvResolveResult { let remaining = map( filter(env.bindings |> map_values, b => map_contains_key(local_names, intern(table: env.intern_table, s: b.name).id)), @@ -11644,7 +11676,7 @@ fn topo_resolve_types( ) if ready |> count == 0 { - let stuck_accum = fold(remaining, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, diagnostics: [] }, f: (acc, name) => + let stuck_accum = fold(remaining, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, visible_str_bindings: env.visible_str_bindings, unit_variant_index: env.unit_variant_index, diagnostics: [] }, f: (acc, name) => let ident = intern(table: env.intern_table, s: name).id match map_get(env.bindings, ident) { Present { value: binding } => @@ -11653,21 +11685,17 @@ fn topo_resolve_types( let resolved = preserve_nominal_brand_on_resolve( identity: pre, structural: result.resolved, brand_name: binding.name, source_indices: env.source_indices) let updated_binding = TypeBinding { name: name, resolved: resolved, provenance: SubValueUnknown } - BindingsAccum { - bindings: map_insert(acc.bindings, ident, updated_binding), - str_bindings: map_insert(acc.str_bindings, name, updated_binding), - diagnostics: concat(acc.diagnostics, result.diagnostics) - } + bindings_accum_insert(acc: acc, ident: ident, updated_binding: updated_binding, source_indices: env.source_indices, result_diagnostics: result.diagnostics) Absent => acc } ) return EnvResolveResult { - env: TypeEnv { module_path: env.module_path, bindings: stuck_accum.bindings, str_bindings: stuck_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index }, + env: TypeEnv { module_path: env.module_path, bindings: stuck_accum.bindings, str_bindings: stuck_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, visible_str_bindings: stuck_accum.visible_str_bindings, unit_variant_index: stuck_accum.unit_variant_index }, diagnostics: concat(diagnostics, stuck_accum.diagnostics) } } - let ready_accum = fold(ready, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, diagnostics: [] }, f: (acc, name) => + let ready_accum = fold(ready, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, visible_str_bindings: env.visible_str_bindings, unit_variant_index: env.unit_variant_index, diagnostics: [] }, f: (acc, name) => let ident = intern(table: env.intern_table, s: name).id match map_get(env.bindings, ident) { Present { value: binding } => @@ -11676,11 +11704,7 @@ fn topo_resolve_types( let resolved = preserve_nominal_brand_on_resolve( identity: pre, structural: result.resolved, brand_name: binding.name, source_indices: env.source_indices) let updated_binding = TypeBinding { name: name, resolved: resolved, provenance: SubValueUnknown } - BindingsAccum { - bindings: map_insert(acc.bindings, ident, updated_binding), - str_bindings: map_insert(acc.str_bindings, name, updated_binding), - diagnostics: concat(acc.diagnostics, result.diagnostics) - } + bindings_accum_insert(acc: acc, ident: ident, updated_binding: updated_binding, source_indices: env.source_indices, result_diagnostics: result.diagnostics) Absent => acc } ) @@ -11690,7 +11714,7 @@ fn topo_resolve_types( topo_resolve_types( remaining: next_remaining, - env: TypeEnv { module_path: env.module_path, bindings: ready_accum.bindings, str_bindings: ready_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index }, + env: TypeEnv { module_path: env.module_path, bindings: ready_accum.bindings, str_bindings: ready_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, visible_str_bindings: ready_accum.visible_str_bindings, unit_variant_index: ready_accum.unit_variant_index }, module_name: module_name, diagnostics: concat(diagnostics, ready_accum.diagnostics), local_names: local_names, @@ -12098,10 +12122,14 @@ fn rewire_type_env_import_str_binding_identity(modules: List, sourc local_names: local_names, inherited_keys: inherited_keys ) + let str_binding_overlay = rewire_str_binding_overlay(str_bindings: m.type_env.str_bindings, rewrites: rewrites) let rewired = StrBindingsRewireAccum { - str_bindings: map_merge(m.type_env.str_bindings, rewire_str_binding_overlay(str_bindings: m.type_env.str_bindings, rewrites: rewrites)), + str_bindings: map_merge(m.type_env.str_bindings, str_binding_overlay), ancestry_str_bindings: map_merge(m.type_env.ancestry_str_bindings, rewrites) } + let rewired_visible = fold(str_binding_overlay |> map_values, init: VisibleBindingsUpdate { visible_str_bindings: m.type_env.visible_str_bindings, unit_variant_index: m.type_env.unit_variant_index }, f: (acc, binding) => + visible_bindings_insert(visible_str_bindings: acc.visible_str_bindings, unit_variant_index: acc.unit_variant_index, binding: binding, source_indices: source_indices) + ) TypedModule { progress: m.progress, module: m.module, @@ -12117,7 +12145,9 @@ fn rewire_type_env_import_str_binding_identity(modules: List, sourc source_indices: m.type_env.source_indices, intern_table: m.type_env.intern_table, source_visible_names: m.type_env.source_visible_names, authored_import_names: m.type_env.authored_import_names, - symbol_index: m.type_env.symbol_index + symbol_index: m.type_env.symbol_index, + visible_str_bindings: rewired_visible.visible_str_bindings, + unit_variant_index: rewired_visible.unit_variant_index }, type_env_cache: m.type_env_cache, interface: m.interface, @@ -12152,7 +12182,8 @@ fn compiler_kernel_type_env(source_indices: Map, intern_ta let node_fields = inductive_fields_list_to_map(fields: compiler_inductive_fields) let kernel_recursive_types = map_keys(compiler_recursive_types) |> map(name => intern(table: intern_table, s: name).id) let kernel_recursive_type_set = fold(map_keys(compiler_recursive_types), init: empty_map(), f: (acc, name) => map_insert(acc, intern(table: intern_table, s: name).id, true)) - TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: str_bindings_from_bindings(bindings: kernel_bindings), ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index() } + let kernel_str_bindings = str_bindings_from_bindings(bindings: kernel_bindings) + TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: kernel_str_bindings, ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), visible_str_bindings: kernel_str_bindings, unit_variant_index: build_unit_variant_index(visible_str_bindings: kernel_str_bindings, source_indices: source_indices) } } fn rewire_type_env_parent_links(modules: List, source_indices: Map) -> List { @@ -12180,6 +12211,8 @@ fn rewire_type_env_parent_links(modules: List, source_indices: Map< Absent => [] } ) + let rewired_parents = concat(import_parents, [shared_kernel]) + let rewired_visible = build_visible_bindings_update(str_bindings: m.type_env.str_bindings, parents: rewired_parents, source_indices: m.type_env.source_indices) TypedModule { progress: m.progress, module: m.module, @@ -12188,14 +12221,16 @@ fn rewire_type_env_parent_links(modules: List, source_indices: Map< bindings: m.type_env.bindings, str_bindings: m.type_env.str_bindings, ancestry_str_bindings: m.type_env.ancestry_str_bindings, - parents: concat(import_parents, [shared_kernel]), + parents: rewired_parents, recursive_types: m.type_env.recursive_types, recursive_type_set: m.type_env.recursive_type_set, inductive_fields: m.type_env.inductive_fields, source_indices: m.type_env.source_indices, intern_table: m.type_env.intern_table, source_visible_names: m.type_env.source_visible_names, authored_import_names: m.type_env.authored_import_names, - symbol_index: m.type_env.symbol_index + symbol_index: m.type_env.symbol_index, + visible_str_bindings: rewired_visible.visible_str_bindings, + unit_variant_index: rewired_visible.unit_variant_index }, type_env_cache: m.type_env_cache, interface: m.interface, diff --git a/src/v1/04_resolve.dag b/src/v1/04_resolve.dag index 7287fa9bb38..aaf0a0e728f 100644 --- a/src/v1/04_resolve.dag +++ b/src/v1/04_resolve.dag @@ -46,59 +46,30 @@ import std.induction { SubValueUnknown } import v1.compiler.infer_env { TypeEnv, TypeBinding, lookup_type, lookup_type_by_name, lookup_type_for, is_recursive_type, is_recursive_type_by_name, is_recursive_type_for, authored_name, env_with_type_variable_bindings, bare_name_miss_diagnostic, - type_ref_measure_binding_authority -} - -fn is_unit_variant_node(variant: Node) -> Bool { - (variant.children |> count) == 0 -} - -fn unit_variant_in_coproduct(env: TypeEnv, ty: Node, variant_name: String) -> Node? { - match ty.connective { - Disj => - fold(ty.children, init: none, f: (acc, v) => - if acc != none { acc } - else if authored_name_at(source_indices: env.source_indices, node: v) == variant_name && is_unit_variant_node(variant: v) { - Present { value: v } - } else { none } - ) - _ => none - } -} - -fn structural_type_for_variant_lookup(env: TypeEnv, ty: Node) -> Node { - if ty.connective == NoConnective && ty.inferred != none { - match ty.inferred { - Present { value: Resolved { node: target } } => target - _ => ty - } - } else { ty } + type_ref_measure_binding_authority, + UnitVariantContribution } +// Phantom unit-variant resolution reads the env's precomputed unit_variant_index (built and +// maintained beside visible_str_bindings in v1.compiler.infer_env). The former shape re-merged +// every parent's str_bindings and re-scanned every visible binding PER LOOKUP — one call per +// bare-variant reference over an environment of thousands — measured 2026-08-28 at ~66% of the +// whole-corpus compile.reconcile wall (92 of 148 gdb stack samples over strict preparation). +// The contract is unchanged: exactly one visible unit variant with this name resolves; zero or +// several refuse. Duplicate variant names within one coproduct keep count > 1 and refuse, as +// the scan's multiple appended matches did. fn lookup_unit_variant_phantom_type(env: TypeEnv, variant_name: String) -> Node? { - let matches = collect_unit_variant_phantom_matches(env: env, variant_name: variant_name) - if matches |> count == 1 { - match matches |> first { - Present { value: variant } => Present { value: variant } - Absent => none - } - } else { none } -} - -fn collect_unit_variant_phantom_matches(env: TypeEnv, variant_name: String) -> List { - let direct_bindings = fold(env.parents, init: env.str_bindings, f: (acc, parent) => - map_merge(parent.str_bindings, acc) - ) - fold(direct_bindings |> map_values, init: [], f: (acc, binding) => - match unit_variant_in_coproduct( - env: env, - ty: structural_type_for_variant_lookup(env: env, ty: binding.resolved), - variant_name: variant_name - ) { - Present { value: variant } => concat(acc, [variant]) - Absent => acc - } - ) + match map_get(env.unit_variant_index, variant_name) { + Present { value: contribs } => + let total = fold(contribs |> map_values, init: 0, f: (acc, c) => acc + c.count) + if total == 1 { + match filter(contribs |> map_values, c => c.count == 1) |> first { + Present { value: single } => Present { value: single.variant } + Absent => none + } + } else { none } + Absent => none + } } fn is_width_nat_type_literal(n: Node) -> Bool { diff --git a/src/v1/05_emit.dag b/src/v1/05_emit.dag index 74743d64093..503455f88c1 100644 --- a/src/v1/05_emit.dag +++ b/src/v1/05_emit.dag @@ -255,7 +255,7 @@ fn emit_simple_string_interp(parts: List, target: RenderTarget, sour fn empty_emit_scope() -> InferScope { InferScope { - type_env: TypeEnv { module_path: "", bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: empty_map(), intern_table: empty_intern_table(), source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index() }, + type_env: TypeEnv { module_path: "", bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: empty_map(), intern_table: empty_intern_table(), source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), visible_str_bindings: empty_map(), unit_variant_index: empty_map() }, func_env: ResolvedFuncEnv { name: "", local: empty_map(), parents: [] }, locals: empty_map(), body_locals: empty_map(), From db42cbe4907f117f5483ab6bafe15a58944d5e8e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 23:01:01 +0000 Subject: [PATCH 3/5] stage0 mirror: regen for unit-variant index (v1_compiler_{emit,infer,infer_env,infer_resolve}) Emitted by claim_executor --required-regen from the .dag change in 6d746a8; v1_rt.rs left untouched (pre-existing committed-vs-emitted doc-pointer drift unrelated to this change). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01XBEhjFZhdjJ1eyRdu15MNQ --- src/v1/stage0/src/v1_compiler_emit.rs | 6 + src/v1/stage0/src/v1_compiler_infer.rs | 233 +++++++++++++---- src/v1/stage0/src/v1_compiler_infer_env.rs | 240 ++++++++++++++++++ .../stage0/src/v1_compiler_infer_resolve.rs | 104 ++------ 4 files changed, 447 insertions(+), 136 deletions(-) diff --git a/src/v1/stage0/src/v1_compiler_emit.rs b/src/v1/stage0/src/v1_compiler_emit.rs index 54efa15020c..985e2fcd9e7 100644 --- a/src/v1/stage0/src/v1_compiler_emit.rs +++ b/src/v1/stage0/src/v1_compiler_emit.rs @@ -44,6 +44,7 @@ pub use crate::v1_compiler_infer::InferScope; pub use crate::v1_compiler_infer::{build_params_scope, call_param_caller_labels, extend_scope}; pub use crate::v1_compiler_infer_emit_info::{EmitGraphInfo, TypeSummary}; use crate::v1_compiler_infer_env::GlobalBareLookupState::*; +pub use crate::v1_compiler_infer_env::UnitVariantContribution; pub use crate::v1_compiler_infer_env::{authored_name, empty_symbol_index}; pub use crate::v1_compiler_infer_env::{GlobalBareLookupState, TypeBinding, TypeEnv}; pub use crate::v1_compiler_infer_items::{ItemInfo, ResolvedGraph, TypedModule}; @@ -587,6 +588,11 @@ pub fn empty_emit_scope() -> Rc { source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), + visible_str_bindings: v1_rt::rc_empty_map::>(), + unit_variant_index: v1_rt::rc_empty_map::< + String, + Rc>>, + >(), }), func_env: Rc::new(ResolvedFuncEnv { name: "".to_string(), diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index 27146525ca9..866666c9aab 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -74,8 +74,9 @@ 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, + bare_name_miss_diagnostic, binding_declares_name, build_unit_variant_index, + build_visible_bindings_update, build_visible_str_bindings, 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, @@ -83,11 +84,12 @@ pub use crate::v1_compiler_infer_env::{ 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, + symbol_index_insert_service, symbol_index_lookup, visible_bindings_insert, }; pub use crate::v1_compiler_infer_env::{ GlobalBareCandidate, GlobalBareLookupState, GuardedTypeEnvCacheMerge, ServiceCensusEntry, SymbolIndex, TypeBinding, TypeEnv, TypeEnvCache, TypeEnvCacheMergeConflict, + UnitVariantContribution, VisibleBindingsUpdate, }; use crate::v1_compiler_infer_items::ItemKind::{ DataItem, FnItem, FuncItem, OtherItem, ServiceItem, TypeItem, @@ -17985,6 +17987,11 @@ pub fn type_env_for_import(module_path: String, parent_env: Rc) -> Rc) -> Rc String { 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()); + let visible_update = crate::v1_compiler_infer_env::build_visible_bindings_update( + filtered.str_bindings.clone(), + Rc::new(vec![]), + filtered.source_indices.clone(), + ); Rc::new(TypeEnv { module_path: module_path.clone(), bindings: filtered.bindings.clone(), @@ -18032,6 +18046,8 @@ pub fn interface_env_for_import(module_path: String, parent_env: Rc) -> source_visible_names: filtered.source_visible_names.clone(), authored_import_names: filtered.authored_import_names.clone(), symbol_index: filtered.symbol_index.clone(), + visible_str_bindings: visible_update.visible_str_bindings.clone(), + unit_variant_index: visible_update.unit_variant_index.clone(), }) } } @@ -18055,21 +18071,30 @@ pub fn interface_signature_fingerprint_v0_note() -> String { } 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(), - authored_import_names: env.authored_import_names.clone(), - symbol_index: env.symbol_index.clone(), - }) + { + let visible_update = crate::v1_compiler_infer_env::build_visible_bindings_update( + env.str_bindings.clone(), + Rc::new(vec![]), + env.source_indices.clone(), + ); + 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(), + authored_import_names: env.authored_import_names.clone(), + symbol_index: env.symbol_index.clone(), + visible_str_bindings: visible_update.visible_str_bindings.clone(), + unit_variant_index: visible_update.unit_variant_index.clone(), + }) + } } pub fn interface_cache_from_module(cache: Rc) -> Rc { @@ -19149,6 +19174,11 @@ pub fn census_fn_sig_env( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: census.clone(), + visible_str_bindings: v1_rt::rc_empty_map::>(), + unit_variant_index: v1_rt::rc_empty_map::< + String, + Rc>>, + >(), }); crate::v1_compiler_infer_env::env_with_type_variable_bindings( base.clone(), @@ -20205,12 +20235,12 @@ pub fn build_type_env( ) }, ); + let kernel_str_bindings = + crate::v1_compiler_infer_env::str_bindings_from_bindings(kernel_bindings.clone()); let kernel = Rc::new(TypeEnv { module_path: "".to_string(), bindings: kernel_bindings.clone(), - str_bindings: crate::v1_compiler_infer_env::str_bindings_from_bindings( - kernel_bindings.clone(), - ), + str_bindings: kernel_str_bindings.clone(), ancestry_str_bindings: v1_rt::rc_empty_map::>(), parents: Rc::new(vec![]), recursive_types: kernel_recursive_types.clone(), @@ -20221,6 +20251,11 @@ pub fn build_type_env( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), + visible_str_bindings: kernel_str_bindings.clone(), + unit_variant_index: crate::v1_compiler_infer_env::build_unit_variant_index( + kernel_str_bindings.clone(), + source_indices.clone(), + ), }); let module_name_str = crate::v1_std_core::authored_name_at(source_indices.clone(), module.module.clone()); @@ -20641,6 +20676,11 @@ pub fn build_type_env( } }, ); + let module_visible = crate::v1_compiler_infer_env::build_visible_bindings_update( + local_str_bindings.clone(), + scope_parents.clone(), + source_indices.clone(), + ); let unresolved_env = Rc::new(TypeEnv { module_path: module_name_str.clone(), bindings: all_local_bindings.clone(), @@ -20655,6 +20695,8 @@ pub fn build_type_env( source_visible_names: source_visible_names.clone(), authored_import_names: authored_import_names.clone(), symbol_index: symbol_index.clone(), + visible_str_bindings: module_visible.visible_str_bindings.clone(), + unit_variant_index: module_visible.unit_variant_index.clone(), }); let resolved = resolve_env_bindings( unresolved_env.clone(), @@ -20678,6 +20720,8 @@ pub fn build_type_env( source_visible_names: source_visible_names.clone(), authored_import_names: authored_import_names.clone(), symbol_index: resolved_env_out.symbol_index.clone(), + visible_str_bindings: resolved_env_out.visible_str_bindings.clone(), + unit_variant_index: resolved_env_out.unit_variant_index.clone(), }); let cache_str_bindings = v1_rt::rc_map_merge( final_env.ancestry_str_bindings.clone(), @@ -20852,12 +20896,12 @@ pub fn build_type_env_unresolved( provenance: Rc::new(SubValueRelation::SubValueUnknown), }), ); + let kernel_str_bindings = + crate::v1_compiler_infer_env::str_bindings_from_bindings(kernel_bindings.clone()); let kernel = Rc::new(TypeEnv { module_path: "".to_string(), bindings: kernel_bindings.clone(), - str_bindings: crate::v1_compiler_infer_env::str_bindings_from_bindings( - kernel_bindings.clone(), - ), + str_bindings: kernel_str_bindings.clone(), ancestry_str_bindings: v1_rt::rc_empty_map::>(), parents: Rc::new(vec![]), recursive_types: Rc::new(vec![]), @@ -20868,6 +20912,11 @@ pub fn build_type_env_unresolved( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), + visible_str_bindings: kernel_str_bindings.clone(), + unit_variant_index: crate::v1_compiler_infer_env::build_unit_variant_index( + kernel_str_bindings.clone(), + source_indices.clone(), + ), }); let module_name_str = crate::v1_std_core::authored_name_at(source_indices.clone(), module.module.clone()); @@ -21169,6 +21218,11 @@ pub fn build_type_env_unresolved( 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 module_visible = crate::v1_compiler_infer_env::build_visible_bindings_update( + local_str_bindings.clone(), + scope_parents.clone(), + source_indices.clone(), + ); let unresolved_env = Rc::new(TypeEnv { module_path: module_name_str.clone(), bindings: local_bindings.clone(), @@ -21183,6 +21237,8 @@ pub fn build_type_env_unresolved( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), + visible_str_bindings: module_visible.visible_str_bindings.clone(), + unit_variant_index: module_visible.unit_variant_index.clone(), }); let type_env_cache = Rc::new(TypeEnvCache { deps_map: all_deps_map.clone(), @@ -22441,9 +22497,43 @@ pub struct BindingResult { pub struct BindingsAccum { pub bindings: Rc>>, pub str_bindings: Rc>>, + pub visible_str_bindings: Rc>>, + pub unit_variant_index: Rc>>>>, pub diagnostics: Rc>>, } +pub fn bindings_accum_insert( + acc: Rc, + ident: i64, + updated_binding: Rc, + source_indices: Rc>>, + result_diagnostics: Rc>>, +) -> Rc { + { + let visible_update = crate::v1_compiler_infer_env::visible_bindings_insert( + acc.visible_str_bindings.clone(), + acc.unit_variant_index.clone(), + updated_binding.clone(), + source_indices.clone(), + ); + 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(), + updated_binding.name.clone(), + updated_binding.clone(), + ), + visible_str_bindings: visible_update.visible_str_bindings.clone(), + unit_variant_index: visible_update.unit_variant_index.clone(), + diagnostics: v1_rt::concat(acc.diagnostics.clone(), result_diagnostics.clone()), + }) + } +} + pub fn resolve_env_bindings( env: Rc, module_name: String, @@ -22545,6 +22635,8 @@ pub fn topo_resolve_types( let stuck_accum = remaining.iter().cloned().fold(Rc::new(BindingsAccum { bindings: env.bindings.clone(), str_bindings: env.str_bindings.clone(), + visible_str_bindings: env.visible_str_bindings.clone(), + unit_variant_index: env.unit_variant_index.clone(), diagnostics: Rc::new(vec![]), }), |acc: Rc, name: String| { let ident = crate::v1_std_core::intern(env.intern_table.clone(), name.clone()).id.clone(); @@ -22558,11 +22650,7 @@ let updated_binding = Rc::new(TypeBinding { 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()), -}) +bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.source_indices.clone(), result.diagnostics.clone()) }, None => acc.clone(), } @@ -22582,6 +22670,8 @@ Rc::new(BindingsAccum { source_visible_names: env.source_visible_names.clone(), authored_import_names: env.authored_import_names.clone(), symbol_index: env.symbol_index.clone(), + visible_str_bindings: stuck_accum.visible_str_bindings.clone(), + unit_variant_index: stuck_accum.unit_variant_index.clone(), }), diagnostics: v1_rt::concat( diagnostics.clone(), @@ -22594,6 +22684,8 @@ Rc::new(BindingsAccum { Rc::new(BindingsAccum { bindings: env.bindings.clone(), str_bindings: env.str_bindings.clone(), + visible_str_bindings: env.visible_str_bindings.clone(), + unit_variant_index: env.unit_variant_index.clone(), diagnostics: Rc::new(vec![]), }), |acc: Rc, name: String| { @@ -22620,22 +22712,13 @@ Rc::new(BindingsAccum { 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(), - ), - }) + bindings_accum_insert( + acc.clone(), + ident.clone(), + updated_binding.clone(), + env.source_indices.clone(), + result.diagnostics.clone(), + ) } None => acc.clone(), } @@ -22674,6 +22757,8 @@ Rc::new(BindingsAccum { source_visible_names: env.source_visible_names.clone(), authored_import_names: env.authored_import_names.clone(), symbol_index: env.symbol_index.clone(), + visible_str_bindings: ready_accum.visible_str_bindings.clone(), + unit_variant_index: ready_accum.unit_variant_index.clone(), }); let __tco_2 = v1_rt::concat(diagnostics, ready_accum.diagnostics.clone()); let __tco_3 = (fuel - 1); @@ -23458,19 +23543,41 @@ pub fn rewire_type_env_import_str_binding_identity( local_names.clone(), inherited_keys.clone(), ); + let str_binding_overlay = rewire_str_binding_overlay( + m.type_env.clone().str_bindings.clone(), + rewrites.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(), - ), + str_binding_overlay.clone(), ), ancestry_str_bindings: v1_rt::rc_map_merge( m.type_env.clone().ancestry_str_bindings.clone(), rewrites.clone(), ), }); + let rewired_visible = Rc::new(v1_rt::map_values(&str_binding_overlay)) + .iter() + .cloned() + .fold( + Rc::new(VisibleBindingsUpdate { + visible_str_bindings: m + .type_env + .clone() + .visible_str_bindings + .clone(), + unit_variant_index: m.type_env.clone().unit_variant_index.clone(), + }), + |acc: Rc, binding: Rc| { + crate::v1_compiler_infer_env::visible_bindings_insert( + acc.visible_str_bindings.clone(), + acc.unit_variant_index.clone(), + binding.clone(), + source_indices.clone(), + ) + }, + ); Rc::new(TypedModule { progress: m.progress.clone(), module: m.module.clone(), @@ -23489,6 +23596,8 @@ pub fn rewire_type_env_import_str_binding_identity( source_visible_names: m.type_env.clone().source_visible_names.clone(), authored_import_names: m.type_env.clone().authored_import_names.clone(), symbol_index: m.type_env.clone().symbol_index.clone(), + visible_str_bindings: rewired_visible.visible_str_bindings.clone(), + unit_variant_index: rewired_visible.unit_variant_index.clone(), }), type_env_cache: m.type_env_cache.clone(), interface: m.interface.clone(), @@ -23701,12 +23810,12 @@ pub fn compiler_kernel_type_env( ) }, ); + let kernel_str_bindings = + crate::v1_compiler_infer_env::str_bindings_from_bindings(kernel_bindings.clone()); Rc::new(TypeEnv { module_path: "".to_string(), bindings: kernel_bindings.clone(), - str_bindings: crate::v1_compiler_infer_env::str_bindings_from_bindings( - kernel_bindings.clone(), - ), + str_bindings: kernel_str_bindings.clone(), ancestry_str_bindings: v1_rt::rc_empty_map::>(), parents: Rc::new(vec![]), recursive_types: kernel_recursive_types.clone(), @@ -23717,6 +23826,11 @@ pub fn compiler_kernel_type_env( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), + visible_str_bindings: kernel_str_bindings.clone(), + unit_variant_index: crate::v1_compiler_infer_env::build_unit_variant_index( + kernel_str_bindings.clone(), + source_indices.clone(), + ), }) } } @@ -23799,6 +23913,14 @@ pub fn rewire_type_env_parent_links( } __result }); + let rewired_parents = + v1_rt::concat(import_parents.clone(), Rc::new(vec![shared_kernel.clone()])); + let rewired_visible = + crate::v1_compiler_infer_env::build_visible_bindings_update( + m.type_env.clone().str_bindings.clone(), + rewired_parents.clone(), + m.type_env.clone().source_indices.clone(), + ); Rc::new(TypedModule { progress: m.progress.clone(), module: m.module.clone(), @@ -23808,10 +23930,7 @@ pub fn rewire_type_env_parent_links( 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()]), - ), + parents: rewired_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(), @@ -23820,6 +23939,8 @@ pub fn rewire_type_env_parent_links( source_visible_names: m.type_env.clone().source_visible_names.clone(), authored_import_names: m.type_env.clone().authored_import_names.clone(), symbol_index: m.type_env.clone().symbol_index.clone(), + visible_str_bindings: rewired_visible.visible_str_bindings.clone(), + unit_variant_index: rewired_visible.unit_variant_index.clone(), }), type_env_cache: m.type_env_cache.clone(), interface: m.interface.clone(), diff --git a/src/v1/stage0/src/v1_compiler_infer_env.rs b/src/v1/stage0/src/v1_compiler_infer_env.rs index dfbe3344020..74dfff6a4ce 100644 --- a/src/v1/stage0/src/v1_compiler_infer_env.rs +++ b/src/v1/stage0/src/v1_compiler_infer_env.rs @@ -59,6 +59,8 @@ pub struct TypeEnv { pub authored_import_names: Rc>, pub symbol_index: Rc, pub module_path: String, + pub visible_str_bindings: Rc>>, + pub unit_variant_index: Rc>>>>, } #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] @@ -68,6 +70,231 @@ pub struct TypeBinding { pub provenance: Rc, } +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UnitVariantContribution { + pub count: i64, + pub variant: Rc, +} + +pub fn is_unit_variant_node(variant: Rc) -> bool { + ((variant.children.clone().len() as i64) == 0) +} + +pub fn variant_lookup_structural(ty: Rc) -> Rc { + if ((ty.connective.clone() == Connective::NoConnective) && (ty.inferred.clone() != None)) { + match ty.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: target, .. }) => target.clone(), + _ => ty, + } + } else { + ty + } +} + +pub fn binding_unit_variant_contributions( + binding: Rc, + source_indices: Rc>>, +) -> Rc>> { + { + let ty = variant_lookup_structural(binding.resolved.clone()); + match ty.connective.clone() { + Connective::Disj => ty.children.clone().iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, v: Rc| { + if is_unit_variant_node(v.clone()) { + { + let vname = crate::v1_std_core::authored_name_at( + source_indices.clone(), + v.clone(), + ); + match v1_rt::map_get(&acc, vname.clone()) { + Some(prev) => v1_rt::rc_map_insert( + acc.clone(), + vname.clone(), + Rc::new(UnitVariantContribution { + count: (prev.count.clone() + 1), + variant: prev.variant.clone(), + }), + ), + None => v1_rt::rc_map_insert( + acc.clone(), + vname.clone(), + Rc::new(UnitVariantContribution { + count: 1, + variant: v.clone(), + }), + ), + } + } + } else { + acc.clone() + } + }, + ), + _ => v1_rt::rc_empty_map::>(), + } + } +} + +pub fn contributions_without_key( + contribs: Rc>>, + key: String, +) -> Rc>> { + Rc::new(v1_rt::map_keys(&contribs)).iter().cloned().fold( + v1_rt::rc_empty_map::>(), + |acc: Rc>>, k: String| { + if (k.clone() == key.clone()) { + acc.clone() + } else { + match v1_rt::map_get(&contribs, k.clone()) { + Some(c) => v1_rt::rc_map_insert(acc.clone(), k.clone(), c.clone()), + None => acc.clone(), + } + } + }, + ) +} + +pub fn unit_variant_index_remove_binding( + index: Rc>>>>, + binding: Rc, + source_indices: Rc>>, +) -> Rc>>>> { + Rc::new(v1_rt::map_keys(&binding_unit_variant_contributions( + binding.clone(), + source_indices.clone(), + ))) + .iter() + .cloned() + .fold( + index.clone(), + |acc: Rc>>>>, + vname: String| match v1_rt::map_get(&acc, vname.clone()) { + Some(contribs) => v1_rt::rc_map_insert( + acc.clone(), + vname.clone(), + contributions_without_key(contribs.clone(), binding.name.clone()), + ), + None => acc.clone(), + }, + ) +} + +pub fn unit_variant_index_add_binding( + index: Rc>>>>, + binding: Rc, + source_indices: Rc>>, +) -> Rc>>>> { + { + let contributions = + binding_unit_variant_contributions(binding.clone(), source_indices.clone()); + Rc::new(v1_rt::map_keys(&contributions)) + .iter() + .cloned() + .fold( + index.clone(), + |acc: Rc>>>>, + vname: String| match v1_rt::map_get(&contributions, vname.clone()) + { + Some(contribution) => { + let contribs = match v1_rt::map_get(&acc, vname.clone()) { + Some(existing) => existing.clone(), + None => v1_rt::rc_empty_map::>(), + }; + v1_rt::rc_map_insert( + acc.clone(), + vname.clone(), + v1_rt::rc_map_insert( + contribs.clone(), + binding.name.clone(), + contribution.clone(), + ), + ) + } + None => acc.clone(), + }, + ) + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct VisibleBindingsUpdate { + pub visible_str_bindings: Rc>>, + pub unit_variant_index: Rc>>>>, +} + +pub fn visible_bindings_insert( + visible_str_bindings: Rc>>, + unit_variant_index: Rc>>>>, + binding: Rc, + source_indices: Rc>>, +) -> Rc { + { + let cleared = match v1_rt::map_get(&visible_str_bindings, binding.name.clone()) { + Some(shadowed) => unit_variant_index_remove_binding( + unit_variant_index.clone(), + shadowed.clone(), + source_indices.clone(), + ), + None => unit_variant_index.clone(), + }; + Rc::new(VisibleBindingsUpdate { + visible_str_bindings: v1_rt::rc_map_insert( + visible_str_bindings.clone(), + binding.name.clone(), + binding.clone(), + ), + unit_variant_index: unit_variant_index_add_binding( + cleared.clone(), + binding.clone(), + source_indices.clone(), + ), + }) + } +} + +pub fn build_visible_str_bindings( + str_bindings: Rc>>, + parents: Rc>>, +) -> Rc>> { + parents.iter().cloned().fold( + str_bindings.clone(), + |acc: Rc>>, parent: Rc| { + v1_rt::rc_map_merge(parent.str_bindings.clone(), acc) + }, + ) +} + +pub fn build_unit_variant_index( + visible_str_bindings: Rc>>, + source_indices: Rc>>, +) -> Rc>>>> { + Rc::new(v1_rt::map_values(&visible_str_bindings)) + .iter() + .cloned() + .fold( + v1_rt::rc_empty_map::>>>(), + |acc: Rc>>>>, + binding: Rc| { + unit_variant_index_add_binding(acc, binding.clone(), source_indices.clone()) + }, + ) +} + +pub fn build_visible_bindings_update( + str_bindings: Rc>>, + parents: Rc>>, + source_indices: Rc>>, +) -> Rc { + { + let visible = build_visible_str_bindings(str_bindings.clone(), parents.clone()); + Rc::new(VisibleBindingsUpdate { + visible_str_bindings: visible.clone(), + unit_variant_index: build_unit_variant_index(visible.clone(), source_indices.clone()), + }) + } +} + pub fn global_bare_fallback_invariant() -> String { thread_local! { static CACHED: String = { @@ -162,6 +389,11 @@ pub fn empty_type_env() -> Rc { source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: empty_symbol_index(), + visible_str_bindings: v1_rt::rc_empty_map::>(), + unit_variant_index: v1_rt::rc_empty_map::< + String, + Rc>>, + >(), }) } @@ -1960,6 +2192,12 @@ pub fn env_with_type_variable_bindings(env: Rc, tp_names: Rc, tp_names: Rc) -> bool { - ((variant.children.clone().len() as i64) == 0) -} - -pub fn unit_variant_in_coproduct( +pub fn lookup_unit_variant_phantom_type( env: Rc, - ty: Rc, variant_name: String, ) -> Option> { - match ty.connective.clone() { - Connective::Disj => { - ty.children - .clone() + match v1_rt::map_get(&env.unit_variant_index.clone(), variant_name.clone()) { + Some(contribs) => { + let total = Rc::new(v1_rt::map_values(&contribs)) .iter() .cloned() - .fold(None, |acc: _, v: Rc| { - if (acc.clone() != None) { - acc.clone() - } else { - if ((crate::v1_std_core::authored_name_at( - env.source_indices.clone(), - v.clone(), - ) == variant_name.clone()) - && is_unit_variant_node(v.clone())) - { - Some(v.clone()) - } else { - None + .fold(0, |acc: i64, c: Rc| { + (acc + c.count.clone()) + }); + if (total.clone() == 1) { + match Rc::new({ + let mut __result = Vec::new(); + for c in Rc::new(v1_rt::map_values(&contribs)).iter().cloned() { + if (c.count.clone() == 1) { + __result.push(c); } } + __result }) - } - _ => None, - } -} - -pub fn structural_type_for_variant_lookup(env: Rc, ty: Rc) -> Rc { - if ((ty.connective.clone() == Connective::NoConnective) && (ty.inferred.clone() != None)) { - match ty.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: target, .. }) => target.clone(), - _ => ty, - } - } else { - ty - } -} - -pub fn lookup_unit_variant_phantom_type( - env: Rc, - variant_name: String, -) -> Option> { - { - let matches = collect_unit_variant_phantom_matches(env.clone(), variant_name.clone()); - if ((matches.clone().len() as i64) == 1) { - match matches.clone().first().cloned() { - Some(variant) => Some(variant.clone()), - None => None, + .first() + .cloned() + { + Some(single) => Some(single.variant.clone()), + None => None, + } + } else { + None } - } else { - None } - } -} - -pub fn collect_unit_variant_phantom_matches( - env: Rc, - variant_name: String, -) -> Rc>> { - { - let direct_bindings = env.parents.clone().iter().cloned().fold( - env.str_bindings.clone(), - |acc: Rc>>, parent: Rc| { - v1_rt::rc_map_merge(parent.str_bindings.clone(), acc) - }, - ); - Rc::new(v1_rt::map_values(&direct_bindings)) - .iter() - .cloned() - .fold( - Rc::new(vec![]), - |acc: Rc>>, binding: Rc| match unit_variant_in_coproduct( - env.clone(), - structural_type_for_variant_lookup(env.clone(), binding.resolved.clone()), - variant_name.clone(), - ) { - Some(variant) => v1_rt::concat(acc.clone(), Rc::new(vec![variant.clone()])), - None => acc.clone(), - }, - ) + None => None, } } From d8f5d14d36315fd96df5db7dbde0a017e32bf879 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 23:41:46 +0000 Subject: [PATCH 4/5] reconcile index: drop retained visible map, keep index only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first cut stored the merged visibility map on every env; ~4k retained merged maps moved the strict-preparation OOM earlier instead of later (measured: both runs die at the 13.6GB cgroup cap, the indexed one at ~8.5min vs ~17.5min — compute fixed, residency regressed). The index alone is small; the shadowed binding an insert displaces is recovered by an ordered lookup (effective_visible_binding) instead of a stored map, and the merged map is now transient inside build_unit_variant_index. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01XBEhjFZhdjJ1eyRdu15MNQ --- src/v1/04_env.dag | 73 +++++++++++++++++++++------------------------ src/v1/04_infer.dag | 72 +++++++++++++++++++++----------------------- src/v1/05_emit.dag | 2 +- 3 files changed, 69 insertions(+), 78 deletions(-) diff --git a/src/v1/04_env.dag b/src/v1/04_env.dag index 1c051d3f28b..fd01f5a84dd 100644 --- a/src/v1/04_env.dag +++ b/src/v1/04_env.dag @@ -31,7 +31,6 @@ type TypeEnv { authored_import_names: Map symbol_index: SymbolIndex module_path: String - visible_str_bindings: Map unit_variant_index: Map> } @@ -45,12 +44,16 @@ type TypeBinding { // direct parents, one level — the exact set collect_unit_variant_phantom_matches used to // re-merge and re-scan per lookup; measured 2026-08-28 at ~66% of the whole-corpus // compile.reconcile wall, 92 of 148 stack samples, before this index existed). -// visible_str_bindings is that merged map, built once per env and maintained on insert; -// unit_variant_index is its inversion: variant name -> (visible binding name -> that -// binding's unit variants with this name). Shadowing removal is by KEY (the contributing -// binding's name), never by count decrement, so a replaced binding's contribution cannot -// leave residue; a coproduct declaring the same unit-variant name twice keeps count > 1 and -// still refuses at lookup exactly as the scan's two appended matches did. +// unit_variant_index inverts that visible set: variant name -> (visible binding name -> +// that binding's unit variants with this name). The merged visibility map itself is +// TRANSIENT — built inside build_unit_variant_index and dropped — never stored on the env: +// a first cut retained it per env and the ~4k retained merged maps moved the OOM earlier +// instead of later. Shadowing removal is by KEY (the contributing binding's name), never by +// count decrement, so a replaced binding's contribution cannot leave residue; the shadowed +// binding an insert displaces is recovered by effective_visible_binding's ordered lookup +// (locals first, then parents in order — the same precedence the merge implemented). +// A coproduct declaring the same unit-variant name twice keeps count > 1 and still refuses +// at lookup exactly as the scan's two appended matches did. type UnitVariantContribution { count: Int variant: Node @@ -130,48 +133,41 @@ fn unit_variant_index_add_binding( ) } -type VisibleBindingsUpdate { - visible_str_bindings: Map - unit_variant_index: Map> +// The shadowed binding an insert displaces, under the same precedence the per-call merge +// implemented: locals first, then parents in declaration order (first parent wins). +fn effective_visible_binding(str_bindings: Map, parents: List, name: String) -> TypeBinding? { + match map_get(str_bindings, name) { + Present { value: b } => Present { value: b } + Absent => + fold(parents, init: none, f: (acc, parent) => + if acc != none { acc } + else { map_get(parent.str_bindings, name) } + ) + } } // The one write path: inserting a binding shadows whatever was visible under that name, so -// the shadowed binding's contribution leaves the index with it — exact under locals-over- -// parents precedence because visible_str_bindings IS the post-shadowing map. -fn visible_bindings_insert( - visible_str_bindings: Map, +// the shadowed binding's contribution leaves the index with it. +fn unit_variant_index_shadow_insert( unit_variant_index: Map>, + shadowed: TypeBinding?, binding: TypeBinding, source_indices: Map -) -> VisibleBindingsUpdate { - let cleared = match map_get(visible_str_bindings, binding.name) { - Present { value: shadowed } => unit_variant_index_remove_binding(index: unit_variant_index, binding: shadowed, source_indices: source_indices) +) -> Map> { + let cleared = match shadowed { + Present { value: old } => unit_variant_index_remove_binding(index: unit_variant_index, binding: old, source_indices: source_indices) Absent => unit_variant_index } - VisibleBindingsUpdate { - visible_str_bindings: map_insert(visible_str_bindings, binding.name, binding), - unit_variant_index: unit_variant_index_add_binding(index: cleared, binding: binding, source_indices: source_indices) - } + unit_variant_index_add_binding(index: cleared, binding: binding, source_indices: source_indices) } -fn build_visible_str_bindings(str_bindings: Map, parents: List) -> Map { - fold(parents, init: str_bindings, f: (acc, parent) => map_merge(parent.str_bindings, acc)) -} - -fn build_unit_variant_index(visible_str_bindings: Map, source_indices: Map) -> Map> { - fold(visible_str_bindings |> map_values, init: empty_map(), f: (acc, binding) => +fn build_unit_variant_index(str_bindings: Map, parents: List, source_indices: Map) -> Map> { + let visible = fold(parents, init: str_bindings, f: (acc, parent) => map_merge(parent.str_bindings, acc)) + fold(visible |> map_values, init: empty_map(), f: (acc, binding) => unit_variant_index_add_binding(index: acc, binding: binding, source_indices: source_indices) ) } -fn build_visible_bindings_update(str_bindings: Map, parents: List, source_indices: Map) -> VisibleBindingsUpdate { - let visible = build_visible_str_bindings(str_bindings: str_bindings, parents: parents) - VisibleBindingsUpdate { - visible_str_bindings: visible, - unit_variant_index: build_unit_variant_index(visible_str_bindings: visible, source_indices: source_indices) - } -} - data global_bare_fallback_invariant: String = "Corpus-wide bare-name census, resolved by ONE uniform containment walk (operator ruling 2026-07-18: global uniqueness is NOT a special tier — it is the shallowest level of the same walk; filepaths are irrelevant, the declared module path is the containment tree). SymbolIndex.global_bare is keyed on the bare declared name and built once by build_symbol_index_census over graph.modules before any module typechecks (order-independent). Tracking is decl-only via symbol_index_insert_decl / local_binding_for_item (type/fn/data names) plus corpus-globally-unique Disj variant aliases (unique across the WHOLE bare-name space: a variant whose name any type/fn/data decl claims stays qualified-only, never a global_bare candidate — else a type-vs-variant tie, e.g. actions.Job vs ExpressionContext.Job, refuses every far use of the TYPE); every homonym keeps its FULL candidate list (module_path + binding), never a candidate-free Ambiguous tombstone. Resolution (global_bare_lookup): a single candidate resolves from anywhere (the one-candidate degenerate case of the walk); multiple candidates resolve by nearest-ancestor containment under ImportScoped, while NamespaceOnlyY filters to the referencing module's containment chain and routes 0/1/many through module_path_owner_binding_decide. The production flip that removes the corpus fallback is downstream of reference-derived closure. lookup_binding_by_name consults global_bare only after str_bindings/ancestry_str_bindings/intern+bindings all miss. Variant arms additionally merge into per-module variant_locals via merge_global_bare_variant_locals (constructor_binding_authority — owner is the coproduct node)." data qualified_module_projection_invariant: String = "Grammar lane G1/G1b: container.member module projection in value/type/pattern and fn/data/let type-annotation positions resolves via symbol_index_lookup on the full qualified path (module projection), not value field-access — v2 resolve: TypeNode Conj QN spines; v1 typecheck: lookup_binding_by_name after global_bare; v1 patterns: lookup_variant_in_type routes dotted variant names through symbol_index_lookup. build_symbol_index_census materializes declared-module item paths plus module-unique Disj variant aliases (qualified path always; corpus-unique variants also enter global_bare — mirrors v2 symbol_index_fill_unique_variant_aliases); lookup_qualified_module_projection runs only when the reference carries a dot (fail-closed on miss — never widens to field-access semantics)." @@ -236,7 +232,6 @@ fn empty_type_env() -> TypeEnv { intern_table: empty_intern_table(), source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), - visible_str_bindings: empty_map(), unit_variant_index: empty_map() } } @@ -1206,7 +1201,8 @@ fn env_with_type_variable_bindings(env: TypeEnv, tp_names: List) -> Type resolved: Node { name: tp_name, span: kernel_span(name: tp_name), ident_span: Present { value: kernel_span(name: tp_name) }, children: [], connective: NoConnective, params: [], inferred: Present { value: TypeVariable { id: tp_name } }, return_cardinality: Required, uses: [], body: none, transport: none, properties: [], type_annotation: none, is_self_recursive: false, has_non_tail_self_call: false, match_pattern: none, expr_data: NoExprData }, provenance: SubValueUnknown } - let visible_update = visible_bindings_insert(visible_str_bindings: e.visible_str_bindings, unit_variant_index: e.unit_variant_index, binding: tp_binding, source_indices: e.source_indices) + let shadowed = effective_visible_binding(str_bindings: e.str_bindings, parents: e.parents, name: tp_name) + let updated_index = unit_variant_index_shadow_insert(unit_variant_index: e.unit_variant_index, shadowed: shadowed, binding: tp_binding, source_indices: e.source_indices) TypeEnv { module_path: e.module_path, bindings: map_insert(e.bindings, intern(table: e.intern_table, s: tp_name).id, tp_binding), str_bindings: map_insert(e.str_bindings, tp_name, tp_binding), @@ -1220,8 +1216,7 @@ fn env_with_type_variable_bindings(env: TypeEnv, tp_names: List) -> Type source_visible_names: map_insert(e.source_visible_names, tp_name, true), authored_import_names: e.authored_import_names, symbol_index: e.symbol_index, - visible_str_bindings: visible_update.visible_str_bindings, - unit_variant_index: visible_update.unit_variant_index + unit_variant_index: updated_index } ) } diff --git a/src/v1/04_infer.dag b/src/v1/04_infer.dag index f62f52fcb2e..7192676b58e 100644 --- a/src/v1/04_infer.dag +++ b/src/v1/04_infer.dag @@ -114,8 +114,8 @@ import v1.compiler.infer_env { ServiceCensusEntry, qualify_decl_reference_positions, lookup_binding_by_name, binding_declares_name, listed_import_required_bare_call_blocked, - VisibleBindingsUpdate, visible_bindings_insert, build_visible_str_bindings, - build_unit_variant_index, build_visible_bindings_update, UnitVariantContribution + effective_visible_binding, unit_variant_index_shadow_insert, + build_unit_variant_index, UnitVariantContribution } import std.node { compiler_inductive_fields, compiler_recursive_types } import std.content_hash { content_hash_atom, content_hash_tagged_structural, content_hash_combine_structural } @@ -9667,7 +9667,7 @@ fn type_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv { } } ) - let visible_update = build_visible_bindings_update(str_bindings: filtered_str, parents: parent_env.parents, source_indices: parent_env.source_indices) + let rebuilt_index = build_unit_variant_index(str_bindings: filtered_str, parents: parent_env.parents, source_indices: parent_env.source_indices) TypeEnv { module_path: module_path, bindings: filtered, str_bindings: filtered_str, @@ -9680,8 +9680,7 @@ fn type_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv { intern_table: parent_env.intern_table, source_visible_names: parent_env.source_visible_names, authored_import_names: parent_env.authored_import_names, symbol_index: parent_env.symbol_index, - visible_str_bindings: visible_update.visible_str_bindings, - unit_variant_index: visible_update.unit_variant_index + unit_variant_index: rebuilt_index } } else { parent_env } } @@ -9690,7 +9689,7 @@ data interface_env_for_import_note: String = "Interface-grain scope parent (S2a fn interface_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv { let filtered = type_env_for_import(module_path: module_path, parent_env: parent_env) - let visible_update = build_visible_bindings_update(str_bindings: filtered.str_bindings, parents: [], source_indices: filtered.source_indices) + let rebuilt_index = build_unit_variant_index(str_bindings: filtered.str_bindings, parents: [], source_indices: filtered.source_indices) TypeEnv { module_path: module_path, bindings: filtered.bindings, str_bindings: filtered.str_bindings, @@ -9703,8 +9702,7 @@ fn interface_env_for_import(module_path: String, parent_env: TypeEnv) -> TypeEnv intern_table: filtered.intern_table, source_visible_names: filtered.source_visible_names, authored_import_names: filtered.authored_import_names, symbol_index: filtered.symbol_index, - visible_str_bindings: visible_update.visible_str_bindings, - unit_variant_index: visible_update.unit_variant_index + unit_variant_index: rebuilt_index } } @@ -9713,7 +9711,7 @@ data interface_summary_consumer_note: String = "S2a move 2 increment B (resolver data interface_signature_fingerprint_v0_note: 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." fn interface_env_surface(env: TypeEnv) -> TypeEnv { - let visible_update = build_visible_bindings_update(str_bindings: env.str_bindings, parents: [], source_indices: env.source_indices) + let rebuilt_index = build_unit_variant_index(str_bindings: env.str_bindings, parents: [], source_indices: env.source_indices) TypeEnv { module_path: env.module_path, bindings: env.bindings, str_bindings: env.str_bindings, @@ -9726,8 +9724,7 @@ fn interface_env_surface(env: TypeEnv) -> TypeEnv { intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, - visible_str_bindings: visible_update.visible_str_bindings, - unit_variant_index: visible_update.unit_variant_index + unit_variant_index: rebuilt_index } } @@ -10378,7 +10375,6 @@ fn census_fn_sig_env(census: SymbolIndex, module_path: String, tp_names: List let kernel_recursive_types = map_keys(compiler_recursive_types) |> map(name => intern(table: intern_table, s: name).id) let kernel_recursive_type_set = fold(map_keys(compiler_recursive_types), init: empty_map(), f: (acc, name) => map_insert(acc, intern(table: intern_table, s: name).id, true)) let kernel_str_bindings = str_bindings_from_bindings(bindings: kernel_bindings) - let kernel = TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: kernel_str_bindings, ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), visible_str_bindings: kernel_str_bindings, unit_variant_index: build_unit_variant_index(visible_str_bindings: kernel_str_bindings, source_indices: source_indices) } + let kernel = TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: kernel_str_bindings, ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), unit_variant_index: build_unit_variant_index(str_bindings: kernel_str_bindings, parents: [], source_indices: source_indices) } let module_name_str = authored_name_at(source_indices: source_indices, node: module.module) let import_parents = flat_map(module.resolved_imports, imp => @@ -10844,8 +10840,8 @@ fn build_type_env(module: ResolvedModule, parent_index: Map fold(imp.specific_names, init: acc, f: (x, n) => map_insert(x, n, true)) } ) - let module_visible = build_visible_bindings_update(str_bindings: local_str_bindings, parents: scope_parents, source_indices: source_indices) - let unresolved_env = TypeEnv { module_path: module_name_str, bindings: all_local_bindings, str_bindings: local_str_bindings, ancestry_str_bindings: ancestry_str_bindings, parents: scope_parents, recursive_types: cycle_set, recursive_type_set: cross_type_set, inductive_fields: merged_inductive_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: source_visible_names, authored_import_names: authored_import_names, symbol_index: symbol_index, visible_str_bindings: module_visible.visible_str_bindings, unit_variant_index: module_visible.unit_variant_index } + let module_variant_index = build_unit_variant_index(str_bindings: local_str_bindings, parents: scope_parents, source_indices: source_indices) + let unresolved_env = TypeEnv { module_path: module_name_str, bindings: all_local_bindings, str_bindings: local_str_bindings, ancestry_str_bindings: ancestry_str_bindings, parents: scope_parents, recursive_types: cycle_set, recursive_type_set: cross_type_set, inductive_fields: merged_inductive_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: source_visible_names, authored_import_names: authored_import_names, symbol_index: symbol_index, unit_variant_index: module_variant_index } let resolved = resolve_env_bindings(env: unresolved_env, module_name: module_name_str, local_names: local_name_set, deps_map: all_deps_map) let resolved_env_out = resolved.env let resolved_diags = resolved.diagnostics @@ -10861,7 +10857,6 @@ fn build_type_env(module: ResolvedModule, parent_index: Map intern_table: intern_table, source_visible_names: source_visible_names, authored_import_names: authored_import_names, symbol_index: resolved_env_out.symbol_index, - visible_str_bindings: resolved_env_out.visible_str_bindings, unit_variant_index: resolved_env_out.unit_variant_index, } let cache_str_bindings = map_merge(final_env.ancestry_str_bindings, final_env.str_bindings) @@ -10894,7 +10889,7 @@ fn build_type_env_unresolved(module: ResolvedModule, parent_index: Map @@ -10963,8 +10958,8 @@ fn build_type_env_unresolved(module: ResolvedModule, parent_index: Map str_bindings: Map - visible_str_bindings: Map unit_variant_index: Map> diagnostics: List } -fn bindings_accum_insert(acc: BindingsAccum, ident: Int, updated_binding: TypeBinding, source_indices: Map, result_diagnostics: List) -> BindingsAccum { - let visible_update = visible_bindings_insert(visible_str_bindings: acc.visible_str_bindings, unit_variant_index: acc.unit_variant_index, binding: updated_binding, source_indices: source_indices) +fn bindings_accum_insert(acc: BindingsAccum, ident: Int, updated_binding: TypeBinding, parents: List, source_indices: Map, result_diagnostics: List) -> BindingsAccum { + let shadowed = effective_visible_binding(str_bindings: acc.str_bindings, parents: parents, name: updated_binding.name) BindingsAccum { bindings: map_insert(acc.bindings, ident, updated_binding), str_bindings: map_insert(acc.str_bindings, updated_binding.name, updated_binding), - visible_str_bindings: visible_update.visible_str_bindings, - unit_variant_index: visible_update.unit_variant_index, + unit_variant_index: unit_variant_index_shadow_insert(unit_variant_index: acc.unit_variant_index, shadowed: shadowed, binding: updated_binding, source_indices: source_indices), diagnostics: concat(acc.diagnostics, result_diagnostics) } } @@ -11676,7 +11669,7 @@ fn topo_resolve_types( ) if ready |> count == 0 { - let stuck_accum = fold(remaining, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, visible_str_bindings: env.visible_str_bindings, unit_variant_index: env.unit_variant_index, diagnostics: [] }, f: (acc, name) => + let stuck_accum = fold(remaining, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, unit_variant_index: env.unit_variant_index, diagnostics: [] }, f: (acc, name) => let ident = intern(table: env.intern_table, s: name).id match map_get(env.bindings, ident) { Present { value: binding } => @@ -11685,17 +11678,17 @@ fn topo_resolve_types( let resolved = preserve_nominal_brand_on_resolve( identity: pre, structural: result.resolved, brand_name: binding.name, source_indices: env.source_indices) let updated_binding = TypeBinding { name: name, resolved: resolved, provenance: SubValueUnknown } - bindings_accum_insert(acc: acc, ident: ident, updated_binding: updated_binding, source_indices: env.source_indices, result_diagnostics: result.diagnostics) + bindings_accum_insert(acc: acc, ident: ident, updated_binding: updated_binding, parents: env.parents, source_indices: env.source_indices, result_diagnostics: result.diagnostics) Absent => acc } ) return EnvResolveResult { - env: TypeEnv { module_path: env.module_path, bindings: stuck_accum.bindings, str_bindings: stuck_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, visible_str_bindings: stuck_accum.visible_str_bindings, unit_variant_index: stuck_accum.unit_variant_index }, + env: TypeEnv { module_path: env.module_path, bindings: stuck_accum.bindings, str_bindings: stuck_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, unit_variant_index: stuck_accum.unit_variant_index }, diagnostics: concat(diagnostics, stuck_accum.diagnostics) } } - let ready_accum = fold(ready, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, visible_str_bindings: env.visible_str_bindings, unit_variant_index: env.unit_variant_index, diagnostics: [] }, f: (acc, name) => + let ready_accum = fold(ready, init: BindingsAccum { bindings: env.bindings, str_bindings: env.str_bindings, unit_variant_index: env.unit_variant_index, diagnostics: [] }, f: (acc, name) => let ident = intern(table: env.intern_table, s: name).id match map_get(env.bindings, ident) { Present { value: binding } => @@ -11704,7 +11697,7 @@ fn topo_resolve_types( let resolved = preserve_nominal_brand_on_resolve( identity: pre, structural: result.resolved, brand_name: binding.name, source_indices: env.source_indices) let updated_binding = TypeBinding { name: name, resolved: resolved, provenance: SubValueUnknown } - bindings_accum_insert(acc: acc, ident: ident, updated_binding: updated_binding, source_indices: env.source_indices, result_diagnostics: result.diagnostics) + bindings_accum_insert(acc: acc, ident: ident, updated_binding: updated_binding, parents: env.parents, source_indices: env.source_indices, result_diagnostics: result.diagnostics) Absent => acc } ) @@ -11714,7 +11707,7 @@ fn topo_resolve_types( topo_resolve_types( remaining: next_remaining, - env: TypeEnv { module_path: env.module_path, bindings: ready_accum.bindings, str_bindings: ready_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, visible_str_bindings: ready_accum.visible_str_bindings, unit_variant_index: ready_accum.unit_variant_index }, + env: TypeEnv { module_path: env.module_path, bindings: ready_accum.bindings, str_bindings: ready_accum.str_bindings, ancestry_str_bindings: env.ancestry_str_bindings, parents: env.parents, recursive_types: env.recursive_types, recursive_type_set: env.recursive_type_set, inductive_fields: env.inductive_fields, source_indices: env.source_indices, intern_table: env.intern_table, source_visible_names: env.source_visible_names, authored_import_names: env.authored_import_names, symbol_index: env.symbol_index, unit_variant_index: ready_accum.unit_variant_index }, module_name: module_name, diagnostics: concat(diagnostics, ready_accum.diagnostics), local_names: local_names, @@ -12127,8 +12120,13 @@ fn rewire_type_env_import_str_binding_identity(modules: List, sourc str_bindings: map_merge(m.type_env.str_bindings, str_binding_overlay), ancestry_str_bindings: map_merge(m.type_env.ancestry_str_bindings, rewrites) } - let rewired_visible = fold(str_binding_overlay |> map_values, init: VisibleBindingsUpdate { visible_str_bindings: m.type_env.visible_str_bindings, unit_variant_index: m.type_env.unit_variant_index }, f: (acc, binding) => - visible_bindings_insert(visible_str_bindings: acc.visible_str_bindings, unit_variant_index: acc.unit_variant_index, binding: binding, source_indices: source_indices) + let rewired_index = fold(str_binding_overlay |> map_values, init: m.type_env.unit_variant_index, f: (acc, binding) => + unit_variant_index_shadow_insert( + unit_variant_index: acc, + shadowed: effective_visible_binding(str_bindings: m.type_env.str_bindings, parents: m.type_env.parents, name: binding.name), + binding: binding, + source_indices: source_indices + ) ) TypedModule { progress: m.progress, @@ -12146,8 +12144,7 @@ fn rewire_type_env_import_str_binding_identity(modules: List, sourc intern_table: m.type_env.intern_table, source_visible_names: m.type_env.source_visible_names, authored_import_names: m.type_env.authored_import_names, symbol_index: m.type_env.symbol_index, - visible_str_bindings: rewired_visible.visible_str_bindings, - unit_variant_index: rewired_visible.unit_variant_index + unit_variant_index: rewired_index }, type_env_cache: m.type_env_cache, interface: m.interface, @@ -12183,7 +12180,7 @@ fn compiler_kernel_type_env(source_indices: Map, intern_ta let kernel_recursive_types = map_keys(compiler_recursive_types) |> map(name => intern(table: intern_table, s: name).id) let kernel_recursive_type_set = fold(map_keys(compiler_recursive_types), init: empty_map(), f: (acc, name) => map_insert(acc, intern(table: intern_table, s: name).id, true)) let kernel_str_bindings = str_bindings_from_bindings(bindings: kernel_bindings) - TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: kernel_str_bindings, ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), visible_str_bindings: kernel_str_bindings, unit_variant_index: build_unit_variant_index(visible_str_bindings: kernel_str_bindings, source_indices: source_indices) } + TypeEnv { module_path: "", bindings: kernel_bindings, str_bindings: kernel_str_bindings, ancestry_str_bindings: empty_map(), parents: [], recursive_types: kernel_recursive_types, recursive_type_set: kernel_recursive_type_set, inductive_fields: node_fields, source_indices: source_indices, intern_table: intern_table, source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), unit_variant_index: build_unit_variant_index(str_bindings: kernel_str_bindings, parents: [], source_indices: source_indices) } } fn rewire_type_env_parent_links(modules: List, source_indices: Map) -> List { @@ -12212,7 +12209,7 @@ fn rewire_type_env_parent_links(modules: List, source_indices: Map< } ) let rewired_parents = concat(import_parents, [shared_kernel]) - let rewired_visible = build_visible_bindings_update(str_bindings: m.type_env.str_bindings, parents: rewired_parents, source_indices: m.type_env.source_indices) + let rewired_index = build_unit_variant_index(str_bindings: m.type_env.str_bindings, parents: rewired_parents, source_indices: m.type_env.source_indices) TypedModule { progress: m.progress, module: m.module, @@ -12229,8 +12226,7 @@ fn rewire_type_env_parent_links(modules: List, source_indices: Map< intern_table: m.type_env.intern_table, source_visible_names: m.type_env.source_visible_names, authored_import_names: m.type_env.authored_import_names, symbol_index: m.type_env.symbol_index, - visible_str_bindings: rewired_visible.visible_str_bindings, - unit_variant_index: rewired_visible.unit_variant_index + unit_variant_index: rewired_index }, type_env_cache: m.type_env_cache, interface: m.interface, diff --git a/src/v1/05_emit.dag b/src/v1/05_emit.dag index 503455f88c1..77d2b120396 100644 --- a/src/v1/05_emit.dag +++ b/src/v1/05_emit.dag @@ -255,7 +255,7 @@ fn emit_simple_string_interp(parts: List, target: RenderTarget, sour fn empty_emit_scope() -> InferScope { InferScope { - type_env: TypeEnv { module_path: "", bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: empty_map(), intern_table: empty_intern_table(), source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), visible_str_bindings: empty_map(), unit_variant_index: empty_map() }, + type_env: TypeEnv { module_path: "", bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: empty_map(), intern_table: empty_intern_table(), source_visible_names: empty_map(), authored_import_names: empty_map(), symbol_index: empty_symbol_index(), unit_variant_index: empty_map() }, func_env: ResolvedFuncEnv { name: "", local: empty_map(), parents: [] }, locals: empty_map(), body_locals: empty_map(), From 4d7e15528d74a26f29b67b740e05427d57c041d9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 23:52:53 +0000 Subject: [PATCH 5/5] stage0 mirror: regen for index-only revision Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01XBEhjFZhdjJ1eyRdu15MNQ --- src/v1/stage0/src/v1_compiler_emit.rs | 1 - src/v1/stage0/src/v1_compiler_infer.rs | 110 ++++++++++----------- src/v1/stage0/src/v1_compiler_infer_env.rs | 99 ++++++++----------- 3 files changed, 92 insertions(+), 118 deletions(-) diff --git a/src/v1/stage0/src/v1_compiler_emit.rs b/src/v1/stage0/src/v1_compiler_emit.rs index 985e2fcd9e7..1d80aec1b9f 100644 --- a/src/v1/stage0/src/v1_compiler_emit.rs +++ b/src/v1/stage0/src/v1_compiler_emit.rs @@ -588,7 +588,6 @@ pub fn empty_emit_scope() -> Rc { source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), - visible_str_bindings: v1_rt::rc_empty_map::>(), unit_variant_index: v1_rt::rc_empty_map::< String, Rc>>, diff --git a/src/v1/stage0/src/v1_compiler_infer.rs b/src/v1/stage0/src/v1_compiler_infer.rs index 866666c9aab..62ef28e0a8a 100644 --- a/src/v1/stage0/src/v1_compiler_infer.rs +++ b/src/v1/stage0/src/v1_compiler_infer.rs @@ -75,8 +75,8 @@ use crate::v1_compiler_infer_env::GlobalBareLookupState::{ }; pub use crate::v1_compiler_infer_env::{ bare_name_miss_diagnostic, binding_declares_name, build_unit_variant_index, - build_visible_bindings_update, build_visible_str_bindings, empty_symbol_index, - empty_type_env_cache, env_with_type_variable_bindings, global_bare_is_ambiguous, + effective_visible_binding, 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, @@ -84,12 +84,12 @@ pub use crate::v1_compiler_infer_env::{ 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, visible_bindings_insert, + symbol_index_insert_service, symbol_index_lookup, unit_variant_index_shadow_insert, }; pub use crate::v1_compiler_infer_env::{ GlobalBareCandidate, GlobalBareLookupState, GuardedTypeEnvCacheMerge, ServiceCensusEntry, SymbolIndex, TypeBinding, TypeEnv, TypeEnvCache, TypeEnvCacheMergeConflict, - UnitVariantContribution, VisibleBindingsUpdate, + UnitVariantContribution, }; use crate::v1_compiler_infer_items::ItemKind::{ DataItem, FnItem, FuncItem, OtherItem, ServiceItem, TypeItem, @@ -17987,7 +17987,7 @@ pub fn type_env_for_import(module_path: String, parent_env: Rc) -> Rc) -> Rc String { 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()); - let visible_update = crate::v1_compiler_infer_env::build_visible_bindings_update( + let rebuilt_index = crate::v1_compiler_infer_env::build_unit_variant_index( filtered.str_bindings.clone(), Rc::new(vec![]), filtered.source_indices.clone(), @@ -18046,8 +18045,7 @@ pub fn interface_env_for_import(module_path: String, parent_env: Rc) -> source_visible_names: filtered.source_visible_names.clone(), authored_import_names: filtered.authored_import_names.clone(), symbol_index: filtered.symbol_index.clone(), - visible_str_bindings: visible_update.visible_str_bindings.clone(), - unit_variant_index: visible_update.unit_variant_index.clone(), + unit_variant_index: rebuilt_index.clone(), }) } } @@ -18072,7 +18070,7 @@ pub fn interface_signature_fingerprint_v0_note() -> String { pub fn interface_env_surface(env: Rc) -> Rc { { - let visible_update = crate::v1_compiler_infer_env::build_visible_bindings_update( + let rebuilt_index = crate::v1_compiler_infer_env::build_unit_variant_index( env.str_bindings.clone(), Rc::new(vec![]), env.source_indices.clone(), @@ -18091,8 +18089,7 @@ pub fn interface_env_surface(env: Rc) -> Rc { source_visible_names: env.source_visible_names.clone(), authored_import_names: env.authored_import_names.clone(), symbol_index: env.symbol_index.clone(), - visible_str_bindings: visible_update.visible_str_bindings.clone(), - unit_variant_index: visible_update.unit_variant_index.clone(), + unit_variant_index: rebuilt_index.clone(), }) } } @@ -19174,7 +19171,6 @@ pub fn census_fn_sig_env( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: census.clone(), - visible_str_bindings: v1_rt::rc_empty_map::>(), unit_variant_index: v1_rt::rc_empty_map::< String, Rc>>, @@ -20251,9 +20247,9 @@ pub fn build_type_env( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), - visible_str_bindings: kernel_str_bindings.clone(), unit_variant_index: crate::v1_compiler_infer_env::build_unit_variant_index( kernel_str_bindings.clone(), + Rc::new(vec![]), source_indices.clone(), ), }); @@ -20676,7 +20672,7 @@ pub fn build_type_env( } }, ); - let module_visible = crate::v1_compiler_infer_env::build_visible_bindings_update( + let module_variant_index = crate::v1_compiler_infer_env::build_unit_variant_index( local_str_bindings.clone(), scope_parents.clone(), source_indices.clone(), @@ -20695,8 +20691,7 @@ pub fn build_type_env( source_visible_names: source_visible_names.clone(), authored_import_names: authored_import_names.clone(), symbol_index: symbol_index.clone(), - visible_str_bindings: module_visible.visible_str_bindings.clone(), - unit_variant_index: module_visible.unit_variant_index.clone(), + unit_variant_index: module_variant_index.clone(), }); let resolved = resolve_env_bindings( unresolved_env.clone(), @@ -20720,7 +20715,6 @@ pub fn build_type_env( source_visible_names: source_visible_names.clone(), authored_import_names: authored_import_names.clone(), symbol_index: resolved_env_out.symbol_index.clone(), - visible_str_bindings: resolved_env_out.visible_str_bindings.clone(), unit_variant_index: resolved_env_out.unit_variant_index.clone(), }); let cache_str_bindings = v1_rt::rc_map_merge( @@ -20912,9 +20906,9 @@ pub fn build_type_env_unresolved( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), - visible_str_bindings: kernel_str_bindings.clone(), unit_variant_index: crate::v1_compiler_infer_env::build_unit_variant_index( kernel_str_bindings.clone(), + Rc::new(vec![]), source_indices.clone(), ), }); @@ -21218,7 +21212,7 @@ pub fn build_type_env_unresolved( 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 module_visible = crate::v1_compiler_infer_env::build_visible_bindings_update( + let module_variant_index = crate::v1_compiler_infer_env::build_unit_variant_index( local_str_bindings.clone(), scope_parents.clone(), source_indices.clone(), @@ -21237,8 +21231,7 @@ pub fn build_type_env_unresolved( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), - visible_str_bindings: module_visible.visible_str_bindings.clone(), - unit_variant_index: module_visible.unit_variant_index.clone(), + unit_variant_index: module_variant_index.clone(), }); let type_env_cache = Rc::new(TypeEnvCache { deps_map: all_deps_map.clone(), @@ -22497,7 +22490,6 @@ pub struct BindingResult { pub struct BindingsAccum { pub bindings: Rc>>, pub str_bindings: Rc>>, - pub visible_str_bindings: Rc>>, pub unit_variant_index: Rc>>>>, pub diagnostics: Rc>>, } @@ -22506,15 +22498,15 @@ pub fn bindings_accum_insert( acc: Rc, ident: i64, updated_binding: Rc, + parents: Rc>>, source_indices: Rc>>, result_diagnostics: Rc>>, ) -> Rc { { - let visible_update = crate::v1_compiler_infer_env::visible_bindings_insert( - acc.visible_str_bindings.clone(), - acc.unit_variant_index.clone(), - updated_binding.clone(), - source_indices.clone(), + let shadowed = crate::v1_compiler_infer_env::effective_visible_binding( + acc.str_bindings.clone(), + parents.clone(), + updated_binding.name.clone(), ); Rc::new(BindingsAccum { bindings: v1_rt::rc_map_insert( @@ -22527,8 +22519,12 @@ pub fn bindings_accum_insert( updated_binding.name.clone(), updated_binding.clone(), ), - visible_str_bindings: visible_update.visible_str_bindings.clone(), - unit_variant_index: visible_update.unit_variant_index.clone(), + unit_variant_index: crate::v1_compiler_infer_env::unit_variant_index_shadow_insert( + acc.unit_variant_index.clone(), + shadowed.clone(), + updated_binding.clone(), + source_indices.clone(), + ), diagnostics: v1_rt::concat(acc.diagnostics.clone(), result_diagnostics.clone()), }) } @@ -22635,7 +22631,6 @@ pub fn topo_resolve_types( let stuck_accum = remaining.iter().cloned().fold(Rc::new(BindingsAccum { bindings: env.bindings.clone(), str_bindings: env.str_bindings.clone(), - visible_str_bindings: env.visible_str_bindings.clone(), unit_variant_index: env.unit_variant_index.clone(), diagnostics: Rc::new(vec![]), }), |acc: Rc, name: String| { @@ -22650,7 +22645,7 @@ let updated_binding = Rc::new(TypeBinding { resolved: resolved.clone(), provenance: Rc::new(SubValueRelation::SubValueUnknown), }); -bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.source_indices.clone(), result.diagnostics.clone()) +bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.parents.clone(), env.source_indices.clone(), result.diagnostics.clone()) }, None => acc.clone(), } @@ -22670,7 +22665,6 @@ bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.s source_visible_names: env.source_visible_names.clone(), authored_import_names: env.authored_import_names.clone(), symbol_index: env.symbol_index.clone(), - visible_str_bindings: stuck_accum.visible_str_bindings.clone(), unit_variant_index: stuck_accum.unit_variant_index.clone(), }), diagnostics: v1_rt::concat( @@ -22684,7 +22678,6 @@ bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.s Rc::new(BindingsAccum { bindings: env.bindings.clone(), str_bindings: env.str_bindings.clone(), - visible_str_bindings: env.visible_str_bindings.clone(), unit_variant_index: env.unit_variant_index.clone(), diagnostics: Rc::new(vec![]), }), @@ -22716,6 +22709,7 @@ bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.s acc.clone(), ident.clone(), updated_binding.clone(), + env.parents.clone(), env.source_indices.clone(), result.diagnostics.clone(), ) @@ -22757,7 +22751,6 @@ bindings_accum_insert(acc.clone(), ident.clone(), updated_binding.clone(), env.s source_visible_names: env.source_visible_names.clone(), authored_import_names: env.authored_import_names.clone(), symbol_index: env.symbol_index.clone(), - visible_str_bindings: ready_accum.visible_str_bindings.clone(), unit_variant_index: ready_accum.unit_variant_index.clone(), }); let __tco_2 = v1_rt::concat(diagnostics, ready_accum.diagnostics.clone()); @@ -23557,22 +23550,22 @@ pub fn rewire_type_env_import_str_binding_identity( rewrites.clone(), ), }); - let rewired_visible = Rc::new(v1_rt::map_values(&str_binding_overlay)) + let rewired_index = Rc::new(v1_rt::map_values(&str_binding_overlay)) .iter() .cloned() .fold( - Rc::new(VisibleBindingsUpdate { - visible_str_bindings: m - .type_env - .clone() - .visible_str_bindings - .clone(), - unit_variant_index: m.type_env.clone().unit_variant_index.clone(), - }), - |acc: Rc, binding: Rc| { - crate::v1_compiler_infer_env::visible_bindings_insert( - acc.visible_str_bindings.clone(), - acc.unit_variant_index.clone(), + m.type_env.clone().unit_variant_index.clone(), + |acc: Rc< + HashMap>>>, + >, + binding: Rc| { + crate::v1_compiler_infer_env::unit_variant_index_shadow_insert( + acc, + crate::v1_compiler_infer_env::effective_visible_binding( + m.type_env.clone().str_bindings.clone(), + m.type_env.clone().parents.clone(), + binding.name.clone(), + ), binding.clone(), source_indices.clone(), ) @@ -23596,8 +23589,7 @@ pub fn rewire_type_env_import_str_binding_identity( source_visible_names: m.type_env.clone().source_visible_names.clone(), authored_import_names: m.type_env.clone().authored_import_names.clone(), symbol_index: m.type_env.clone().symbol_index.clone(), - visible_str_bindings: rewired_visible.visible_str_bindings.clone(), - unit_variant_index: rewired_visible.unit_variant_index.clone(), + unit_variant_index: rewired_index.clone(), }), type_env_cache: m.type_env_cache.clone(), interface: m.interface.clone(), @@ -23826,9 +23818,9 @@ pub fn compiler_kernel_type_env( source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: crate::v1_compiler_infer_env::empty_symbol_index(), - visible_str_bindings: kernel_str_bindings.clone(), unit_variant_index: crate::v1_compiler_infer_env::build_unit_variant_index( kernel_str_bindings.clone(), + Rc::new(vec![]), source_indices.clone(), ), }) @@ -23915,12 +23907,11 @@ pub fn rewire_type_env_parent_links( }); let rewired_parents = v1_rt::concat(import_parents.clone(), Rc::new(vec![shared_kernel.clone()])); - let rewired_visible = - crate::v1_compiler_infer_env::build_visible_bindings_update( - m.type_env.clone().str_bindings.clone(), - rewired_parents.clone(), - m.type_env.clone().source_indices.clone(), - ); + let rewired_index = crate::v1_compiler_infer_env::build_unit_variant_index( + m.type_env.clone().str_bindings.clone(), + rewired_parents.clone(), + m.type_env.clone().source_indices.clone(), + ); Rc::new(TypedModule { progress: m.progress.clone(), module: m.module.clone(), @@ -23939,8 +23930,7 @@ pub fn rewire_type_env_parent_links( source_visible_names: m.type_env.clone().source_visible_names.clone(), authored_import_names: m.type_env.clone().authored_import_names.clone(), symbol_index: m.type_env.clone().symbol_index.clone(), - visible_str_bindings: rewired_visible.visible_str_bindings.clone(), - unit_variant_index: rewired_visible.unit_variant_index.clone(), + unit_variant_index: rewired_index.clone(), }), type_env_cache: m.type_env_cache.clone(), interface: m.interface.clone(), diff --git a/src/v1/stage0/src/v1_compiler_infer_env.rs b/src/v1/stage0/src/v1_compiler_infer_env.rs index 74dfff6a4ce..68fe4480206 100644 --- a/src/v1/stage0/src/v1_compiler_infer_env.rs +++ b/src/v1/stage0/src/v1_compiler_infer_env.rs @@ -59,7 +59,6 @@ pub struct TypeEnv { pub authored_import_names: Rc>, pub symbol_index: Rc, pub module_path: String, - pub visible_str_bindings: Rc>>, pub unit_variant_index: Rc>>>>, } @@ -217,81 +216,64 @@ pub fn unit_variant_index_add_binding( } } -#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] -pub struct VisibleBindingsUpdate { - pub visible_str_bindings: Rc>>, - pub unit_variant_index: Rc>>>>, +pub fn effective_visible_binding( + str_bindings: Rc>>, + parents: Rc>>, + name: String, +) -> Option> { + match v1_rt::map_get(&str_bindings, name.clone()) { + Some(b) => Some(b.clone()), + None => parents + .iter() + .cloned() + .fold(None, |acc: _, parent: Rc| { + if (acc.clone() != None) { + acc.clone() + } else { + v1_rt::map_get(&parent.str_bindings.clone(), name.clone()) + } + }), + } } -pub fn visible_bindings_insert( - visible_str_bindings: Rc>>, +pub fn unit_variant_index_shadow_insert( unit_variant_index: Rc>>>>, + shadowed: Option>, binding: Rc, source_indices: Rc>>, -) -> Rc { +) -> Rc>>>> { { - let cleared = match v1_rt::map_get(&visible_str_bindings, binding.name.clone()) { - Some(shadowed) => unit_variant_index_remove_binding( + let cleared = match shadowed.clone() { + Some(old) => unit_variant_index_remove_binding( unit_variant_index.clone(), - shadowed.clone(), + old.clone(), source_indices.clone(), ), None => unit_variant_index.clone(), }; - Rc::new(VisibleBindingsUpdate { - visible_str_bindings: v1_rt::rc_map_insert( - visible_str_bindings.clone(), - binding.name.clone(), - binding.clone(), - ), - unit_variant_index: unit_variant_index_add_binding( - cleared.clone(), - binding.clone(), - source_indices.clone(), - ), - }) + unit_variant_index_add_binding(cleared.clone(), binding.clone(), source_indices.clone()) } } -pub fn build_visible_str_bindings( +pub fn build_unit_variant_index( str_bindings: Rc>>, parents: Rc>>, -) -> Rc>> { - parents.iter().cloned().fold( - str_bindings.clone(), - |acc: Rc>>, parent: Rc| { - v1_rt::rc_map_merge(parent.str_bindings.clone(), acc) - }, - ) -} - -pub fn build_unit_variant_index( - visible_str_bindings: Rc>>, source_indices: Rc>>, ) -> Rc>>>> { - Rc::new(v1_rt::map_values(&visible_str_bindings)) - .iter() - .cloned() - .fold( + { + let visible = parents.iter().cloned().fold( + str_bindings.clone(), + |acc: Rc>>, parent: Rc| { + v1_rt::rc_map_merge(parent.str_bindings.clone(), acc) + }, + ); + Rc::new(v1_rt::map_values(&visible)).iter().cloned().fold( v1_rt::rc_empty_map::>>>(), |acc: Rc>>>>, binding: Rc| { unit_variant_index_add_binding(acc, binding.clone(), source_indices.clone()) }, ) -} - -pub fn build_visible_bindings_update( - str_bindings: Rc>>, - parents: Rc>>, - source_indices: Rc>>, -) -> Rc { - { - let visible = build_visible_str_bindings(str_bindings.clone(), parents.clone()); - Rc::new(VisibleBindingsUpdate { - visible_str_bindings: visible.clone(), - unit_variant_index: build_unit_variant_index(visible.clone(), source_indices.clone()), - }) } } @@ -389,7 +371,6 @@ pub fn empty_type_env() -> Rc { source_visible_names: v1_rt::rc_empty_map::(), authored_import_names: v1_rt::rc_empty_map::(), symbol_index: empty_symbol_index(), - visible_str_bindings: v1_rt::rc_empty_map::>(), unit_variant_index: v1_rt::rc_empty_map::< String, Rc>>, @@ -2192,9 +2173,14 @@ pub fn env_with_type_variable_bindings(env: Rc, tp_names: Rc, tp_names: Rc