diff --git a/src/Reflection/Php/PhpClassReflectionExtension.php b/src/Reflection/Php/PhpClassReflectionExtension.php index 4e77208566..939e1550d3 100644 --- a/src/Reflection/Php/PhpClassReflectionExtension.php +++ b/src/Reflection/Php/PhpClassReflectionExtension.php @@ -839,7 +839,17 @@ public function createUserlandMethodReflection(ClassReflection $fileDeclaringCla } $isInternal = $resolvedPhpDoc->isInternal(); $isFinal = $resolvedPhpDoc->isFinal(); - $isPure = $resolvedPhpDoc->isPure(); + $isPure = null; + foreach ($actualDeclaringClass->getAncestors() as $className => $ancestor) { + if ($this->signatureMapProvider->hasMethodMetadata($className, $methodReflection->getName())) { + $hasSideEffects = $this->signatureMapProvider->getMethodMetadata($className, $methodReflection->getName())['hasSideEffects']; + $isPure = !$hasSideEffects; + + break; + } + } + + $isPure ??= $resolvedPhpDoc->isPure(); $asserts = Assertions::createFromResolvedPhpDocBlock($resolvedPhpDoc); $acceptsNamedArguments = $resolvedPhpDoc->acceptsNamedArguments(); $selfOutType = $resolvedPhpDoc->getSelfOutTag() !== null ? $resolvedPhpDoc->getSelfOutTag()->getType() : null; diff --git a/src/Reflection/SignatureMap/Php8SignatureMapProvider.php b/src/Reflection/SignatureMap/Php8SignatureMapProvider.php index c706e7dbbf..61b1553782 100644 --- a/src/Reflection/SignatureMap/Php8SignatureMapProvider.php +++ b/src/Reflection/SignatureMap/Php8SignatureMapProvider.php @@ -64,9 +64,6 @@ public function __construct( public function hasMethodSignature(string $className, string $methodName): bool { $lowerClassName = strtolower($className); - if ($lowerClassName === 'backedenum') { - return false; - } if (!array_key_exists($lowerClassName, $this->map->classes)) { return $this->functionSignatureMapProvider->hasMethodSignature($className, $methodName); } diff --git a/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php b/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php index 44e326a0d6..66d1cec464 100644 --- a/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php +++ b/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php @@ -174,4 +174,10 @@ public function testBug12224(): void ]); } + #[RequiresPhp('>= 8.1')] + public function testBug13201(): void + { + $this->analyse([__DIR__ . '/data/bug-13201.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Pure/data/bug-13201.php b/tests/PHPStan/Rules/Pure/data/bug-13201.php new file mode 100644 index 0000000000..09ed46ef53 --- /dev/null +++ b/tests/PHPStan/Rules/Pure/data/bug-13201.php @@ -0,0 +1,19 @@ += 8.1 + +namespace PHPStan\Rules\Pure\data\Bug13201; + +enum Foo: string +{ + + case Bar = 'bar'; + case Unknown = 'unknown'; + +} + +/** + * @pure + */ +function createWithFallback(string $type): Foo +{ + return Foo::tryFrom($type) ?? Foo::Unknown; +}