From 36406a9f44fc699de33c28a084c397f848d5e295 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 21 Jan 2025 17:07:10 +0100 Subject: [PATCH 1/2] Traverse typewhen we can contain lowercase/upercase strings --- src/Type/VerbosityLevel.php | 10 +++++++++- .../PhpDoc/WrongVariableNameInVarTagRuleTest.php | 13 +++++++++++++ tests/PHPStan/Rules/PhpDoc/data/bug-12457.php | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/PhpDoc/data/bug-12457.php diff --git a/src/Type/VerbosityLevel.php b/src/Type/VerbosityLevel.php index 988b2a2405..ec733df635 100644 --- a/src/Type/VerbosityLevel.php +++ b/src/Type/VerbosityLevel.php @@ -91,10 +91,18 @@ public static function getRecommendedLevelByType(Type $acceptingType, ?Type $acc $moreVerboseCallback = static function (Type $type, callable $traverse) use (&$moreVerbose, &$veryVerbose): Type { if ($type->isCallable()->yes()) { $moreVerbose = true; - return $type; + + // Keep checking if we need to be very verbose. + return $traverse($type); } if ($type->isConstantValue()->yes() && $type->isNull()->no()) { $moreVerbose = true; + + // For ConstantArrayType we need to keep checking if we need to be very verbose. + if (!$type->isArray()->no()) { + return $traverse($type); + } + return $type; } if ( diff --git a/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php b/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php index 6083de943d..44a9984ef9 100644 --- a/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php +++ b/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php @@ -511,4 +511,17 @@ public function testReportWrongType( $this->analyse([__DIR__ . '/data/wrong-var-native-type.php'], $expectedErrors); } + public function testBug12457(): void + { + $this->checkTypeAgainstNativeType = true; + $this->checkTypeAgainstPhpDocType = true; + $this->strictWideningCheck = true; + $this->analyse([__DIR__ . '/data/bug-12457.php'], [ + [ + 'PHPDoc tag @var with type array{numeric-string} is not subtype of type array{lowercase-string&numeric-string&uppercase-string}.', + 13, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php b/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php new file mode 100644 index 0000000000..3ea0e82f03 --- /dev/null +++ b/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php @@ -0,0 +1,15 @@ + Date: Tue, 21 Jan 2025 17:45:00 +0100 Subject: [PATCH 2/2] Add test --- .../Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php | 4 ++++ tests/PHPStan/Rules/PhpDoc/data/bug-12457.php | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php b/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php index 44a9984ef9..e25e8df924 100644 --- a/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php +++ b/tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php @@ -521,6 +521,10 @@ public function testBug12457(): void 'PHPDoc tag @var with type array{numeric-string} is not subtype of type array{lowercase-string&numeric-string&uppercase-string}.', 13, ], + [ + 'PHPDoc tag @var with type callable(): string is not subtype of type callable(): numeric-string&lowercase-string&uppercase-string.', + 22, + ], ]); } diff --git a/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php b/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php index 3ea0e82f03..2d1564036f 100644 --- a/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php +++ b/tests/PHPStan/Rules/PhpDoc/data/bug-12457.php @@ -12,4 +12,13 @@ public function sayHello(array $a): void /** @var array{numeric-string} $b */ $b = $a; } + + /** + * @param callable(): numeric-string&uppercase-string&lowercase-string $a + */ + public function sayHello2(callable $a): void + { + /** @var callable(): string $b */ + $b = $a; + } }