From 618985cfab869b3c157d0055ad7ddfa3da3329fd Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Mon, 5 Oct 2026 21:08:37 +0200 Subject: [PATCH 1/3] Allow __debugInfo() in enums on PHP 8.6+ Closes phpstan/phpstan#15368 --- src/Php/PhpVersions.php | 5 +++ src/Rules/Classes/EnumSanityRule.php | 5 ++- .../Rules/Classes/EnumSanityRuleTest.php | 19 ++++++++++++ .../data/enum-debug-info-php-versions.php | 31 +++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php diff --git a/src/Php/PhpVersions.php b/src/Php/PhpVersions.php index 84bd2c3f5f2..6fe7ae260f8 100644 --- a/src/Php/PhpVersions.php +++ b/src/Php/PhpVersions.php @@ -193,6 +193,11 @@ public function supportsDeprecatedTraits(): TrinaryLogic return IntegerRangeType::fromInterval(80500, null)->isSuperTypeOf($this->phpVersions)->result; } + public function supportsDebugInfoOnEnums(): TrinaryLogic + { + return IntegerRangeType::fromInterval(80600, null)->isSuperTypeOf($this->phpVersions)->result; + } + public function arrayFunctionsReturnNullWithNonArray(): TrinaryLogic { return IntegerRangeType::fromInterval(null, 79999)->isSuperTypeOf($this->phpVersions)->result; diff --git a/src/Rules/Classes/EnumSanityRule.php b/src/Rules/Classes/EnumSanityRule.php index d5e84aad004..6dad483ee7d 100644 --- a/src/Rules/Classes/EnumSanityRule.php +++ b/src/Rules/Classes/EnumSanityRule.php @@ -80,7 +80,10 @@ public function processNode(Node $node, Scope $scope): array ->line($methodNode->getStartLine()) ->nonIgnorable() ->build(); - } elseif (!array_key_exists($lowercasedMethodName, self::ALLOWED_MAGIC_METHODS)) { + } elseif ( + !array_key_exists($lowercasedMethodName, self::ALLOWED_MAGIC_METHODS) + && !($lowercasedMethodName === '__debuginfo' && $scope->getPhpVersion()->supportsDebugInfoOnEnums()->yes()) + ) { $errors[] = RuleErrorBuilder::message(sprintf( 'Enum %s contains magic method %s().', $classReflection->getDisplayName(), diff --git a/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php b/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php index 1d4ff07cc78..0371381a680 100644 --- a/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php +++ b/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php @@ -190,4 +190,23 @@ public function testBug11891(): void ]); } + #[RequiresPhp('>= 8.1.0')] + public function testDebugInfoPhpVersions(): void + { + $errors = [ + [ + 'Enum EnumDebugInfoPhpVersions\\UnsupportedInBranch contains magic method __debugInfo().', + 18, + ], + ]; + if (PHP_VERSION_ID < 80600) { + $errors[] = [ + 'Enum EnumDebugInfoPhpVersions\\DependsOnPhpVersion contains magic method __debugInfo().', + 27, + ]; + } + + $this->analyse([__DIR__ . '/data/enum-debug-info-php-versions.php'], $errors); + } + } diff --git a/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php new file mode 100644 index 00000000000..ac03ec03371 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php @@ -0,0 +1,31 @@ += 8.1 + +namespace EnumDebugInfoPhpVersions; + +if (PHP_VERSION_ID >= 80600) { + enum SupportedInBranch + { + public function __debugInfo(): array + { + return []; + } + } +} + +if (PHP_VERSION_ID < 80600) { + enum UnsupportedInBranch + { + public function __debugInfo(): array + { + return []; + } + } +} + +enum DependsOnPhpVersion +{ + public function __debugInfo(): array + { + return []; + } +} From 6feaa37092c3c05890bb84bd402ca12702ee2b3f Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Mon, 5 Oct 2026 21:23:32 +0200 Subject: [PATCH 2/3] Import PHP_VERSION_ID in EnumSanityRuleTest --- tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php b/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php index 0371381a680..e2146395987 100644 --- a/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php +++ b/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php @@ -6,6 +6,7 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\RequiresPhp; +use const PHP_VERSION_ID; /** * @extends RuleTestCase From cb2d0604b13d5536aab3a21e56afe871797cc087 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 6 Oct 2026 05:02:06 +0200 Subject: [PATCH 3/3] Simplify the __debugInfo() condition and cover a PHP version range spanning 8.6 in EnumSanityRule --- src/Rules/Classes/EnumSanityRule.php | 2 +- .../Classes/EnumSanityRuleConfigPhpTest.php | 45 +++++++++++++++++++ .../data/enum-debug-info-php-version.neon | 4 ++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php create mode 100644 tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon diff --git a/src/Rules/Classes/EnumSanityRule.php b/src/Rules/Classes/EnumSanityRule.php index 6dad483ee7d..5c1eead481f 100644 --- a/src/Rules/Classes/EnumSanityRule.php +++ b/src/Rules/Classes/EnumSanityRule.php @@ -82,7 +82,7 @@ public function processNode(Node $node, Scope $scope): array ->build(); } elseif ( !array_key_exists($lowercasedMethodName, self::ALLOWED_MAGIC_METHODS) - && !($lowercasedMethodName === '__debuginfo' && $scope->getPhpVersion()->supportsDebugInfoOnEnums()->yes()) + && ($lowercasedMethodName !== '__debuginfo' || !$scope->getPhpVersion()->supportsDebugInfoOnEnums()->yes()) ) { $errors[] = RuleErrorBuilder::message(sprintf( 'Enum %s contains magic method %s().', diff --git a/tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php b/tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php new file mode 100644 index 00000000000..6b3bb67dbe1 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php @@ -0,0 +1,45 @@ + + */ +class EnumSanityRuleConfigPhpTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new EnumSanityRule( + self::getContainer()->getByType(InitializerExprTypeResolver::class), + ); + } + + #[RequiresPhp('>= 8.1.0')] + public function testDebugInfoPhpVersionRangeSpanning86(): void + { + $this->analyse([__DIR__ . '/data/enum-debug-info-php-versions.php'], [ + [ + 'Enum EnumDebugInfoPhpVersions\UnsupportedInBranch contains magic method __debugInfo().', + 18, + ], + [ + 'Enum EnumDebugInfoPhpVersions\DependsOnPhpVersion contains magic method __debugInfo().', + 27, + ], + ]); + } + + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/data/enum-debug-info-php-version.neon', + ]; + } + +} diff --git a/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon new file mode 100644 index 00000000000..37a89190078 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon @@ -0,0 +1,4 @@ +parameters: + phpVersion: + min: 80500 + max: 80600