Skip to content

Fieldless enums should infer an integer backing (auto-increment discriminants, as i32) instead of requiring : i32: #309

@ehartford

Description

@ehartford

Summary

A fieldless enum written without an explicit : i32: backing should behave the same as one with it — the integer backing should be inferred, discriminants should auto-increment from the last explicit value, and as i32 should yield the discriminant. Today the backing-less form is a second-class citizen: explicit discriminants are rejected at parse time, as i32 fails codegen, and (worst) an older compiler silently miscompiles the form.

Expected

enum StackifyTermKind:
    Br = 0
    CondBr      // = 1 (auto-increment)
    Select      // = 2

should be identical to enum StackifyTermKind: i32: Br = 0 CondBr = 1 Select = 2.

Actual (current compiler, origin/main)

1. Explicit discriminant without : i32: → parse error

enum K:
    A = 0
    B
error: expected declaration (fn, type, enum, let, use, extern)
 --> x.w:2:7
2 |     A = 0
  |       ^

2. as i32 on a bare fieldless enum → codegen failure

enum K:
    A
    B
    C
fn main:
    print_i32(K.C as i32)   // error: code generation failed

With enum K: i32: the identical code prints 2.

3. Bare enums work for match/compare (so they're not wholly broken — only discriminant/as i32/explicit-value use fails):

enum Kind: A B C
// used in a Vec, compared with ==, passed by value: works, prints "abc"

Worst failure mode: silent miscompile (build corruption)

lib/std/cfg/stackify.w was edited to drop : i32: from StackifyTermKind/StackifyNodeKind/etc. while keeping Br = 0-style discriminants. The v0.14.5 seed accepted this and produced a corrupted stage1 (it then emitted nonsense expected declaration parse errors at unrelated lines of out/gen/main.w), rather than failing loudly. The current compiler errors loudly on the parse form (item 1), which is better, but the form should work, not just fail loudly.

Acceptance

  • A fieldless enum infers an integer backing; Foo = N then bare variants auto-increment (N+1, N+2, …).
  • EnumVal as i32 yields the discriminant for any fieldless enum, backed or not.
  • No syntax accepted by one compiler version may silently miscompile in another — reject loudly or compile correctly.
  • Regression: enum K: A=0 B C + K.B as i32 == 1, K.C as i32 == 2.

Env: with at origin/main, darwin-aarch64. (Note: : i32: alone does not confer Copy; that is a separate axis via impl Copy.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions