diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index b15204d841..4dee7223bd 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -735,12 +735,12 @@ public function isConstantScalarValue(): TrinaryLogic public function getConstantScalarTypes(): array { - return $this->pickFromTypes(static fn (Type $type) => $type->getConstantScalarTypes()); + return $this->notBenevolentPickFromTypes(static fn (Type $type) => $type->getConstantScalarTypes()); } public function getConstantScalarValues(): array { - return $this->pickFromTypes(static fn (Type $type) => $type->getConstantScalarValues()); + return $this->notBenevolentPickFromTypes(static fn (Type $type) => $type->getConstantScalarValues()); } public function isTrue(): TrinaryLogic @@ -1008,4 +1008,26 @@ protected function pickFromTypes(callable $getValues): array return $values; } + /** + * @template T + * @param callable(Type $type): list $getValues + * @return list + */ + private function notBenevolentPickFromTypes(callable $getValues): array + { + $values = []; + foreach ($this->types as $type) { + $innerValues = $getValues($type); + if ($innerValues === []) { + return []; + } + + foreach ($innerValues as $innerType) { + $values[] = $innerType; + } + } + + return $values; + } + } diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index e11ae15473..a0c4dfd9b2 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -1201,6 +1201,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/list-shapes.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7607.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/ibm_db2.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/benevolent-union-math.php'); } /** diff --git a/tests/PHPStan/Analyser/data/benevolent-union-math.php b/tests/PHPStan/Analyser/data/benevolent-union-math.php new file mode 100644 index 0000000000..6b273c9672 --- /dev/null +++ b/tests/PHPStan/Analyser/data/benevolent-union-math.php @@ -0,0 +1,44 @@ +getBenevolent(); + assertType('array|null', $dbresponse); + + if ($dbresponse === null) {return;} + + assertType('array', $dbresponse); + assertType('(float|int|string|null)', $dbresponse['Value']); + assertType('int<0, max>', strlen($dbresponse['Value'])); + } + + /** + * @return array>|null + */ + private function getBenevolent(): ?array{ + return rand(10) > 1 ? null : []; + } +}