Skip to content

Language: enum methods and non-const enum body elements (self-host subset) #2299

Description

@PurHur

Problem

Backed enum declarations are green (#1356 ✅) for const-like cases, but lib/Compiler.php::compileEnumBody() still throws on any enum body child that is not Op\Terminal\Const_:

throw new \LogicException('Unsupported enum body element: '.get_class($child));

docs/bootstrap-inventory.md may list Unsupported enum body element: when inventory regresses. Host/vendor PHP 8.2+ code uses enum methods, implements clauses, and non-const patterns that block self-host batches.

Goal (v1 subset)

Support the smallest set needed to reduce inventory noise without full PHP 8.1 enum semantics:

  1. Enum methods — public function label(): string lowered like class methods (Language: Class methods and property access in JIT #58 / Language: Visibility, constructors, and destructors #145 dependency)
  2. Enum interfaces — enum Foo: string implements Bar recorded in class metadata (no dynamic dispatch v1)
  3. Document out of scope: pure enums without backing type, enum hooks, const + method combos requiring traits (Language: Traits, abstract classes, and interfaces #144)

Implementation hints

Layer Path Notes
Compiler lib/Compiler.php — compileEnum, compileEnumBody Accept ClassMethod in enum body; reuse compileClassBody pieces
VM lib/VM.php Enum case objects + method dispatch (mirror class vtable v1)
JIT lib/JIT.php Defer until VM green; pair #2114 if try/catch in enum method
Lint lib/Lint/UnsupportedRegistry.php Remove enum-method kinds when implemented
AOT lib/AOT/ Same lowering as instance methods after #58

Suggested PR slices

  1. Metadata only — parse implements on enum; no dispatch
  2. Single enum method — public function name(): string with $this as case wrapper
  3. Compliance — test/compliance/cases/enum_method.phpt
  4. Inventory — regen docs/bootstrap-inventory.md; expect warning delta

Test plan

./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter Enum'
php bin/vm.php -r 'enum E: string { case A = "a"; public function x(): string { return $this->name; } } echo E::A->x();'

Acceptance criteria

  • compileEnumBody accepts at least one ClassMethod without throw
  • Compliance PHPT passes on VM (JIT optional follow-up)
  • php script/bootstrap-inventory.php --check still clean or documented delta
  • script/capability-matrix.php row updated

Verification (local / Docker only)

./script/ci-fast.sh --filter enum
make test-harness   # pre-merge when JIT touched

No GitHub Actions (#394 ✅).

Dependencies

Links

Activity

  1. PurHur commented on May 26, 2026

    @PurHur
    OwnerAuthor

    Implementation expansion (backlog pass)

    Compiler paths

    Symbol Location Change
    compileEnumBody lib/Compiler.php Accept Op\Stmt\ClassMethod alongside Const_
    compileEnum same Record implements list on enum metadata (no dispatch v1)
    Enum case values existing #1356 ✅ Unchanged

    Reuse compileClassMethod() helper where possible — enums share VM class registry with TYPE_ENUM (verify constant in OpCode).

    VM / JIT ordering

    1. VM: register enum methods on enum id; calls via MethodCall on enum case or enum name per PHPT design.
    2. JIT: blocked on Language: Class methods and property access in JIT #58 for ClassMethod emission — document markTestSkipped in @group llvm PHPT until then.
    3. AOT: same as class methods once VM green.

    First PR slice

    // test/compliance/cases/enum_method.phpt
    enum Status: string {
        case Ok = 'ok';
        public function label(): string { return $this->name; }
    }

    Assert Status::Ok->label() or static call pattern you support in v1.

    Inventory probe

    php script/bootstrap-inventory-triage.php --grep 'Unsupported enum body' --top 5
    php script/bootstrap-inventory.php | grep -c 'Unsupported enum body element'

    Docs

    Dependencies (strict)

    Land after or with minimal #58 VM method dispatch — otherwise PHPT passes parse/lowering but fails at runtime.

    Epic #1492 · ROADMAP #78 Phase 1.

  2. added a commit that references this issue on May 27, 2026
  3. added a commit that references this issue on May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions