Skip to content

Commit 45d8715

Browse files
committed
More precise implode() return type
1 parent 2132cc0 commit 45d8715

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

src/Type/Php/ImplodeFunctionReturnTypeExtension.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,23 @@ private function implode(Type $arrayType, Type $separatorType): Type
8080
}
8181

8282
$accessoryTypes = [];
83+
$valueTypeAsString = $arrayType->getIterableValueType()->toString();
8384
if ($arrayType->isIterableAtLeastOnce()->yes()) {
84-
if ($arrayType->getIterableValueType()->isNonFalsyString()->yes() || $separatorType->isNonFalsyString()->yes()) {
85+
if ($valueTypeAsString->isNonFalsyString()->yes() || $separatorType->isNonFalsyString()->yes()) {
8586
$accessoryTypes[] = new AccessoryNonFalsyStringType();
86-
} elseif ($arrayType->getIterableValueType()->isNonEmptyString()->yes() || $separatorType->isNonEmptyString()->yes()) {
87+
} elseif ($valueTypeAsString->isNonEmptyString()->yes() || $separatorType->isNonEmptyString()->yes()) {
8788
$accessoryTypes[] = new AccessoryNonEmptyStringType();
8889
}
8990
}
9091

9192
// implode is one of the four functions that can produce literal strings as blessed by the original RFC: wiki.php.net/rfc/is_literal
92-
if ($arrayType->getIterableValueType()->isLiteralString()->yes() && $separatorType->isLiteralString()->yes()) {
93+
if ($valueTypeAsString->isLiteralString()->yes() && $separatorType->isLiteralString()->yes()) {
9394
$accessoryTypes[] = new AccessoryLiteralStringType();
9495
}
95-
if ($arrayType->getIterableValueType()->isLowercaseString()->yes() && $separatorType->isLowercaseString()->yes()) {
96+
if ($valueTypeAsString->isLowercaseString()->yes() && $separatorType->isLowercaseString()->yes()) {
9697
$accessoryTypes[] = new AccessoryLowercaseStringType();
9798
}
98-
if ($arrayType->getIterableValueType()->isUppercaseString()->yes() && $separatorType->isUppercaseString()->yes()) {
99+
if ($valueTypeAsString->isUppercaseString()->yes() && $separatorType->isUppercaseString()->yes()) {
99100
$accessoryTypes[] = new AccessoryUppercaseStringType();
100101
}
101102

tests/PHPStan/Analyser/nsrt/bug-11201.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function returnsBool(): bool {
4141
assertType('string', $s);
4242

4343
$s = sprintf("%s", implode(', ', array_map('intval', returnsArray())));
44-
assertType('string', $s);
44+
assertType('lowercase-string&uppercase-string', $s);
4545

4646
$s = sprintf('%2$s', 1234, returnsNonFalsyString());
4747
assertType('non-falsy-string', $s);

tests/PHPStan/Analyser/nsrt/implode.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66

77
class Foo
88
{
9+
/**
10+
* @param array<int> $arr
11+
*/
12+
public function ints(array $arr, int $i)
13+
{
14+
assertType("lowercase-string&uppercase-string", implode($arr));
15+
assertType("lowercase-string&non-empty-string&uppercase-string", implode([$i, $i]));
16+
if ($i !== 0) {
17+
assertType("lowercase-string&non-falsy-string&uppercase-string", implode([$i, $i]));
18+
}
19+
}
20+
921
const X = 'x';
1022
const ONE = 1;
1123

tests/PHPStan/Analyser/nsrt/non-empty-string.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public function sayHello(int $i): void
212212
// coming from issue #5291
213213
$s = array(1, $i);
214214

215-
assertType('non-falsy-string', implode("a", $s));
215+
assertType('lowercase-string&non-falsy-string', implode("a", $s));
216216
}
217217

218218
/**
@@ -233,7 +233,7 @@ public function sayHello2(int $i): void
233233
// coming from issue #5291
234234
$s = array(1, $i);
235235

236-
assertType('non-falsy-string', join("a", $s));
236+
assertType('lowercase-string&non-falsy-string', join("a", $s));
237237
}
238238

239239
/**

0 commit comments

Comments
 (0)