Skip to content

Commit e3040bb

Browse files
authored
Skip deep expression when root expression changes while scope generalization
1 parent d5f3f7e commit e3040bb

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

src/Analyser/MutatingScope.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
use function strlen;
169169
use function strtolower;
170170
use function substr;
171+
use function uksort;
171172
use function usort;
172173
use const PHP_INT_MAX;
173174
use const PHP_INT_MIN;
@@ -5296,19 +5297,37 @@ private function generalizeVariableTypeHolders(
52965297
array $otherVariableTypeHolders,
52975298
): array
52985299
{
5300+
uksort($variableTypeHolders, static fn (string $exprA, string $exprB): int => strlen($exprA) <=> strlen($exprB));
5301+
5302+
$generalizedExpressions = [];
5303+
$newVariableTypeHolders = [];
52995304
foreach ($variableTypeHolders as $variableExprString => $variableTypeHolder) {
5305+
foreach ($generalizedExpressions as $generalizedExprString => $generalizedExpr) {
5306+
if (!$this->shouldInvalidateExpression($generalizedExprString, $generalizedExpr, $variableTypeHolder->getExpr())) {
5307+
continue;
5308+
}
5309+
5310+
continue 2;
5311+
}
53005312
if (!isset($otherVariableTypeHolders[$variableExprString])) {
5313+
$newVariableTypeHolders[$variableExprString] = $variableTypeHolder;
53015314
continue;
53025315
}
53035316

5304-
$variableTypeHolders[$variableExprString] = new ExpressionTypeHolder(
5317+
$generalizedType = $this->generalizeType($variableTypeHolder->getType(), $otherVariableTypeHolders[$variableExprString]->getType(), 0);
5318+
if (
5319+
!$generalizedType->equals($variableTypeHolder->getType())
5320+
) {
5321+
$generalizedExpressions[$variableExprString] = $variableTypeHolder->getExpr();
5322+
}
5323+
$newVariableTypeHolders[$variableExprString] = new ExpressionTypeHolder(
53055324
$variableTypeHolder->getExpr(),
5306-
$this->generalizeType($variableTypeHolder->getType(), $otherVariableTypeHolders[$variableExprString]->getType(), 0),
5325+
$generalizedType,
53075326
$variableTypeHolder->getCertainty(),
53085327
);
53095328
}
53105329

5311-
return $variableTypeHolders;
5330+
return $newVariableTypeHolders;
53125331
}
53135332

53145333
private function generalizeType(Type $a, Type $b, int $depth): Type
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace PR4390;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function (string $s): void {
8+
$locations = [];
9+
for ($i = 0; $i < 10; $i++) {
10+
$locations[$i] = [];
11+
for ($j = 0; $j < 10; $j++) {
12+
$locations[$i][$j] = $s;
13+
}
14+
}
15+
16+
assertType('non-empty-array<int<0, 9>, non-empty-array<int<0, 9>, string>>', $locations);
17+
assertType('non-empty-array<int<0, 9>, string>', $locations[0]);
18+
};

0 commit comments

Comments
 (0)