diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 4f3e7f9c43..f50bacc339 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -1964,11 +1964,15 @@ private function processBooleanSureConditionalTypes(Scope $scope, SpecifiedTypes continue; } - $holder = new ConditionalExpressionHolder( - $conditions, - ExpressionTypeHolder::createYes($expr, TypeCombinator::intersect($scope->getType($expr), $type)), - ); - $holders[$exprString][$holder->getKey()] = $holder; + $resultTypeHolder = ExpressionTypeHolder::createYes($expr, TypeCombinator::intersect($scope->getType($expr), $type)); + + foreach ($this->expandUnionConditions($conditions) as $expandedConditions) { + $holder = new ConditionalExpressionHolder( + $expandedConditions, + $resultTypeHolder, + ); + $holders[$exprString][$holder->getKey()] = $holder; + } } return $holders; @@ -2085,11 +2089,15 @@ private function processBooleanNotSureConditionalTypes(Scope $scope, SpecifiedTy continue; } - $holder = new ConditionalExpressionHolder( - $conditions, - ExpressionTypeHolder::createYes($expr, TypeCombinator::remove($scope->getType($expr), $type)), - ); - $holders[$exprString][$holder->getKey()] = $holder; + $resultTypeHolder = ExpressionTypeHolder::createYes($expr, TypeCombinator::remove($scope->getType($expr), $type)); + + foreach ($this->expandUnionConditions($conditions) as $expandedConditions) { + $holder = new ConditionalExpressionHolder( + $expandedConditions, + $resultTypeHolder, + ); + $holders[$exprString][$holder->getKey()] = $holder; + } } return $holders; @@ -2098,6 +2106,29 @@ private function processBooleanNotSureConditionalTypes(Scope $scope, SpecifiedTy return []; } + /** + * @param array $conditions + * @return list> + */ + private function expandUnionConditions(array $conditions): array + { + $result = [$conditions]; + foreach ($conditions as $exprString => $typeHolder) { + $type = $typeHolder->getType(); + if (!$type instanceof UnionType) { + continue; + } + + foreach ($type->getTypes() as $innerType) { + $expanded = $conditions; + $expanded[$exprString] = ExpressionTypeHolder::createYes($typeHolder->getExpr(), $innerType); + $result[] = $expanded; + } + } + + return $result; + } + /** * @return array{Expr, ConstantScalarType, Type}|null */ diff --git a/tests/PHPStan/Analyser/nsrt/bug-13591.php b/tests/PHPStan/Analyser/nsrt/bug-13591.php new file mode 100644 index 0000000000..fea4eafdb0 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-13591.php @@ -0,0 +1,16 @@ +