diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 008704829b..c40ad28c13 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -168,6 +168,7 @@ use function strlen; use function strtolower; use function substr; +use function uksort; use function usort; use const PHP_INT_MAX; use const PHP_INT_MIN; @@ -5296,19 +5297,37 @@ private function generalizeVariableTypeHolders( array $otherVariableTypeHolders, ): array { + uksort($variableTypeHolders, static fn (string $exprA, string $exprB): int => strlen($exprA) <=> strlen($exprB)); + + $generalizedExpressions = []; + $newVariableTypeHolders = []; foreach ($variableTypeHolders as $variableExprString => $variableTypeHolder) { + foreach ($generalizedExpressions as $generalizedExprString => $generalizedExpr) { + if (!$this->shouldInvalidateExpression($generalizedExprString, $generalizedExpr, $variableTypeHolder->getExpr())) { + continue; + } + + continue 2; + } if (!isset($otherVariableTypeHolders[$variableExprString])) { + $newVariableTypeHolders[$variableExprString] = $variableTypeHolder; continue; } - $variableTypeHolders[$variableExprString] = new ExpressionTypeHolder( + $generalizedType = $this->generalizeType($variableTypeHolder->getType(), $otherVariableTypeHolders[$variableExprString]->getType(), 0); + if ( + !$generalizedType->equals($variableTypeHolder->getType()) + ) { + $generalizedExpressions[$variableExprString] = $variableTypeHolder->getExpr(); + } + $newVariableTypeHolders[$variableExprString] = new ExpressionTypeHolder( $variableTypeHolder->getExpr(), - $this->generalizeType($variableTypeHolder->getType(), $otherVariableTypeHolders[$variableExprString]->getType(), 0), + $generalizedType, $variableTypeHolder->getCertainty(), ); } - return $variableTypeHolders; + return $newVariableTypeHolders; } private function generalizeType(Type $a, Type $b, int $depth): Type diff --git a/tests/PHPStan/Analyser/nsrt/pr-4390.php b/tests/PHPStan/Analyser/nsrt/pr-4390.php new file mode 100644 index 0000000000..c318b9b6ee --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/pr-4390.php @@ -0,0 +1,18 @@ +, non-empty-array, string>>', $locations); + assertType('non-empty-array, string>', $locations[0]); +};