Fix phpstan/phpstan#14366: call-to-function is deprecated, depending on PHP_VERSION#5295
Closed
phpstan-bot wants to merge 2 commits intophpstan:2.1.xfrom
Closed
Fix phpstan/phpstan#14366: call-to-function is deprecated, depending on PHP_VERSION#5295phpstan-bot wants to merge 2 commits intophpstan:2.1.xfrom
phpstan-bot wants to merge 2 commits intophpstan:2.1.xfrom
Conversation
…precation version - Added DeprecatedSinceVersionHelper to extract the `since` version from #[Deprecated] attributes and compare it against the scope's narrowed PHP version - In NativeFunctionReflectionProvider, convert JetBrains\PhpStorm\Deprecated stub attributes to Deprecated AttributeReflection so the version info is accessible - Applied version-aware deprecation filtering in all RestrictedUsage rules: RestrictedFunctionUsageRule, RestrictedMethodUsageRule, RestrictedStaticMethodUsageRule, RestrictedPropertyUsageRule, RestrictedStaticPropertyUsageRule, RestrictedClassConstantUsageRule, and their callable variants - New regression test in tests/PHPStan/Rules/RestrictedUsage/Bug14366Test.php
staabm
reviewed
Mar 25, 2026
Comment on lines
+95
to
+100
| if ( | ||
| str_ends_with($restrictedUsage->identifier, '.deprecated') | ||
| && DeprecatedSinceVersionHelper::isScopeVersionBeforeDeprecation($constantReflection->getAttributes(), $scope->getPhpVersion()) | ||
| ) { | ||
| continue; | ||
| } |
Contributor
There was a problem hiding this comment.
deprecations is only one use-case of Restricted* classes. we should not mix this use-case into the this abstract base-classes
Collaborator
Author
There was a problem hiding this comment.
That was the initial make phpstan run which failed due to the dead method detection. The re-run after adding @api passed cleanly, and the commit has been pushed.
Member
|
I don't think I'd ever like what the bot came up with for this, this needs a human 😊 |
Member
|
Also it's not a priority. |
… to deprecation-rules extensions The Restricted*UsageRule classes are generic infrastructure for all restricted usage extensions, not just deprecations. Move the version-aware deprecation filtering into the phpstan-deprecation-rules extensions where it belongs. Mark DeprecatedSinceVersionHelper::isScopeVersionBeforeDeprecation as @api since it is consumed by the deprecation-rules extension package. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
When a deprecated function call (like
curl_close()) is guarded by aPHP_VERSION_IDcomparison (e.g.,if (PHP_VERSION_ID < 80000)), PHPStan should not report a deprecation error if the scope's narrowed PHP version falls below the version where the function was deprecated.Changes
src/Rules/RestrictedUsage/DeprecatedSinceVersionHelper.php— extracts thesinceversion from#[Deprecated(since: 'X.Y')]attributes and compares it against the scope's PHP version rangesrc/Reflection/SignatureMap/NativeFunctionReflectionProvider.php— convertsJetBrains\PhpStorm\Deprecatedattributes from phpstorm-stubs into PHPStanAttributeReflectionobjects withDeprecatedname, preserving thesinceandmessageargumentssrc/Rules/RestrictedUsage/RestrictedFunctionUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedFunctionCallableUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedMethodUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedMethodCallableUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedStaticMethodUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedStaticMethodCallableUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedPropertyUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedStaticPropertyUsageRule.phpsrc/Rules/RestrictedUsage/RestrictedClassConstantUsageRule.phpRoot cause
PHPStan narrows the PHP version type when it encounters
PHP_VERSION_IDcomparisons, but the deprecation reporting in the vendorphpstan-deprecation-rulesextension doesn't check the scope's PHP version against the function's deprecated-since version. The fix adds this check at the rule level in phpstan-src, where both the scope (with narrowed PHP version) and the function reflection (with attributes) are available.A secondary issue was that
JetBrains\PhpStorm\Deprecatedattributes from phpstorm-stubs were not being converted to PHPStanAttributeReflectionobjects (because theJetBrains\PhpStorm\Deprecatedclass isn't recognized by theAttributeReflectionFactory). The fix explicitly converts these toDeprecatedAttributeReflectionobjects inNativeFunctionReflectionProvider.Test
Added
tests/PHPStan/Rules/RestrictedUsage/Bug14366Test.phpwith test data intests/PHPStan/Rules/RestrictedUsage/data/bug-14366.php. The test configures PHP 8.5 (wherecurl_close()is deprecated) and verifies that:curl_close()insideif (PHP_VERSION_ID < 80000)does NOT produce a deprecation errorcurl_close()outside any version guard DOES produce a deprecation errorFixes phpstan/phpstan#14366