diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index a43ba35dda..cf9eb75808 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -3539,6 +3539,9 @@ private function createConditionalExpressions( array $mergedExpressionTypes, ): array { + $globalVariableCallback = fn (Node $node) => $node instanceof Variable && is_string($node->name) && $this->isGlobalVariable($node->name); + $nodeFinder = new NodeFinder(); + $newVariableTypes = $ourExpressionTypes; foreach ($theirExpressionTypes as $exprString => $holder) { if (!array_key_exists($exprString, $mergedExpressionTypes)) { @@ -3595,6 +3598,16 @@ private function createConditionalExpressions( continue; } + $expr = $holder->getExpr(); + $containsSuperGlobal = $expr->getAttribute(self::CONTAINS_SUPER_GLOBAL_ATTRIBUTE_NAME); + if ($containsSuperGlobal === null) { + $containsSuperGlobal = $nodeFinder->findFirst($expr, $globalVariableCallback) !== null; + $expr->setAttribute(self::CONTAINS_SUPER_GLOBAL_ATTRIBUTE_NAME, $containsSuperGlobal); + } + if ($containsSuperGlobal === true) { + continue; + } + $variableTypeGuards = $typeGuards; unset($variableTypeGuards[$exprString]); @@ -3622,6 +3635,16 @@ private function createConditionalExpressions( continue; } + $expr = $mergedExprTypeHolder->getExpr(); + $containsSuperGlobal = $expr->getAttribute(self::CONTAINS_SUPER_GLOBAL_ATTRIBUTE_NAME); + if ($containsSuperGlobal === null) { + $containsSuperGlobal = $nodeFinder->findFirst($expr, $globalVariableCallback) !== null; + $expr->setAttribute(self::CONTAINS_SUPER_GLOBAL_ATTRIBUTE_NAME, $containsSuperGlobal); + } + if ($containsSuperGlobal === true) { + continue; + } + foreach ($typeGuards as $guardExprString => $guardHolder) { $conditionalExpression = new ConditionalExpressionHolder([$guardExprString => $guardHolder], new ExpressionTypeHolder($mergedExprTypeHolder->getExpr(), new ErrorType(), TrinaryLogic::createNo())); $conditionalExpressions[$exprString][$conditionalExpression->getKey()] = $conditionalExpression; diff --git a/tests/PHPStan/Rules/Variables/IssetRuleTest.php b/tests/PHPStan/Rules/Variables/IssetRuleTest.php index fd841e49b1..aef9f80458 100644 --- a/tests/PHPStan/Rules/Variables/IssetRuleTest.php +++ b/tests/PHPStan/Rules/Variables/IssetRuleTest.php @@ -526,6 +526,13 @@ public function testBug9503(): void $this->analyse([__DIR__ . '/data/bug-9503.php'], []); } + public function testBug14421(): void + { + $this->treatPhpDocTypesAsCertain = true; + + $this->analyse([__DIR__ . '/data/bug-14421.php'], []); + } + public function testBug14393(): void { $this->treatPhpDocTypesAsCertain = true; diff --git a/tests/PHPStan/Rules/Variables/data/bug-14421.php b/tests/PHPStan/Rules/Variables/data/bug-14421.php new file mode 100644 index 0000000000..eafdc7068a --- /dev/null +++ b/tests/PHPStan/Rules/Variables/data/bug-14421.php @@ -0,0 +1,20 @@ +