The mutating compiler-API, minting types LAZILY at lowering time (single pass,
the existing runComptimeTypeFunc path — so the write side is legacy-only; the
VM isn't wired at lowering time, and the read-side readers stay dual-path):
declare_type(name) -> Type forward nominal handle (≈ declare)
pointer_to(t) -> Type build *T references
register_type(handle, kind, members) ONE kind-branching fill (≈ unified define)
register_type branches on kind IN THE COMPILER (subsuming define's per-kind
dispatch); codes match type_kind: 1 struct, 2 actual .@"enum", 3 tagged_union,
4 tuple. Members are {name: string, ty: Type}. A non-generic `-> Type` builder is
now flagged is_comptime (decl.zig) so its dead body permits the welded calls.
Graph support: forward declare_type handles + pointer_to express a mutually-
recursive A<->B graph (*A, *B, B-by-value) before bodies are filled. register_type
is idempotent — re-filling a nominal slot (a minting module reached via two import
edges) re-mints identically rather than erroring (nominalIdent reads identity from
any nominal kind).
Fixes (issue 0142):
- A fully payloadless comptime-minted enum was minted as an all-void tagged_union,
whose IR size disagrees with its LLVM size -> verifySizes panic. Now mints a real
.@"enum" (register_type kind 2 AND the metatype defineEnum).
- Bare `EnumType.variant` qualified construction of a payloadless variant wasn't
supported (failed for hand-written enums too — the type name lowered to a Type
value). Added in lowerFieldAccess via isPayloadlessVariant; payload-carrying
variants keep their call form.
Examples: 0631 (graph + actual enum + reflection), 0632 (make_enum all-void),
0633/0634/0635 (namespaced / bare / multi-edge import of a minted type), 0187
(qualified variant construction). Unit tests added.
Parity 697/697 (gate OFF and -Dcomptime-flat).
32 lines
1.0 KiB
Plaintext
32 lines
1.0 KiB
Plaintext
// Regression (issue 0142): a comptime-minted FULLY payloadless enum (every
|
|
// variant tagless) must mint as a real `.@"enum"`, not an all-void tagged_union
|
|
// — the latter has an IR/LLVM size mismatch that tripped `verifySizes` at
|
|
// codegen. `make_enum` (declare/define) with an all-void variant list now
|
|
// produces an ordinary enum, usable like a hand-written one.
|
|
|
|
#import "modules/std.sx";
|
|
#import "modules/std/meta.sx";
|
|
|
|
make_suit :: () -> Type {
|
|
return make_enum("Suit", EnumVariant.[
|
|
EnumVariant.{ name = "hearts", payload = void },
|
|
EnumVariant.{ name = "spades", payload = void },
|
|
EnumVariant.{ name = "diamonds", payload = void },
|
|
]);
|
|
}
|
|
Suit :: make_suit();
|
|
|
|
show :: (s: Suit) {
|
|
if s == {
|
|
case .hearts: { print("hearts\n"); }
|
|
case .spades: { print("spades\n"); }
|
|
case .diamonds: { print("diamonds\n"); }
|
|
}
|
|
}
|
|
|
|
main :: () {
|
|
show(.spades); // leading-dot, typed context
|
|
x := Suit.diamonds; // qualified construction
|
|
show(x);
|
|
}
|