Skip to content

Commit 55c8a14

Browse files
committed
Fixed assigning to arrays with optional keys
1 parent a5beb06 commit 55c8a14

3 files changed

Lines changed: 41 additions & 0 deletions

File tree

src/Type/Constant/ConstantArrayTypeBuilder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Type\ArrayType;
66
use PHPStan\Type\Type;
77
use PHPStan\Type\TypeCombinator;
8+
use function array_filter;
89

910
class ConstantArrayTypeBuilder
1011
{
@@ -74,6 +75,9 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
7475
foreach ($this->keyTypes as $i => $keyType) {
7576
if ($keyType->getValue() === $offsetType->getValue()) {
7677
$this->valueTypes[$i] = $valueType;
78+
$this->optionalKeys = array_values(array_filter($this->optionalKeys, static function (int $index) use ($i): bool {
79+
return $index !== $i;
80+
}));
7781
return;
7882
}
7983
}

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9894,6 +9894,14 @@ public function dataAssignNestedArray(): array
98949894
return $this->gatherAssertTypes(__DIR__ . '/data/assign-nested-arrays.php');
98959895
}
98969896

9897+
public function dataBug3276(): array
9898+
{
9899+
if (PHP_VERSION_ID < 70400) {
9900+
$this->markTestSkipped('Test requires PHP 7.4.');
9901+
}
9902+
return $this->gatherAssertTypes(__DIR__ . '/data/bug-3276.php');
9903+
}
9904+
98979905
/**
98989906
* @dataProvider dataBug2574
98999907
* @dataProvider dataBug2577
@@ -9941,6 +9949,7 @@ public function dataAssignNestedArray(): array
99419949
* @dataProvider dataBug3266
99429950
* @dataProvider dataBug3269
99439951
* @dataProvider dataAssignNestedArray
9952+
* @dataProvider dataBug3276
99449953
* @param ConstantStringType $expectedType
99459954
* @param Type $actualType
99469955
*/
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php // lint >= 7.4
2+
3+
namespace Bug3276;
4+
5+
use function PHPStan\Analyser\assertType;
6+
7+
class Foo
8+
{
9+
10+
/**
11+
* @param array{name?:string} $settings
12+
*/
13+
public function doFoo(array $settings): void
14+
{
15+
$settings['name'] ??= 'unknown';
16+
assertType('array(\'name\' => string)', $settings);
17+
}
18+
19+
/**
20+
* @param array{name?:string} $settings
21+
*/
22+
public function doBar(array $settings): void
23+
{
24+
$settings['name'] = 'unknown';
25+
assertType('array(\'name\' => \'unknown\')', $settings);
26+
}
27+
28+
}

0 commit comments

Comments
 (0)