Repository navigation
Stop the recursion when an enum case value reads itself - #6731
Merged
Merged
Conversation
staabm
reviewed
Oct 14, 2026
Comment on lines
+518
to
+519
| * Resolves the backing value of an enum case. A read of the case while | ||
| * its value is being resolved gives mixed, like a class constant does. |
Contributor
There was a problem hiding this comment.
Suggested change
| * Resolves the backing value of an enum case. A read of the case while | |
| * its value is being resolved gives mixed, like a class constant does. | |
| * Resolves the backing value of an enum case. A read of the case while | |
| * its value is being resolved gives mixed - like a class constant does - to prevent endless recursions. |
SanderMuller
force-pushed
the
enum-case-self-reference
branch
from
October 14, 2026 13:29
425e467 to
305963f
Compare
VincentLanglet
approved these changes
Oct 16, 2026
ClassReflection::getEnumCase() and getEnumCases() now resolve a case value through InitializerExprTypeResolver::getEnumCaseValueType(). It uses the currentlyResolvingClassConstant guard of class constants. Before, a case value that read itself, directly or through other cases, recursed until the call stack limit or the memory limit stopped the process. Now the read of the case that is being resolved gives mixed, as the read of a class constant that is being resolved does. The Turbo extension mirrors the change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
staabm
force-pushed
the
enum-case-self-reference
branch
from
October 16, 2026 08:17
305963f to
5230ed7
Compare
staabm
approved these changes
Oct 16, 2026
Contributor
|
thank you! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A backed enum case can read its own value, for example
case A = self::A->value;.ClassReflection::getEnumCase()then resolved the same value expression again and again. With the Turbo extension, the worker stopped on the call stack limit. Without it, the worker ran until the memory limit stopped it.getEnumCase()andgetEnumCases()now resolve the case value through the newInitializerExprTypeResolver::getEnumCaseValueType(). This method uses thecurrentlyResolvingClassConstantguard that class constants already use, with the keyClass::case. The read of a case that is being resolved now givesmixed, as the read of a class constant that is being resolved does. Socase A = self::A->value;resolves tomixed, andcase A = self::A->value . 'x';resolves tonon-falsy-string, the same asconst A = self::A . 'x';.When the value resolves to
mixed,EnumSanityRulereports the case withenum.caseType:PHP rejects this code at runtime with "Cannot declare self-referencing constant", so the error is on code that cannot run.
The Turbo extension mirrors the change in
InitializerExprTypeResolver.cppandClassReflection.cpp.The tests cover these cases:
getEnumCase()and throughgetEnumCases()Closes phpstan/phpstan#15458
🤖 Generated with Claude Code