Fix phpstan/phpstan#14102: No error if construct signature of class-string of abstract class is invalid#5234
Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Open
Conversation
- Included abstract classes in class-string resolution in InstantiationRule::getClassNames() - Added $isFromClassString flag to skip "abstract class" error for class-string-resolved types - Constant string types (e.g. Foo::class) still go through the existing path and report abstract errors - New regression test in tests/PHPStan/Rules/Classes/data/bug-14102.php - Updated existing class-string test to expect errors for abstract class constructors
Member
|
This is a new class of error that should only be there with bleeding edge |
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 using
class-string<AbstractClass>withnew $className(), PHPStan was not checking constructor parameters if the class was abstract. This fix ensures constructor parameter validation works for abstract classes resolved from class-string types.Changes
src/Rules/Classes/InstantiationRule.php:!$classReflection->isAbstract()from the filter ingetClassNames()so abstract classes from class-string types are included in constructor validation$isFromClassStringflag (third element in the return tuple) to distinguish class-string-resolved names from constant string or direct namesFoo::class), so those still correctly report "abstract class" errors via the existing path$isFromClassStringflag incheckClassName()to suppress the "Instantiated class X is abstract" error for class-string-resolved typestests/PHPStan/Rules/Classes/InstantiationRuleTest.php:testBug14102()regression testtestClassString()to expect constructor parameter errors for abstract class Btests/PHPStan/Rules/Classes/data/bug-14102.phptest dataRoot cause
In
InstantiationRule::getClassNames(), abstract classes were explicitly filtered out when resolving class-string types. This was overly conservative — while you can't directly instantiate an abstract class,class-string<AbstractClass>represents concrete subclasses that inherit the abstract class's constructor signature. The constructor parameters should still be validated.The fix includes abstract classes in the class-string resolution but introduces a
$isFromClassStringflag to prevent false "Instantiated class X is abstract" errors. Constant string types (Foo::class) are excluded from the class-string path so they continue to correctly report abstract instantiation errors.Test
Added
tests/PHPStan/Rules/Classes/data/bug-14102.phpwhich reproduces the exact scenario from the issue: an abstract classHelloWorldwith a 2-parameter constructor, and a factory method acceptingclass-string<HelloWorld>that callsnew $className()with 0 parameters. The test expects the error "Class Bug14102\HelloWorld constructor invoked with 0 parameters, 2 required."Fixes phpstan/phpstan#14102