diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 0e3004bddaf..78292314484 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -3805,16 +3805,23 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self } $conditions = []; - foreach ($scope->conditionalExpressions as $conditionalExprString => $conditionalExpressions) { - foreach ($conditionalExpressions as $conditionalExpression) { - foreach ($conditionalExpression->getConditionExpressionTypeHolders() as $holderExprString => $conditionalTypeHolder) { - if (!array_key_exists($holderExprString, $specifiedExpressions) || !$specifiedExpressions[$holderExprString]->equals($conditionalTypeHolder)) { - continue 2; - } + $prevSpecifiedCount = -1; + while (count($specifiedExpressions) !== $prevSpecifiedCount) { + $prevSpecifiedCount = count($specifiedExpressions); + foreach ($scope->conditionalExpressions as $conditionalExprString => $conditionalExpressions) { + if (array_key_exists($conditionalExprString, $conditions)) { + continue; } + foreach ($conditionalExpressions as $conditionalExpression) { + foreach ($conditionalExpression->getConditionExpressionTypeHolders() as $holderExprString => $conditionalTypeHolder) { + if (!array_key_exists($holderExprString, $specifiedExpressions) || !$specifiedExpressions[$holderExprString]->equals($conditionalTypeHolder)) { + continue 2; + } + } - $conditions[$conditionalExprString][] = $conditionalExpression; - $specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder(); + $conditions[$conditionalExprString][] = $conditionalExpression; + $specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder(); + } } } diff --git a/tests/PHPStan/Analyser/nsrt/bug-14178.php b/tests/PHPStan/Analyser/nsrt/bug-14178.php new file mode 100644 index 00000000000..c3c0035f126 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-14178.php @@ -0,0 +1,43 @@ + + */ + public static function diff( + ?self $previousVersion, + ?self $newVersion, + ): array { + $previousVersionExists = $previousVersion !== null; + $newVersionExists = $newVersion !== null; + + if (!$previousVersionExists && !$newVersionExists) { + return []; + } + + if ($previousVersionExists && !$newVersionExists) { + return ['bar']; + } + + if (!$previousVersionExists) { + assertType('true', $newVersionExists); + assertType('Bug14178\\HelloWorld', $newVersion); + $result = []; + $result[] = 'foo'; + $categoryString = implode(', ', $newVersion->getSomething()); + } + + return []; + } + + /** + * @return array + */ + private function getSomething(): array { + return ['foo']; + } +} diff --git a/tests/PHPStan/Analyser/nsrt/dependent-expression-certainty.php b/tests/PHPStan/Analyser/nsrt/dependent-expression-certainty.php index 302d82b609d..d8596c0a21c 100644 --- a/tests/PHPStan/Analyser/nsrt/dependent-expression-certainty.php +++ b/tests/PHPStan/Analyser/nsrt/dependent-expression-certainty.php @@ -153,7 +153,7 @@ function (bool $a, bool $b) { assertVariableCertainty(TrinaryLogic::createMaybe(), $foo); if (returnsBool($b)) { - assertVariableCertainty(TrinaryLogic::createMaybe(), $foo); // could be Yes + assertVariableCertainty(TrinaryLogic::createYes(), $foo); } if (returnsBool($a)) { diff --git a/tests/PHPStan/Analyser/nsrt/dependent-variable-certainty.php b/tests/PHPStan/Analyser/nsrt/dependent-variable-certainty.php index f84857da660..8e34c91b91e 100644 --- a/tests/PHPStan/Analyser/nsrt/dependent-variable-certainty.php +++ b/tests/PHPStan/Analyser/nsrt/dependent-variable-certainty.php @@ -149,7 +149,7 @@ function (bool $a, bool $b) { assertVariableCertainty(TrinaryLogic::createMaybe(), $foo); if ($b) { - assertVariableCertainty(TrinaryLogic::createMaybe(), $foo); // could be Yes + assertVariableCertainty(TrinaryLogic::createYes(), $foo); } if ($a) {