Fix phpstan/phpstan#10690: Using a Trait with many private const triggers: "Constant is unused. "#5320
Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Open
Conversation
…it constants - Added ClassConstant wrapper class (similar to ClassMethod) that tracks isDeclaredInTrait - Updated ClassStatementsGatherer to wrap ClassConst nodes with trait context - Updated ClassConstantsNode with getClassConstants() method preserving backward compatibility - UnusedPrivateConstantRule now skips constants declared in traits - Added regression test in tests/PHPStan/Rules/DeadCode/data/bug-10690.php
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 trait defines private constants and multiple classes use the trait, any class that doesn't reference all the trait's constants would get false "Constant is unused" errors. The fix skips the unused constant check for constants that originate from a trait.
Changes
src/Node/ClassConstant.php— wrapper class (mirrorsClassMethod) that pairs aClassConstnode withisDeclaredInTrait()infosrc/Node/ClassStatementsGatherer.php— wrapsClassConstnodes inClassConstantusing$scope->isInTrait()src/Node/ClassConstantsNode.php— addedgetClassConstants()returningClassConstant[]; existinggetConstants()preserved for backward compatibilitysrc/Rules/DeadCode/UnusedPrivateConstantRule.php— usesgetClassConstants()and skips trait-declared constantstests/PHPStan/Rules/DeadCode/data/bug-10690.php— regression testtestBug10690()intests/PHPStan/Rules/DeadCode/UnusedPrivateConstantRuleTest.phpRoot cause
UnusedPrivateConstantRulechecks all private constants in a class and reports any that aren't referenced within that class. When a trait defines private constants and a class uses that trait, the constants appear in the class's constant list. If the class doesn't use all trait constants, the rule incorrectly reported them as unused. The fix follows the same pattern used for private properties and methods (isDeclaredInTrait()): constants declared in traits are skipped since the trait author intended them to be available across all users of the trait.Test
Added a regression test with a trait
MyTraitdefining two private constants (AAA,BBB), used by two classes —Firstuses both,SecondConsumeruses onlyAAA. The test expects no errors, confirming thatBBBis not falsely reported as unused inSecondConsumer.Fixes phpstan/phpstan#10690