Skip to content

Fix phpstan/phpstan#13133: Conditionally defined classes will be evaluated regardless of the current version#5170

Closed
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-clhquy4
Closed

Fix phpstan/phpstan#13133: Conditionally defined classes will be evaluated regardless of the current version#5170
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-clhquy4

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

Conditionally defined classes using if (PHP_VERSION_ID >= 80300) were still being analysed in the dead branch, causing non-ignorable errors like Class constants with native types are supported only on PHP 8.3 and later. even when running on PHP 8.2.

The fix ensures that RemoveUnusedCodeByPhpVersionIdVisitor is applied in RichParser (used for analysed files), the same way it was already applied in CleaningParser (used for non-analysed/reflection files).

Changes

  • Added PhpVersion dependency to RichParser constructor (src/Parser/RichParser.php)
  • Applied RemoveUnusedCodeByPhpVersionIdVisitor as the first AST traversal step in RichParser::parseString()
  • Updated tests/PHPStan/Analyser/AnalyserTest.php to pass the new PhpVersion parameter
  • Updated tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php to conditionally expect errors based on PHP version (dead branch is now correctly stripped)
  • Added regression test tests/PHPStan/Rules/Constants/NativeTypedClassConstantRuleBug13133Test.php with test data and config

Root cause

The RemoveUnusedCodeByPhpVersionIdVisitor strips dead code branches guarded by PHP_VERSION_ID comparisons from the AST at parse time. This visitor was only applied in CleaningParser (used via PathRoutingParser for non-analysed files/reflection discovery). When a file was in the "analysed files" set, PathRoutingParser routed it through RichParser instead, which did not apply this visitor. As a result, classes defined in dead PHP_VERSION_ID branches were still analysed and rules like NativeTypedClassConstantRule reported non-ignorable errors.

Test

Added NativeTypedClassConstantRuleBug13133Test which sets phpVersion: 80200 via a config file and analyses a file containing a class with typed constants inside if (PHP_VERSION_ID >= 80300) { ... } else { ... }. The test verifies no errors are reported since the typed-constant branch should be stripped as dead code on PHP 8.2.

Fixes phpstan/phpstan#13133

- Added RemoveUnusedCodeByPhpVersionIdVisitor to RichParser so that
  PHP_VERSION_ID-guarded dead code is stripped during analysis, not
  just during reflection discovery
- Previously only the CleaningParser (used for non-analysed files)
  applied this visitor; the RichParser (used for analysed files) did not
- Updated AnalyserTest to pass the new PhpVersion parameter to RichParser
- Updated CallMethodsRuleTest to account for dead branch stripping
- New regression test for conditionally defined classes with typed
  constants guarded by PHP_VERSION_ID checks

Closes phpstan/phpstan#13133
@staabm staabm closed this Mar 10, 2026
@staabm staabm deleted the create-pull-request/patch-clhquy4 branch March 10, 2026 07:28
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.

3 participants