From 505ed737582493771b892159931c2cc0c70e5a86 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 25 Apr 2025 15:23:48 +0200 Subject: [PATCH 1/2] More precise string functions return type with replacement array --- ...aceFunctionsDynamicReturnTypeExtension.php | 3 + .../Rules/Methods/ReturnTypeRuleTest.php | 10 +++ .../PHPStan/Rules/Methods/data/bug-12928.php | 68 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 tests/PHPStan/Rules/Methods/data/bug-12928.php diff --git a/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php b/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php index db046bbe10..01bb1dd29e 100644 --- a/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php +++ b/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php @@ -89,6 +89,9 @@ private function getPreliminarilyResolvedTypeFromFunctionCall( if (count($functionCall->getArgs()) > $replaceArgumentPosition) { $replaceArgumentType = $scope->getType($functionCall->getArgs()[$replaceArgumentPosition]->value); + if ($replaceArgumentType->isArray()->yes()) { + $replaceArgumentType = $replaceArgumentType->getIterableValueType(); + } $accessories = []; if ($subjectArgumentType->isNonFalsyString()->yes() && $replaceArgumentType->isNonFalsyString()->yes()) { diff --git a/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php b/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php index bc3a1b1fae..548589722e 100644 --- a/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php +++ b/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php @@ -1246,4 +1246,14 @@ public function testBug4443(): void ]); } + public function testBug12928(): void + { + $this->analyse([__DIR__ . '/data/bug-12928.php'], [ + [ + 'Method Bug12928\FooBarBaz::render() should return non-empty-string but returns string.', + 59, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Methods/data/bug-12928.php b/tests/PHPStan/Rules/Methods/data/bug-12928.php new file mode 100644 index 0000000000..e8d50fd193 --- /dev/null +++ b/tests/PHPStan/Rules/Methods/data/bug-12928.php @@ -0,0 +1,68 @@ + $replace + * + * @return non-falsy-string + */ + public function render(string $phptFile, string $code, array $replace): string + { + return str_replace( + [ + '__DIR__', + '__FILE__', + ], + $replace, + $code, + ); + } +} + + +class FooBarBaz { + /** + * @param non-empty-string $phptFile + * @param non-empty-string $code + * + * @return non-empty-string + */ + public function render(string $phptFile, string $code, array $replace): string + { + return str_replace( + [ + '__DIR__', + '__FILE__', + ], + $replace, + $code, + ); + } +} From 61daba9e61af3ffe0873b44a740548fc85d937ef Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 25 Apr 2025 15:31:35 +0200 Subject: [PATCH 2/2] remove dead parameter --- tests/PHPStan/Rules/Methods/data/bug-12928.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PHPStan/Rules/Methods/data/bug-12928.php b/tests/PHPStan/Rules/Methods/data/bug-12928.php index e8d50fd193..2b6e038fe9 100644 --- a/tests/PHPStan/Rules/Methods/data/bug-12928.php +++ b/tests/PHPStan/Rules/Methods/data/bug-12928.php @@ -33,7 +33,7 @@ class FooBar { * * @return non-falsy-string */ - public function render(string $phptFile, string $code, array $replace): string + public function render(string $code, array $replace): string { return str_replace( [ @@ -54,7 +54,7 @@ class FooBarBaz { * * @return non-empty-string */ - public function render(string $phptFile, string $code, array $replace): string + public function render(string $code, array $replace): string { return str_replace( [