Skip to content

Commit 0938424

Browse files
authored
Spreading of general arrays should not lead to a non-empty-array
1 parent fc1c685 commit 0938424

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

src/Analyser/MutatingScope.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1774,7 +1774,7 @@ private function resolveType(Expr $node): Type
17741774
}
17751775
} else {
17761776
$arrayBuilder->degradeToGeneralArray();
1777-
$arrayBuilder->setOffsetValueType(new IntegerType(), $valueType->getIterableValueType());
1777+
$arrayBuilder->setOffsetValueType(new IntegerType(), $valueType->getIterableValueType(), !$valueType->isIterableAtLeastOnce()->yes() && !$valueType->getIterableValueType()->isIterableAtLeastOnce()->yes());
17781778
}
17791779
} else {
17801780
$arrayBuilder->setOffsetValueType(

src/Type/Constant/ConstantArrayTypeBuilder.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
105105

106106
$this->keyTypes[] = TypeUtils::generalizeType($offsetType, GeneralizePrecision::moreSpecific());
107107
$this->valueTypes[] = $valueType;
108+
if ($optional) {
109+
$this->optionalKeys[] = count($this->keyTypes) - 1;
110+
}
108111
$this->degradeToGeneralArray = true;
109112
}
110113

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ public function dataFileAsserts(): iterable
533533
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5017.php');
534534
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5992.php');
535535
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6001.php');
536+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5287.php');
536537

537538
if (PHP_VERSION_ID >= 70400) {
538539
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5458.php');
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Bug5287;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @param list<mixed> $arr
9+
*/
10+
function foo(array $arr): void
11+
{
12+
$arrSpread = [...$arr];
13+
assertType('array<int, mixed>', $arrSpread);
14+
}
15+
16+
/**
17+
* @param list<non-empty-array> $arr
18+
*/
19+
function foo2(array $arr): void
20+
{
21+
$arrSpread = [...$arr];
22+
assertType('non-empty-array<int, non-empty-array>', $arrSpread);
23+
}
24+
25+
/**
26+
* @param non-empty-list<string> $arr
27+
*/
28+
function foo3(array $arr): void
29+
{
30+
$arrSpread = [...$arr];
31+
assertType('non-empty-array<int, string>', $arrSpread);
32+
}
33+
34+
/**
35+
* @param non-empty-array<string, int> $arr
36+
*/
37+
function foo3(array $arr): void
38+
{
39+
$arrSpread = [...$arr];
40+
assertType('non-empty-array<int, int>', $arrSpread);
41+
}
42+
43+
/**
44+
* @param non-empty-array<mixed, bool|int> $arr
45+
*/
46+
function foo4(array $arr): void
47+
{
48+
$arrSpread = [...$arr];
49+
assertType('non-empty-array<int, bool|int>', $arrSpread);
50+
}
51+
52+
/**
53+
* @param array{foo: 17, bar: 19} $arr
54+
*/
55+
function bar(array $arr): void
56+
{
57+
$arrSpread = [...$arr];
58+
assertType('array{17, 19}', $arrSpread);
59+
}

0 commit comments

Comments
 (0)