diff --git a/build/phpstan.neon b/build/phpstan.neon index 526f68798d2..7e94e384063 100644 --- a/build/phpstan.neon +++ b/build/phpstan.neon @@ -108,11 +108,11 @@ parameters: message: '#^Variable property access on T of PHPStan\\Rules\\RuleError\.$#' path: ../src/Rules/RuleErrorBuilder.php - - message: "#^Parameter \\#1 (?:\\$argument|\\$objectOrClass) of class ReflectionClass constructor expects class\\-string\\\\|PHPStan\\\\ExtensionInstaller\\\\GeneratedConfig, string given\\.$#" + message: "#^Parameter \\#1 (?:\\$argument|\\$objectOrClass) of class ReflectionClass constructor expects class\\-string\\\\|PHPStan\\\\ExtensionInstaller\\\\GeneratedConfig, 'PHPStan…' given\\.$#" count: 1 path: ../src/Command/CommandHelper.php - - message: "#^Parameter \\#1 (?:\\$argument|\\$objectOrClass) of class ReflectionClass constructor expects class\\-string\\\\|PHPStan\\\\ExtensionInstaller\\\\GeneratedConfig, string given\\.$#" + message: "#^Parameter \\#1 (?:\\$argument|\\$objectOrClass) of class ReflectionClass constructor expects class\\-string\\\\|PHPStan\\\\ExtensionInstaller\\\\GeneratedConfig, 'PHPStan…' given\\.$#" count: 1 path: ../src/Diagnose/PHPStanDiagnoseExtension.php - identifier: ternary.shortNotAllowed diff --git a/src/Type/VerbosityLevel.php b/src/Type/VerbosityLevel.php index 32be9683a81..7cd72a1d32f 100644 --- a/src/Type/VerbosityLevel.php +++ b/src/Type/VerbosityLevel.php @@ -174,6 +174,10 @@ public static function getRecommendedLevelByType(Type $acceptingType, ?Type $acc $moreVerbose = true; return $type; } + if ($type->isString()->yes() && $type->isClassString()->yes()) { + $moreVerbose = true; + return $type; + } return $traverse($type); }; diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index 60b40422305..36f8ce54a75 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -1161,7 +1161,7 @@ public function testBug4413(): void require_once __DIR__ . '/data/bug-4413.php'; $this->analyse([__DIR__ . '/data/bug-4413.php'], [ [ - 'Parameter #1 $date of function Bug4413\takesDate expects class-string, string given.', + 'Parameter #1 $date of function Bug4413\takesDate expects class-string, \'stdClass\' given.', 18, ], ]); diff --git a/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php b/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php index 7aca3e79a0b..fcde4582f19 100644 --- a/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php +++ b/tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php @@ -507,7 +507,7 @@ public function testCallMethods(): void 1461, ], [ - 'Parameter #1 $s of method Test\ClassStringWithUpperBounds::doFoo() expects class-string, string given.', + 'Parameter #1 $s of method Test\ClassStringWithUpperBounds::doFoo() expects class-string, \'Throwable\' given.', 1490, ], [ @@ -834,7 +834,7 @@ public function testCallMethodsOnThisOnly(): void 1379, ], [ - 'Parameter #1 $s of method Test\ClassStringWithUpperBounds::doFoo() expects class-string, string given.', + 'Parameter #1 $s of method Test\ClassStringWithUpperBounds::doFoo() expects class-string, \'Throwable\' given.', 1490, ], [ diff --git a/tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php b/tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php index d7dc2805345..67ad92622be 100644 --- a/tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php +++ b/tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php @@ -454,11 +454,11 @@ public function testBug4550(): void $this->checkThisOnly = false; $this->analyse([__DIR__ . '/data/bug-4550.php'], [ [ - 'Parameter #1 $class of static method Bug4550\Test::valuesOf() expects class-string, string given.', + "Parameter #1 \$class of static method Bug4550\Test::valuesOf() expects class-string, 'Person' given.", 34, ], [ - 'Parameter #1 $class of static method Bug4550\Test::valuesOf() expects class-string, string given.', + "Parameter #1 \$class of static method Bug4550\Test::valuesOf() expects class-string, 'Person' given.", 44, ], ]); @@ -579,7 +579,7 @@ public function testTemplateTypeInOneBranchOfConditional(): void [ 'Parameter #1 $params of static method TemplateTypeInOneBranchOfConditional\DriverManager::getConnection() expects array{wrapperClass?: class-string}, array{wrapperClass: \'stdClass\'} given.', 27, - "Offset 'wrapperClass' (class-string) does not accept type string.", + "Offset 'wrapperClass' (class-string) does not accept type 'stdClass'.", ], [ 'Unable to resolve the template type T in call to static method TemplateTypeInOneBranchOfConditional\DriverManager::getConnection()', diff --git a/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php b/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php index 1f3465af5d8..4ced8dcb0e1 100644 --- a/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php +++ b/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php @@ -1331,4 +1331,18 @@ public function testBug11430(): void $this->analyse([__DIR__ . '/../../Analyser/nsrt/bug-11430.php'], []); } + public function testBug14440(): void + { + $this->analyse([__DIR__ . '/data/bug-14440.php'], [ + [ + 'Method Bug14440\ChildOne::getCounterpartClass() should return class-string but returns \'Bug14440\\\\ChildTwo\'.', + 18, + ], + [ + 'Method Bug14440\ChildTwo::getCounterpartClass() should return class-string but returns \'Bug14440\\\\ChildOne\'.', + 27, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Methods/data/bug-14440.php b/tests/PHPStan/Rules/Methods/data/bug-14440.php new file mode 100644 index 00000000000..7bf699ded15 --- /dev/null +++ b/tests/PHPStan/Rules/Methods/data/bug-14440.php @@ -0,0 +1,29 @@ + */ + abstract public static function getCounterpartClass(): string; +} + +final class ChildOne extends A implements I +{ + #[\Override] + public static function getCounterpartClass(): string + { + return ChildTwo::class; + } +} + +final class ChildTwo extends A implements I +{ + #[\Override] + public static function getCounterpartClass(): string + { + return ChildOne::class; + } +}