Skip to content

Commit fb08fb5

Browse files
herndlmondrejmirtes
authored andcommitted
Fix checking empty constant arrays in array_pop and array_shift extensions
1 parent 52b7bec commit fb08fb5

File tree

6 files changed

+48
-4
lines changed

6 files changed

+48
-4
lines changed

src/Type/Php/ArrayPopFunctionReturnTypeExtension.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
3737
if (count($constantArrays) > 0) {
3838
$valueTypes = [];
3939
foreach ($constantArrays as $constantArray) {
40-
$arrayKeyTypes = $constantArray->getKeyTypes();
41-
if (count($arrayKeyTypes) === 0) {
40+
$iterableAtLeastOnce = $constantArray->isIterableAtLeastOnce();
41+
if (!$iterableAtLeastOnce->yes()) {
4242
$valueTypes[] = new NullType();
43+
}
44+
if ($iterableAtLeastOnce->no()) {
4345
continue;
4446
}
4547
$valueTypes[] = $constantArray->getLastValueType();

src/Type/Php/ArrayShiftFunctionReturnTypeExtension.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
3737
if (count($constantArrays) > 0) {
3838
$valueTypes = [];
3939
foreach ($constantArrays as $constantArray) {
40-
$arrayKeyTypes = $constantArray->getKeyTypes();
41-
if (count($arrayKeyTypes) === 0) {
40+
$iterableAtLeastOnce = $constantArray->isIterableAtLeastOnce();
41+
if (!$iterableAtLeastOnce->yes()) {
4242
$valueTypes[] = new NullType();
43+
}
44+
if ($iterableAtLeastOnce->no()) {
4345
continue;
4446
}
4547

tests/PHPStan/Analyser/data/array-pop.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ public function constantArraysWithOptionalKeys(array $arr): void
4848
/** @var array{a: 0, b: 1, c?: 2} $arr */
4949
assertType('1|2', array_pop($arr));
5050
assertType('array{a: 0, b?: 1}', $arr);
51+
52+
/** @var array{a?: 0, b?: 1, c?: 2} $arr */
53+
assertType('0|1|2|null', array_pop($arr));
54+
assertType('array{a?: 0, b?: 1}', $arr);
5155
}
5256

5357
}

tests/PHPStan/Analyser/data/array-shift.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ public function constantArraysWithOptionalKeys(array $arr): void
4848
/** @var array{a: 0, b: 1, c?: 2} $arr */
4949
assertType('0', array_shift($arr));
5050
assertType('array{b: 1, c?: 2}', $arr);
51+
52+
/** @var array{a?: 0, b?: 1, c?: 2} $arr */
53+
assertType('0|1|2|null', array_shift($arr));
54+
assertType('array{b?: 1, c?: 2}', $arr);
5155
}
5256

5357
}

tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,12 @@ public function testBug7318(): void
352352
]);
353353
}
354354

355+
public function testBug7968(): void
356+
{
357+
$this->treatPhpDocTypesAsCertain = true;
358+
$this->strictUnnecessaryNullsafePropertyFetch = true;
359+
360+
$this->analyse([__DIR__ . '/data/bug-7968.php'], []);
361+
}
362+
355363
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug7968;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @param array{name: string, age: int} $a
9+
* @param array{name: string, age: int} $b
10+
*/
11+
public function compare(array $a, array $b): int
12+
{
13+
$sort = [
14+
$a['name'] <=> $b['name'],
15+
$a['age'] <=> $b['age'],
16+
];
17+
18+
$sort = array_filter($sort, function (int $value): bool {
19+
return $value !== 0;
20+
});
21+
22+
return array_shift($sort) ?? 0;
23+
}
24+
}

0 commit comments

Comments
 (0)