diff --git a/src/Type/Php/StrRepeatFunctionReturnTypeExtension.php b/src/Type/Php/StrRepeatFunctionReturnTypeExtension.php index 793adbffe7..cc8a09a3cd 100644 --- a/src/Type/Php/StrRepeatFunctionReturnTypeExtension.php +++ b/src/Type/Php/StrRepeatFunctionReturnTypeExtension.php @@ -12,9 +12,11 @@ use PHPStan\Type\DynamicFunctionReturnTypeExtension; use PHPStan\Type\IntegerRangeType; use PHPStan\Type\IntersectionType; +use PHPStan\Type\NeverType; use PHPStan\Type\StringType; use PHPStan\Type\Type; use function count; +use function str_repeat; class StrRepeatFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension { @@ -42,6 +44,14 @@ public function getTypeFromFunctionCall( return new ConstantStringType(''); } + if ($multiplierType instanceof ConstantIntegerType && $multiplierType->getValue() < 0) { + return new NeverType(); + } + + if ($inputType instanceof ConstantStringType && $multiplierType instanceof ConstantIntegerType) { + return new ConstantStringType(str_repeat($inputType->getValue(), $multiplierType->getValue())); + } + $accessoryTypes = []; if ($inputType->isNonEmptyString()->yes()) { if (IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($multiplierType)->yes()) { diff --git a/tests/PHPStan/Analyser/data/literal-string.php b/tests/PHPStan/Analyser/data/literal-string.php index 28fce66175..c55c34feff 100644 --- a/tests/PHPStan/Analyser/data/literal-string.php +++ b/tests/PHPStan/Analyser/data/literal-string.php @@ -25,8 +25,10 @@ public function doFoo($literalString, string $string) assertType('string', str_repeat($string, 10)); assertType('literal-string', str_repeat($literalString, 10)); - assertType('literal-string', str_repeat('', 10)); - assertType('literal-string&non-empty-string', str_repeat('foo', 10)); + assertType("''", str_repeat('', 10)); + assertType("'foofoofoofoofoofoofoofoofoofoo'", str_repeat('foo', 10)); + assertType("'?,?,?,'", str_repeat('?,', 3)); + assertType("*NEVER*", str_repeat('?,', -3)); assertType('non-empty-string', str_pad($string, 5, $string)); assertType('non-empty-string', str_pad($literalString, 5, $string));