diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 122340cc27b..4d587050a65 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -3649,6 +3649,15 @@ private function createConditionalExpressions( ) { continue; } + if ( + !array_key_exists($exprString, $theirExpressionTypes) + && array_key_exists($guardExprString, $theirExpressionTypes) + && $theirExpressionTypes[$guardExprString]->getCertainty()->yes() + && $theirExpressionTypes[$guardExprString]->getType()->isObject()->no() + && !$guardHolder->getType()->isSuperTypeOf($theirExpressionTypes[$guardExprString]->getType())->no() + ) { + continue; + } $conditionalExpression = new ConditionalExpressionHolder([$guardExprString => $guardHolder], $holder); $conditionalExpressions[$exprString][$conditionalExpression->getKey()] = $conditionalExpression; } diff --git a/tests/PHPStan/Analyser/nsrt/bug-14469-variants.php b/tests/PHPStan/Analyser/nsrt/bug-14469-variants.php new file mode 100644 index 00000000000..b58ca971f7a --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-14469-variants.php @@ -0,0 +1,54 @@ +id === 10 ? 2 : null; + } elseif ($R['aa']) { + $aa = $R['aa']; + } + + if ($aa) { + assertType('mixed', $R['aa']); + } +} diff --git a/tests/PHPStan/Rules/Comparison/BooleanNotConstantConditionRuleTest.php b/tests/PHPStan/Rules/Comparison/BooleanNotConstantConditionRuleTest.php index 3cf3f2a8bbc..ee1d1ff12fe 100644 --- a/tests/PHPStan/Rules/Comparison/BooleanNotConstantConditionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/BooleanNotConstantConditionRuleTest.php @@ -236,4 +236,10 @@ public function testBug6702(): void $this->analyse([__DIR__ . '/data/bug-6702.php'], []); } + public function testBug14469(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-14469.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-14469.php b/tests/PHPStan/Rules/Comparison/data/bug-14469.php new file mode 100644 index 00000000000..d5aea39bee6 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-14469.php @@ -0,0 +1,66 @@ +id === 10 ? 2 : null; + } elseif ($R['aa']) { + $aa = $R['aa']; + } + + if ($aa) { + if (!$R['aa']) { + return []; + } + } + return $R; +} + +function t2(array $R, bool $var1, object $user): array { + $aa = null; + + if ($var1) { + $aa = $user->id === 10 ? 2 : null; + } elseif ($R['aa']) { + $aa = $R['aa']; + } + + if ($aa) { + if ($R['aa'] === false) { + return []; + } + } + return $R; +} + +function t3(array $R, bool $var1, int $other): array { + $aa = null; + + if ($var1) { + $aa = $other; + } elseif ($R['bb']) { + $aa = $R['bb']; + } + + if ($aa) { + if (!$R['bb']) { + return []; + } + } + return $R; +} + +function t4(array $R, bool $var1, object $user): string { + $aa = null; + + if ($var1) { + $aa = $user->id === 10 ? 2 : null; + } elseif ($R['aa']) { + $aa = $R['aa']; + } + + return $aa ? ($R['aa'] ? 'yes' : 'no') : 'none'; +}