Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
5f12d04
Emitted v2 compiler crate: a declaration's identity is its last segme…
Aug 29, 2026
15c25ad
Class B: the algebra method fallback asserted a v1_rt bridge it had n…
Aug 29, 2026
3d41ffb
Only ModeledProjection carries projected_from: a HostRealizedSeam bod…
Aug 29, 2026
a393835
M1: realize the two symbol bridges, which were host seams nothing dec…
Aug 29, 2026
f17c17b
Regenerate the stage0 mirror for the emitter repairs (fixed point at …
Aug 29, 2026
c5de5aa
test.claim fixtures: one discriminating RED per closed emission class…
Aug 29, 2026
f8ea19f
Fix the class-B boundary control: count has a method template, so it …
Aug 29, 2026
73a1aa4
Unbreak the fixture parse: a trailing semicolon on the note declaration
Aug 29, 2026
c92b670
The self-call seam wall: an unrealized host seam refuses instead of e…
Aug 29, 2026
7a0577c
The seam wall must resolve realization through the roster's primitive…
Aug 29, 2026
50b10e4
The seam wall's realized arm must not suppress the declaration: suppr…
Aug 29, 2026
ebf8dca
The seam refusal is a generated body, not a crate-wide compile_error!…
Aug 29, 2026
bd7dac6
Two obligations the required floor found, both real consequences of t…
Aug 29, 2026
d0de2a4
Class-C fixture was broken, not the repair: the witness pool is small…
Aug 29, 2026
51fb911
is_empty: a conversion is not a repair -- give it the Rust realizatio…
Aug 29, 2026
a715f1c
A receiver's own callable field outranks every name-keyed table: clas…
Aug 29, 2026
54a1bbe
Two more wave admissions: the declaring module rebinds too
Aug 29, 2026
d805243
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 29, 2026
952ffa6
The callable-field tier was consuming the algebra profile's identity …
Aug 29, 2026
443f3de
Regenerate the stage0 mirror at the merge-equivalent tree: byte fixed…
Aug 29, 2026
aeded61
WIP tail classes
Aug 29, 2026
4b57ad1
WIP: if-equals-variant parses as a record literal; name the predicate
Aug 29, 2026
dc04b9d
WIP: annotations at module-item grain
Aug 29, 2026
7f43491
Regen round 1 (BuildBuddy invocation ebbdffc5, compiler gunbc=9830014…
Aug 29, 2026
e9900e2
Regen round 2 (BuildBuddy, compiler gunbc=75d74698aebcdb6e built from…
Aug 29, 2026
675d7ce
Arrow positions deviate from the generic renderer only for the two de…
Aug 29, 2026
0773184
B: the init turbofish declines a declaration's own formals by the lam…
Aug 29, 2026
a5120f1
Regenerate the stage0 mirror at the 0773184 freeze: byte fixed point …
Aug 29, 2026
b0e4ad3
One renderer for every arrow position; a type position never takes th…
Aug 29, 2026
49482b0
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 29, 2026
c2dadc8
Regenerate the stage0 mirror at the 49482b0 freeze: byte fixed point …
Aug 29, 2026
466811e
Witness fixture only: the qualified-type positive control moves to a …
Aug 29, 2026
d223621
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 30, 2026
4d5c549
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 30, 2026
a5af51e
WIP XL-0B commit 1: thread DeclarationRef into the checkpoint-spellin…
Aug 30, 2026
dbee0eb
Enroll the two emission batteries under the required-gate seed prefix…
Aug 30, 2026
678e736
XL-0B commit 1: exact spelling at the fn-signature and declaration-ty…
Aug 30, 2026
a1c9dde
alias-rhs leaf site reads scope.type_env
Aug 30, 2026
c91d79d
Regenerate the stage0 mirror at the XL-0B commit-1 tree: byte fixed p…
Aug 30, 2026
93f3b72
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 30, 2026
8781269
XL-0B commit 2 (source): declared callees imported over builtin captu…
Aug 30, 2026
59178a3
Merge remote-tracking branch 'origin/session/bold-carp-449' into sess…
Aug 30, 2026
e97322e
Regenerate the stage0 mirror for commit 2 (mechanical residue): byte …
Aug 30, 2026
4da6059
A1: relocate the import-admission helpers to their consumer layer; C:…
Aug 30, 2026
db40481
XL-0N: generic LiteralElaboration/OperatorRealization authority — typ…
Aug 30, 2026
0812548
XL-0N: the Peano-Nat inhabitance witness asserts the ruled admission …
Aug 30, 2026
d4b4cf7
Merge remote-tracking branch 'origin/session/bold-carp-449' into sess…
Aug 30, 2026
aa373f9
C corrected: InferredTree.facts stays the open PartialFunction; Parti…
Aug 30, 2026
657010b
XL-0N: operand realization hops alias/refinement declarations to thei…
Aug 30, 2026
c6d9b22
Regenerate the stage0 mirror for A1 + C (aa373f9): byte fixed point a…
Aug 30, 2026
2656610
XL-0N: Bool row -- KernelBoolLiteral into v2.std.logic.Bool via Boole…
Aug 30, 2026
5e73c01
XL-0N: operand realization hops alias items by is_type_alias_item/res…
Aug 30, 2026
eb0ea3c
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
3bf25c2
Commit 3 of the #9664 closure: six emitter mechanisms, the null keywo…
Aug 30, 2026
780b394
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 30, 2026
3989a1d
Hoist commit-3 rationale annotations to module-item grain (§4c refuse…
Aug 30, 2026
a9acc59
XL-0N: operand realization reads the RESOLVED structure -- a NoConnec…
Aug 30, 2026
bcb283c
XL-0N: shape-facts suffix spells Int counts with to_string (the seed …
Aug 30, 2026
6ba83b3
XL-0N: operand realization hops a where-refinement wrapper to its bas…
Aug 30, 2026
f38fdc9
XL-0N: operator realization matches over BinOp are total (14 closed v…
Aug 30, 2026
65ac88a
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
9187f3b
Commit 3 correction after the first regen: withdraw the Violates fiel…
Aug 30, 2026
b115892
Merge remote-tracking branch 'origin/main' into session/bold-carp-449
Aug 30, 2026
c453dd2
XL-0N: retire the regen-diagnosis shape-facts suffix -- the where-ref…
Aug 30, 2026
070a203
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
b621add
XL-0N: regenerated stage0 mirrors at byte fixed point (070a203 source…
Aug 30, 2026
29fa01c
XL-0N: register std.literal_elaboration and std.operator_realization …
Aug 30, 2026
ffdd98d
Merge remote-tracking branch 'origin/session/bold-carp-449' into sess…
Aug 30, 2026
e51aff9
XL-0N: type_reference_declaration_ref resolves an in-place (recursive…
Aug 30, 2026
155764c
XL-0N: regenerated stage0 mirrors at byte fixed point on e51aff9 (Bui…
Aug 30, 2026
bd5850c
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
c7b8056
XL-0N: type_reference_declaration_ref falls back to the module-visibl…
Aug 30, 2026
e10a8a1
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
370f5fa
XL-0N: regen mirrors at e10a8a1 (main cba8580 merged, fixed point rou…
Aug 30, 2026
4a5f9e5
XL-0N: regen mirror for the nested record-literal expansion (fixed po…
Aug 30, 2026
991d232
XL-0N: regenerate the stage0 crate partition artifact (main_wet on 37…
Aug 30, 2026
f7b0e1f
XL-0N: partition crates rendered from the regenerated artifact (regen…
Aug 30, 2026
022d265
XL-0N: an operand without a readable declaration decides by operator …
Aug 30, 2026
279ab70
XL-0N: the binary operator's operand declaration is read once at infe…
Aug 30, 2026
f829c75
XL-0N: regen mirrors for the typed-tree operand declaration (fixed po…
Aug 30, 2026
a2d542d
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
c3c2324
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
0a69d26
XL-0N: regen mirrors on the main-merged head (bootstrapped from f829c…
Aug 30, 2026
a2fe43d
XL-0N: roster the one namespace transition this lane makes -- type_re…
Aug 30, 2026
3ce8889
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
b6ec60b
XL-0N (review 57660): the connective arm states what it does not chec…
Aug 30, 2026
0954959
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 30, 2026
28c3ac8
XL-0N (review 57660 follow-through): the arithmetic refusal is for a …
Aug 30, 2026
c8651c8
XL-0N: host the connective stall in gunbc.guarantee_rung_drop -- the …
Aug 30, 2026
2177446
XL-0N: regen mirrors for the narrowed operand arm and the relocated s…
Aug 30, 2026
4a10272
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 31, 2026
b1356ab
XL-0N: regenerate the four merge-driver-refused mirrors from the merg…
Aug 31, 2026
39ea32f
Merge remote-tracking branch 'origin/main' into session/loyal-raven-297
Aug 31, 2026
b27f74e
XL-0N: delete the two consumerless BinOp Bool predicates (review 57754)
Aug 31, 2026
e1e14c8
XL-0N: refusals carry the BinOp coproduct, the Nat fork gets a stall …
Aug 31, 2026
64d16dd
XL-0N: regenerated stage0 mirrors and partition re-exports for the ma…
Aug 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions dag/gunbc/guarantee_rung_drop.dag
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,54 @@ fn stall_roster_size(ss: List<GuaranteeStall>) -> Int {
cons: fn(acc, s) { acc + 1 },
)
}

// THE CONNECTIVE GAP, DECLARED RATHER THAN CLAIMED (DESIGN section 4b(2): a class below its ceiling
// names its next-rung trigger). Ordering and arithmetic on a structural operand are decided by this
// roster -- a declared comparison, or a typed refusal. The logical connectives are NOT: inference
// constrains only the RESULT of `&&`/`||` to Bool (v1.compiler.types infer_binop_type_node), so a
// structural operand under a connective is authorable and renders as the host token. Found by
// review (claude/claude-opus-4-7 on gunbc#9719, 2026-08-30) reading the arm against its own prose.
//
// WHY THE OBVIOUS REPAIR IS THE WRONG ONE, measured before it was rejected: refusing every
// structural operand under a connective would refuse v2.std.logic Bool, which 593 modules import as
// their ordinary Bool -- the false-refusal cost the namespace wall's own doctrine names, and it
// would land as a corpus-wide red rather than as a wall. The repair is one more row FAMILY of the
// shape this roster already carries for ordering: the declaration names the operation that realizes
// its conjunction and disjunction, connectives on a declaration with a row realize through it, and
// only a declaration with NO row refuses -- at which point the refusal population is enumerable
// instead of being the whole corpus.
// TWO Nat AUTHORITIES ARE ONE NAME ANSWERING FOR TWO CONCEPTS, and this row exists because review
// 57758 correctly refused a version of it that was narrated in prose beside one of the two nat_max
// declarations. The fork predates this lane; what this lane changed is that the Peano side now
// carries real operations, so the fork is load-bearing rather than latent.
data two_nat_authorities_stall: GuaranteeStall = GuaranteeStall {
subject: "std.nat Nat (CommutativeSemiring<Magnitude>, realizing natively as a machine scalar) and v2.std.nat Nat (the Peano coproduct Zero | Succ) are two declarations answering for one name, so nat_add / nat_mul / nat_max / nat_compare each exist twice and a bare reference in a closure containing both modules is ambiguous",
current: Mitigatable,
ceiling: StructurallyImpossible,
blocker: AwaitsOneGrounding {
grounding: "one Nat authority: the numeric tower deciding whether the Peano coproduct IS the declaration and the semiring alias is derived from it, or the reverse -- a modeling ruling this lane cannot make from an operator-realization change",
},
population: BoundedPopulation {
members: [
"std.nat and v2.std.nat both declaring Nat, with per-operation forks (nat_add, nat_mul, nat_max, nat_compare) that no single function can serve because the two are different types",
"every reference site in a closure containing both modules, which must qualify the name (v2.lens.cost.valuation does) or resolve by pool precedence",
],
},
next_rung_trigger: "one Nat declaration in the corpus, with the other side derived from it rather than declared beside it -- retired by that capability and by nothing less, since deleting either declaration without deriving its operations would remove the operations its consumers call rather than unify the authority"
}

data structural_connective_stall: GuaranteeStall = GuaranteeStall {
subject: "std.operator_realization -- a logical connective (&&, ||) applied to a STRUCTURAL operand renders as the host token, because no declared-connective row family exists to realize or refuse it",
current: Mitigatable,
ceiling: MechanicallyPreventable,
blocker: AwaitsOneGrounding {
grounding: "a StructuralConnectiveBinding row family in std.operator_realization keyed on the operand's exact DeclarationRef (the shape StructuralOrderingBinding already has), plus its rows for the declarations this corpus uses under a connective -- v2.std.logic Bool first",
},
population: BoundedPopulation {
members: [
"a connective whose operand is a structural declaration with no host realization (v2.std.logic Bool: renders as the host token today and is the corpus's ordinary conjunction)",
"a connective whose operand is a structural declaration that is not a Boolean algebra at all (a Peano-shaped operand: authorable because inference constrains only the result type)",
],
},
next_rung_trigger: "std.operator_realization declaring StructuralConnectiveBinding and operator_realization_for routing And/Or through it -- realizing where a row exists and refusing, typed and located, where none does; retired by that capability and by nothing less, since a roster with no consumer would leave the host token exactly where it is today"
}
3 changes: 3 additions & 0 deletions dag/gunbc/stage0/stage0_crate_partition_generated.dag
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ data generated_partition_crate_rows: List<GeneratedPartitionCrateRow> = [
"std_occurrence_identity",
"std_source_annotation",
"std_target_representation",
"std_literal_elaboration",
"std_operator_realization",
"v1_std_core"
],
reexport_packages: [
Expand Down Expand Up @@ -147,6 +149,7 @@ data generated_partition_crate_rows: List<GeneratedPartitionCrateRow> = [
kind: GeneratedLayeredCoreCrate,
modules: [
"gunbc_rust_source_type_bindings",
"gunbc_structural_realization_bindings",
"v1_compiler_coercion",
"v1_compiler_infer_emit_info",
"v1_compiler_infer_env",
Expand Down
64 changes: 64 additions & 0 deletions dag/gunbc/structural_realization_bindings.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module gunbc.structural_realization_bindings

import std.types { List, String, Bool, NonEmptyStr }
import std.decl_ref { DeclarationRef, decl_ref }
import std.literal_elaboration { LiteralHomomorphism, LiteralSourceKind, KernelIntLiteral, KernelBoolLiteral, LiteralUnfolding, PeanoUnfold, BooleanUnfold }
import std.operator_realization { StructuralOrderingBinding }

// THE CORPUS'S HALF OF LITERAL ELABORATION AND OPERATOR REALIZATION (std.literal_elaboration,
// std.operator_realization): which of THIS corpus's structural declarations supply a kernel literal,
// and through which of their own constructors; and which declare an ordering, and by which
// comparison. Keyed on the exact declaration, never on a spelling: std.nat Nat (a native-realizing
// semiring alias) and v2.std.nat Nat (the Peano coproduct) share a spelling and only the second is
// a row here. The sibling gunbc.rust_source_type_bindings answers the OTHER question -- which
// declarations realize natively on the Rust target -- and a declaration is never in both: a native
// realization takes the kernel literal directly and the host operator directly.
//
// A ROW MAY ONLY STATE A HOMOMORPHISM THAT IS ALREADY TRUE OF THE DESTINATION, never be added to
// make a failing site compile (the same discipline gunbc.rust_source_type_bindings and
// v1.compiler.coercion numeric_realization_roster_extension_note hold for the native roster). The
// Peano row is true by the definition of the naturals: n maps to succ^n(zero), and that map is the
// unique semiring homomorphism from the kernel integers restricted to the nonnegatives.

fn peano_literal_homomorphism(module_path: String, nat: String, zero: String, succ: String, prev_field: String) -> LiteralHomomorphism {
LiteralHomomorphism {
source_kind: KernelIntLiteral,
destination: decl_ref(module_path: module_path, decl_name: nat),
producer: PeanoUnfold {
zero: decl_ref(module_path: module_path, decl_name: zero),
succ: decl_ref(module_path: module_path, decl_name: succ),
prev_field: prev_field as NonEmptyStr
}
}
}

fn boolean_literal_homomorphism(module_path: String, bool_decl: String, true_variant: String, false_variant: String) -> LiteralHomomorphism {
LiteralHomomorphism {
source_kind: KernelBoolLiteral,
destination: decl_ref(module_path: module_path, decl_name: bool_decl),
producer: BooleanUnfold {
true_variant: decl_ref(module_path: module_path, decl_name: true_variant),
false_variant: decl_ref(module_path: module_path, decl_name: false_variant)
}
}
}

// v2.std.logic Bool = True | False is gated structural on purpose (v1.compiler.coercion
// structural_declaration_modules_for); the corpus-wide prelude std.types Bool realizes natively and
// is NOT a row -- a kernel true/false at that boundary stays the host bool.
data literal_homomorphism_rows: List<LiteralHomomorphism> = [
peano_literal_homomorphism(module_path: "v2.std.nat", nat: "Nat", zero: "Zero", succ: "Succ", prev_field: "prev"),
boolean_literal_homomorphism(module_path: "v2.std.logic", bool_decl: "Bool", true_variant: "True", false_variant: "False")
]

fn structural_ordering_binding(carrier_module: String, carrier: String, compare_module: String, compare: String, ordering_module: String, ordering: String) -> StructuralOrderingBinding {
StructuralOrderingBinding {
carrier: decl_ref(module_path: carrier_module, decl_name: carrier),
compare: decl_ref(module_path: compare_module, decl_name: compare),
ordering: decl_ref(module_path: ordering_module, decl_name: ordering)
}
}

data structural_ordering_rows: List<StructuralOrderingBinding> = [
structural_ordering_binding(carrier_module: "v2.std.nat", carrier: "Nat", compare_module: "v2.std.nat", compare: "nat_compare", ordering_module: "std.algebra", ordering: "Ordering")
]
167 changes: 167 additions & 0 deletions dag/std/literal_elaboration.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
module std.literal_elaboration

import std.types { List, String, Bool, Int, NonEmptyStr }
import std.decl_ref { DeclarationRef, declaration_ref_eq }
import std.syntax { LiteralValue, LitStr, LitInt, LitFloat, LitBool, LitNull, LitSymbol }

// THE EXPECTED-TYPE-DIRECTED LITERAL INTRODUCTION JUDGMENT, as a model (DESIGN section 4: one
// decision procedure, emission and ingestion are the same homomorphism check read in two directions).
//
// A kernel literal (`0`, `"x"`, `true`, `^s`) is a value of the KERNEL type the parser mints for it.
// When such a literal reaches a typed boundary -- a call argument, a declared return, a record
// field, a data initializer, an annotated let, the other operand of a binary operator -- the
// boundary names a DESTINATION declaration. Three things can be true of that pair, and they are
// three outcomes, never one row with a flag:
// DirectLiteral the destination realizes the kernel type itself (a host numeric, the kernel
// type, a native-realizing alias): the literal is already its own value.
// ViaHomomorphism the destination is a STRUCTURAL declaration that SUPPLIES the literal: one
// declared homomorphism from the kernel value into the destination's own
// constructors (a Peano numeral into Zero/Succ, a text into a FreeMonoid of
// scalars). The typed tree carries the destination and the homomorphism at the
// occurrence; emission renders the image and never re-decides from spelling.
// Refused the roster is defective at this key (two rows for one destination).
// A destination with NO row and no native realization is not refused HERE: whether a kernel
// numeral inhabits such a declaration is the inhabitance judgment's question and it already owns
// that refusal (v1.compiler.infer declared_type_inhabitance). Answering it twice would be the two-
// authority state DESIGN section 3 forbids; this judgment introduces values, it does not police them.
//
// GENERIC BY CONSTRUCTION. The judgment is keyed on (source kind, exact destination DeclarationRef)
// and the image is produced by a closed roster of UNFOLDINGS, one arm per structural shape a kernel
// value can be unfolded into. A consumer that needs a new destination adds one ROW to the corpus
// roster (gunbc.structural_realization_bindings) and, if its destination's shape is new, one
// unfolding ARM here -- never a second elaboration fold and never a per-destination special case
// in inference or emission. The Peano arm is the first inhabitant; the FreeMonoid-of-scalars arm
// is the structural-text lane's (XL-0T) to add beside it.
//
// WHY A NEGATIVE-VALUE REFUSAL IS ABSENT ON PURPOSE (DESIGN section 4b: ask whether the RED is
// authorable before writing the check). A kernel integer literal is never negative -- `-3` parses
// as a unary negation applied to the literal `3`, and the negation is an ordinary expression that
// reaches inference through its own arm, not through this judgment. A ValueOutsideHomomorphismDomain
// arm for the Peano unfolding would therefore be permanently green and would be cited as coverage.

type LiteralSourceKind
= KernelIntLiteral
| KernelStringLiteral
| KernelFloatLiteral
| KernelBoolLiteral
| KernelSymbolLiteral
| KernelNullLiteral

fn literal_source_kind_of(value: LiteralValue) -> LiteralSourceKind {
match value {
LitInt { value: _ } => KernelIntLiteral
LitStr { value: _ } => KernelStringLiteral
LitFloat { value: _ } => KernelFloatLiteral
LitBool { value: _ } => KernelBoolLiteral
LitSymbol { value: _ } => KernelSymbolLiteral
LitNull => KernelNullLiteral
}
}

fn literal_source_kind_label(kind: LiteralSourceKind) -> String {
match kind {
KernelIntLiteral => "kernel_int_literal"
KernelStringLiteral => "kernel_string_literal"
KernelFloatLiteral => "kernel_float_literal"
KernelBoolLiteral => "kernel_bool_literal"
KernelSymbolLiteral => "kernel_symbol_literal"
KernelNullLiteral => "kernel_null_literal"
}
}

fn literal_source_kind_eq(a: LiteralSourceKind, b: LiteralSourceKind) -> Bool {
literal_source_kind_label(kind: a) == literal_source_kind_label(kind: b)
}

// HOW A KERNEL VALUE IS UNFOLDED INTO A DESTINATION'S CONSTRUCTORS. Each arm names the destination's
// own constructors by exact DeclarationRef -- the unfolding is a fact about the destination, so a
// renamed variant is a changed row, never a stale spelling inside the compiler.
// PeanoUnfold a nonnegative integer n unfolds to succ^n(zero): `succ { prev_field: ... }` nested
// n deep around the nullary `zero`.
// BooleanUnfold a kernel bool unfolds to the destination's nullary true or false constructor
// (v2.std.logic Bool = True | False, declared structural on purpose).
type LiteralUnfolding
= PeanoUnfold { zero: DeclarationRef, succ: DeclarationRef, prev_field: NonEmptyStr }
| BooleanUnfold { true_variant: DeclarationRef, false_variant: DeclarationRef }

type LiteralHomomorphism {
source_kind: LiteralSourceKind
destination: DeclarationRef
producer: LiteralUnfolding
}

type LiteralHomomorphismLookup
= LiteralHomomorphismFound { row: LiteralHomomorphism }
| LiteralHomomorphismAbsent
| LiteralHomomorphismAmbiguous { row_count: Int }

fn literal_homomorphism_for(
rows: List<LiteralHomomorphism>,
source_kind: LiteralSourceKind,
destination: DeclarationRef
) -> LiteralHomomorphismLookup {
let matching = rows |> filter(r =>
literal_source_kind_eq(a: r.source_kind, b: source_kind)
&& declaration_ref_eq(a: r.destination, b: destination))
let n = matching |> count
if n == 0 {
LiteralHomomorphismAbsent
} else if n == 1 {
match matching |> first {
Present { value: row } => LiteralHomomorphismFound { row: row }
Absent => LiteralHomomorphismAbsent
}
} else {
LiteralHomomorphismAmbiguous { row_count: n }
}
}

type LiteralElaborationRefusal
= HomomorphismDuplicated { source_kind: LiteralSourceKind, destination: DeclarationRef, row_count: Int }

fn literal_elaboration_refusal_message(cause: LiteralElaborationRefusal) -> String {
match cause {
HomomorphismDuplicated { source_kind: k, destination: d, row_count: n } =>
concat(
"literal elaboration: ", literal_source_kind_label(kind: k), " into ",
d.module_path as String, ".", d.decl_name as String,
" has more than one declared homomorphism (gunbc.structural_realization_bindings authoring defect)"
)
}
}

// THE DECISION. `destination_realizes_natively` is the caller's answer to "does this declaration
// realize the kernel type itself" (v1.compiler.coercion decl_file_realizes_natively / the exact
// Rust binding), passed in rather than re-derived so this module stays target-agnostic.
type LiteralElaborationOutcome
= DirectLiteral
| ViaHomomorphism { homomorphism: LiteralHomomorphism }
| LiteralElaborationRefused { cause: LiteralElaborationRefusal }

fn elaborate_literal_at(
rows: List<LiteralHomomorphism>,
source_kind: LiteralSourceKind,
destination: DeclarationRef,
destination_realizes_natively: Bool
) -> LiteralElaborationOutcome {
if destination_realizes_natively {
DirectLiteral
} else {
match literal_homomorphism_for(rows: rows, source_kind: source_kind, destination: destination) {
LiteralHomomorphismFound { row: row } => ViaHomomorphism { homomorphism: row }
LiteralHomomorphismAbsent => DirectLiteral
LiteralHomomorphismAmbiguous { row_count: n } =>
LiteralElaborationRefused { cause: HomomorphismDuplicated { source_kind: source_kind, destination: destination, row_count: n } }
}
}
}

// WHAT THE TYPED TREE CARRIES at an elaborated occurrence: the source kind, the exact destination,
// and the homomorphism selected. The occurrence itself is the node this record sits on (its
// occurrence identity), so it is not duplicated here. Only ViaHomomorphism occurrences carry a
// record -- a DirectLiteral is the ordinary literal node and needs nothing said about it.
type LiteralElaboration {
source_kind: LiteralSourceKind
destination: DeclarationRef
homomorphism: LiteralHomomorphism
}
Loading
Loading