Skip to content

Commit cc56ab5

Browse files
committed
Merge branch 2.1.x into 2.2.x
2 parents ecfa016 + e905481 commit cc56ab5

File tree

3 files changed

+56
-12
lines changed

3 files changed

+56
-12
lines changed

src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.php

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,15 @@ public function specifyTypes(
7777
if ($context->true()) {
7878
$specifiedTypes = new SpecifiedTypes();
7979

80-
if (count($keyType->getConstantScalarTypes()) <= 1) {
81-
$nonEmptyType = $arrayType->isArray()->yes()
82-
? new NonEmptyArrayType()
83-
: TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new NonEmptyArrayType());
84-
$specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create(
85-
$array,
86-
$nonEmptyType,
87-
$context,
88-
$scope,
89-
));
90-
}
80+
$nonEmptyType = $arrayType->isArray()->yes()
81+
? new NonEmptyArrayType()
82+
: TypeCombinator::intersect(new ArrayType(new MixedType(), new MixedType()), new NonEmptyArrayType());
83+
$specifiedTypes = $specifiedTypes->unionWith($this->typeSpecifier->create(
84+
$array,
85+
$nonEmptyType,
86+
$context,
87+
$scope,
88+
));
9189

9290
if ($arrayType->isIterableAtLeastOnce()->no()) {
9391
return $specifiedTypes;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug14489;
4+
5+
use function array_key_exists;
6+
use function array_merge;
7+
use function array_unique;
8+
use function array_values;
9+
use function PHPStan\Testing\assertType;
10+
11+
function () {
12+
$data = [['c1' => [1], 'c2' => [4]]];
13+
14+
$cData = [];
15+
foreach ($data as $cMap) {
16+
foreach ($cMap as $c => $ids) {
17+
if (array_key_exists($c, $cData)) {
18+
$cData[$c] = array_unique(array_merge($cData[$c], $ids));
19+
} else {
20+
$cData[$c] = $ids;
21+
}
22+
}
23+
}
24+
25+
$values = array_values($cData);
26+
assertType('non-empty-list<non-empty-array<0|1, 1|4>>', $values);
27+
};
28+
29+
function () {
30+
/** @var 'c1'|'c2' $c */
31+
$c = 'c1';
32+
/** @var array{1}|array{4} $ids */
33+
$ids = [1];
34+
35+
$cData = [];
36+
while (rand(0, 1)) {
37+
if (array_key_exists($c, $cData)) {
38+
assertType('non-empty-array<\'c1\'|\'c2\', array{1}|array{4}>', $cData);
39+
assertType('array{1}|array{4}', $cData[$c]);
40+
$cData[$c] = $cData[$c];
41+
} else {
42+
$cData[$c] = $ids;
43+
}
44+
}
45+
assertType('array<\'c1\'|\'c2\', array{1}|array{4}>', $cData);
46+
};

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ public function testBug7000b(): void
419419
{
420420
$this->analyse([__DIR__ . '/data/bug-7000b.php'], [
421421
[
422-
"Offset 'require'|'require-dev' might not exist on array{require?: array<string, string>, require-dev?: array<string, string>}.",
422+
"Offset 'require'|'require-dev' might not exist on non-empty-array{require?: array<string, string>, require-dev?: array<string, string>}.",
423423
16,
424424
],
425425
]);

0 commit comments

Comments
 (0)