Skip to content

t27core: enums, byte-identical to gen-c (Closes #8004) - #8007

Merged
gHashTag merged 1 commit into
masterfrom
core/p2-slice2-enums
Oct 9, 2026
Merged

gHashTag merged 1 commit into
masterfrom
core/p2-slice2-enums

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Closes #8004. Part of #5980 (P2: enums). Follows #8000 (structs).

What the core accepts now

Probed against t27c gen-c on master 321ced0. Byte-identical with gen-c:

  • Declarations: [pub] enum E [(SCALAR)] { a, b = N, c = -N, ... } and [pub] const|let E = enum [(SCALAR)] { ... };. gen-c drops the tag type, since a C enum is an int.
  • Enums section: gen-c's "Enums" section, between the constants and the structs, with typedef enum { E_A, E_B = 5, ... } E;.
  • Enum types wherever a struct type stands, struct fields included. Enum-typed globals go in "Constants of declared types".
  • Members E.a, E::a and .a, written as gen-c's upper-cased constant E_A. The same holds in a const value (const D: E = E::a;) and in struct literals.
  • Switch labels:
    • .a => in a switch with an else;
    • a switch with no else whose arms name every member of one enum exactly once. gen-c's closing : 0 is never reached there.
  • Arrays of enums: a list, or a repeat of E.a / E::a, which gen-c writes as a range, as it does a number.

What it refuses (gen-c exits 0 on each)

fixture code gen-c's loss
e13_enum_member_no_single_owner E_ENUM (new, 13) .x with two owners becomes a bare X, here the const 3 (#8001)
e13_enum_member_case_inferred, e13_enum_member_case_dotted E_ENUM .red and E.BLUE match Red and blue once upper-cased; Zig has no such member (#8001)
e5_enum_constant_spelled_by_param E_NAME the parameter MODE_ON hides the constant and C returns it (#8001)
e5_enum_shadowed_by_local E_NAME gen-c reads E.on as the member whatever binds E (#8001)
e13_enum_value_expression E_ENUM p = 1 + 2 gives G_P = 1, G_2: a new member (#8002)
e13_enum_value_separator E_ENUM 1_000 is written as spelled (#8002)
e7_enum_inferred_const E_CONST const D: E = .on; is never emitted (#8003)
e9_enum_repeat_inferred E_ARRAY [_]E{.on} ** 2 becomes {0}, the first member (#8003)
e2_enum_switch_not_exhaustive E_SYNTAX with no else, a missing member reads 0; Zig refuses (#8003)
e2_enum_switch_duplicate_label E_SYNTAX C takes the first arm; Zig refuses (#8003)
e13_enum_constants_collide E_ENUM a and A are one C constant
e13_enum_empty E_ENUM C has no empty enum

Zig backend defect found on the way: #8006. t27c gen writes e as u8 on an enum as @intCast(e), which Zig rejects; t27b refuses the cast too. accept/enum_cast.t27 pins the shape for C, and accept/enum_values.t27 runs on all three routes. The core itself does not cast an enum.

Lines by file

file + - kind
specs/compiler/core/t27core.t27 612 22 .t27
specs/compiler/core/t27core_ddc.t27 8310 7265 .t27: repinned packed data; no new module var
bootstrap/tests/fixtures/core_selfhost/**/*.t27 222 0 .t27 data: 2 accept, 13 refuse
hand-written Rust 0 0 none
generated 0 0 none

On the t27c lab, master's gen/c/policy/own_language.c with origin/master:tools/policy/foreign-exceptions.txt gives check_budget exit 0 and check_all exit 0.

Lab evidence

t27c lab, with t27c built from 321ced0 plus this branch. compiler.rs is unchanged.

check result
core tests (gen-c + cc) 44/44 (36 before, plus 8 enum tests)
fixpoint core(core.t27) == gen-c(core.t27) holds, 141292 bytes
accept fixtures 15/15 byte-identical, and run or build
refuse fixtures every one carries its code
corpus differential 91 accepted, 0 mismatched
cargo test --release -p t27c --test core_selfhost ok
enum fuzzing (scratch generator, not committed) 2150 random programs: 1-3 enums in both forms, tags, values, the three member spellings, exhaustive and else switches, arrays, struct fields, globals, and lossy shapes mixed in. 1027 accepted byte-identical, 0 mismatches, 0 accepted that gen-c refuses
DDC route C (Zig t27c test-report) core 44/44, t27core_ddc 1/1, enum_values 2/2; enum_cast is BLOCKED by #8006
DDC route B (t27b aarch64 under qemu, t27b lab, t27b built from 321ced0 in a private /tmp) core 44/44, t27core_ddc 1/1, enum_values 2/2; enum_cast is refused by t27b (unsupported cast)

t27core_ddc.t27 is repinned:

  • S is 156820 bytes, sha256 d9905301...a649.
  • E is 141292 bytes, sha256 318eda9c...846f.

🤖 Generated with Claude Code

P2 slice 2 of epic #5980. The self-hosted core accepts enum declarations
(`enum E [(T)] { ... }` and `const|let E = enum [(T)] { ... };`), enum
types wherever a struct type stands, members written `E.M`, `E::M` and
`.M`, `.M` switch labels, a switch without `else` that names every member
of one enum once, and arrays of enums repeating `E.M`. gen-c's Enums
section and upper-cased constants are reproduced byte for byte.

New code E_ENUM (13). Refused, each with a fixture: a member matched only
by case or with no single owner, a name spelling an emitted constant, a
local named like an enum (#8001); a member value that is not one number
(#8002); `const D: E = .M;`, `[_]E{.M} ** N`, a non-exhaustive or
duplicated enum switch (#8003); an empty enum; colliding constants.

t27core_ddc.t27 is repinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-09 05:32:25 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 48
PRs with All Checks Green 2
READY 1
FAILING 48
PENDING 0
NO CHECKS YET 0

These columns do not partition: 1 + 48 + 0 + 0 = 49, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=3c0ade9e73e4 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

self-host P2 slice 2: enums, byte-identical to gen-c

2 participants