Skip to content

Commit 6b7f67d

Browse files
Improve
1 parent a95e598 commit 6b7f67d

File tree

2 files changed

+78
-4
lines changed

2 files changed

+78
-4
lines changed

src/Type/UnionType.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use PHPStan\TrinaryLogic;
2626
use PHPStan\Type\Enum\EnumCaseObjectType;
2727
use PHPStan\Type\Generic\GenericClassStringType;
28+
use PHPStan\Type\Generic\GenericObjectType;
2829
use PHPStan\Type\Generic\TemplateIterableType;
2930
use PHPStan\Type\Generic\TemplateMixedType;
3031
use PHPStan\Type\Generic\TemplateType;
@@ -33,6 +34,7 @@
3334
use PHPStan\Type\Generic\TemplateUnionType;
3435
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
3536
use Throwable;
37+
use Traversable;
3638
use function array_diff_assoc;
3739
use function array_fill_keys;
3840
use function array_map;
@@ -194,6 +196,16 @@ public function getConstantStrings(): array
194196

195197
public function accepts(Type $type, bool $strictTypes): AcceptsResult
196198
{
199+
if ($type instanceof IterableType) {
200+
return $this->accepts(new UnionType([
201+
new ArrayType($type->getIterableKeyType(), $type->getIterableValueType()),
202+
new GenericObjectType(Traversable::class, [
203+
$type->getIterableKeyType(),
204+
$type->getIterableValueType(),
205+
]),
206+
]), $strictTypes);
207+
}
208+
197209
foreach (self::EQUAL_UNION_CLASSES as $baseClass => $classes) {
198210
if (!$type->equals(new ObjectType($baseClass))) {
199211
continue;
@@ -1073,6 +1085,16 @@ public function toCoercedArgumentType(bool $strictTypes): Type
10731085

10741086
public function inferTemplateTypes(Type $receivedType): TemplateTypeMap
10751087
{
1088+
if ($receivedType instanceof IterableType) {
1089+
$receivedType = new UnionType([
1090+
new ArrayType($receivedType->getIterableKeyType(), $receivedType->getIterableValueType()),
1091+
new GenericObjectType(Traversable::class, [
1092+
$receivedType->getIterableKeyType(),
1093+
$receivedType->getIterableValueType(),
1094+
]),
1095+
]);
1096+
}
1097+
10761098
$types = TemplateTypeMap::createEmpty();
10771099
if ($receivedType instanceof UnionType) {
10781100
$myTypes = [];

tests/PHPStan/Rules/Functions/data/bug-13247.php

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,24 @@
77
use Traversable;
88

99
/**
10-
* @param array<int, int>|Traversable<int, int> $input
10+
* @template K as array-key
11+
* @template V
1112
*
12-
* @return array<int, int>
13+
* @param array<K, V>|Traversable<K, V> $input
14+
*
15+
* @return array<K, V>
1316
*/
1417
function as_array(array|Traversable $input): array {
1518
return iter_as_array($input);
1619
}
1720

1821
/**
19-
* @param iterable<int, int> $input
22+
* @template K as array-key
23+
* @template V
2024
*
21-
* @return array<int, int>
25+
* @param iterable<K, V> $input
26+
*
27+
* @return array<K, V>
2228
*/
2329
function iter_as_array(iterable $input): array {
2430
return as_array($input);
@@ -41,3 +47,49 @@ function as_array2(array|Traversable $input): array {
4147
function iter_as_array2(iterable $input): array {
4248
return as_array2($input);
4349
}
50+
51+
/**
52+
* @param array<int, int>|Traversable<int, int> $input
53+
*
54+
* @return array<int, int>
55+
*/
56+
function as_array3(array|Traversable $input): array {
57+
return iter_as_array3($input);
58+
}
59+
60+
/**
61+
* @param iterable<int, int> $input
62+
*
63+
* @return array<int, int>
64+
*/
65+
function iter_as_array3(iterable $input): array {
66+
return as_array3($input);
67+
}
68+
69+
/**
70+
* @phpstan-template T of iterable<int, int>
71+
*
72+
* @param T $input
73+
*
74+
* @return mixed
75+
*/
76+
function test1(iterable $input) {
77+
test2($input);
78+
iter_as_array($input);
79+
80+
return as_array($input);
81+
}
82+
83+
/**
84+
* @phpstan-template U of Traversable<int, int>|array<int, int>
85+
*
86+
* @param U $input
87+
*
88+
* @return mixed
89+
*/
90+
function test2($input) {
91+
test1($input);
92+
iter_as_array($input);
93+
94+
return as_array($input);
95+
}

0 commit comments

Comments
 (0)