Skip to content

Fix enum case === / == regression when constants store backing scalars (#5832) - #5857

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-5832-enum-compare-backing-scalar
Jun 4, 2026
Merged

PurHur merged 1 commit into
masterfrom
agent/issue-5832-enum-compare-backing-scalar

Conversation

@PurHur

@PurHur PurHur commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Materialize enum case objects on class const fetch using enumCases metadata when enumCaseCanonicalNames or stored values are legacy backing scalars (Language: backed enum case === / == with backing scalar must be false (zend_operators.c) #5798 regression).
  • Add compile-time isEnumCaseDeclare fallback (enum case Const_ uses flags=0; user const carries visibility bits) so folds emit enum case objects when php-cfg isEnumCase is missing.
  • Add maintainer repro script and unit regression test for legacy scalar constant tables.

php-src reference

  • Zend/zend_operators.c — enum case vs backing scalar compare is never equal
  • Zend/zend_enum.c — enum case singleton materialization

Verification

./script/docker-exec.sh -- bash -lc 'php bin/vm.php test/repro/maintainer_enum_compare_regression_5798.php'
# int-ident:false ... str-equal:false

./script/docker-exec.sh -- bash -lc 'php vendor/bin/phpunit --filter "VmEnumCompareBackingScalarRegressionTest|enum_compare_backing_scalar"'
# OK (6 tests, 12 assertions)

Legacy scalar repro (was true, now false):

./script/docker-exec.sh -- bash -lc 'php -r "
require \"vendor/autoload.php\";
\$runtime = new PHPCompiler\\Runtime();
\$runtime->run(\$runtime->parseAndCompile(\"<?php enum E: int { case A = 1; }\", \"d.php\"));
\$e = \$runtime->vmContext->classes[\"e\"];
\$s = new PHPCompiler\\VM\\Variable(PHPCompiler\\VM\\Variable::TYPE_INTEGER); \$s->int(1);
\$e->constants[\"a\"] = \$s; unset(\$e->enumCaseCanonicalNames[\"a\"]);
ob_start(); \$runtime->run(\$runtime->parseAndCompile(\"<?php var_export(E::A === 1);\", \"c.php\")); echo ob_get_clean();
"'
# false

Closes #5832

Made with Cursor

Materialize enum cases on class const fetch via enumCases metadata so
E::A === 1 stays false when legacy scalar storage drops canonical names;
add compile-time isEnumCase fallback when php-cfg flags are missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit b179062 into master Jun 4, 2026
@PurHur
PurHur deleted the agent/issue-5832-enum-compare-backing-scalar branch June 4, 2026 19:44
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.

Language: regression — backed enum === / == with backing scalar still true (#5798, PR #5802)

1 participant