Category
language · php-src-strict
Problem
Backed enum static factories Enum::tryFrom() and Enum::from() do not resolve valid backing scalars. Zend returns the matching enum case object (or null / ValueError for invalid input). This compiler returns null for every tryFrom() call and raises ValueError on valid from() input.
This breaks deserialization, config parsing, and any code using tryFrom/from for string/int backed enums.
php-src reference
Repro (verified 2026-06-18)
<?php
enum E: string {
case A = 'a';
}
var_dump(E::tryFrom('b')); // Zend: NULL
var_dump(E::tryFrom('a')); // Zend: enum(E::A)
try {
E::from('a');
echo "from ok\n";
} catch (ValueError $e) {
echo 'from fail: ', $e->getMessage(), "\n";
}
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php repro_enum_from.php
php bin/vm.php repro_enum_from.php
'
| Call |
Zend PHP 8.2 |
bin/vm.php (today) |
E::tryFrom('a') |
enum(E::A) |
NULL ❌ |
E::tryFrom('b') |
NULL |
NULL |
E::from('a') |
enum(E::A) |
ValueError ❌ |
Int-backed enums show the same pattern (E::tryFrom(1) → NULL).
Scope (this repo)
| Layer |
Path |
Notes |
| VM |
lib/VM/EnumFromHandler.php, enum case tables on ClassEntry |
Backing-value → case object lookup |
| Compiler |
lib/Compiler.php enum emission |
Ensure case table keys match runtime lookup |
| JIT/AOT |
enum static call lowering |
Same semantics as VM when in scope |
| Tests |
test/compliance/cases/language/enum_try_from.phpt, enum_from.phpt |
|
PHP-in-PHP first: lookup logic in lib/VM/ PHP; no new C runtime.
Done when
Verification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter enum_try_from'
Related
Category
language· php-src-strictProblem
Backed enum static factories
Enum::tryFrom()andEnum::from()do not resolve valid backing scalars. Zend returns the matching enum case object (ornull/ValueErrorfor invalid input). This compiler returnsnullfor everytryFrom()call and raisesValueErroron validfrom()input.This breaks deserialization, config parsing, and any code using
tryFrom/fromfor string/int backed enums.php-src reference
Zend/zend_enum.c—zend_enum_from(),zend_enum_from_base, case table lookup by backing valueZend/zend_enum.h— backed enum case hashZend/Enum.stub.phpRepro (verified 2026-06-18)
bin/vm.php(today)E::tryFrom('a')enum(E::A)NULL❌E::tryFrom('b')NULLNULLE::from('a')enum(E::A)ValueError❌Int-backed enums show the same pattern (
E::tryFrom(1)→NULL).Scope (this repo)
lib/VM/EnumFromHandler.php, enum case tables onClassEntrylib/Compiler.phpenum emissiontest/compliance/cases/language/enum_try_from.phpt,enum_from.phptPHP-in-PHP first: lookup logic in
lib/VM/PHP; no new C runtime.Done when
tryFrom()returns the enum case object for valid backing values andnullfor invalid (string + int backed)from()returns the case object or throwsValueErrorwith Zend-shaped message for invalid values./script/ci-fast.sh --filter enum_try_fromgreen on VM (JIT when enum static calls are wired)::classmust return enum name — VM TypeError on backing scalar (Zend/zend_enum.c) #9518, Language: (object) cast on enum case must return same enum case — not empty stdClass (Zend/zend_operators.c) #9569, Regression: serialize()/unserialize() enum cases — backing scalars not E: wire format (re-#6131, var.c) #8723) remain tracked separatelyVerification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit --filter enum_try_from'Related